Remove obsolete router state and clarify receive diagnostics
This commit is contained in:
1 parent
a258b77240
commit
3bd9b964fa
3 files changed
+21
-22
No files matched your search
@@ -5,7 +5,7 @@
|
||||
// Подпись/шифрование — в route_crypto.c (encode при отправке, decode до изменения состояния приёма)
|
||||
//
|
||||
// Поток сервисной кодограммы:
|
||||
// in -> {send_q} -> [src: etcp_send] -> ... -> [dst: recv_q] -> {incoming_q} -> out
|
||||
// in -> {send_q} -> {inflight_q / etcp_send} -> ... -> {incoming_q} -> {recv_q} -> сервис
|
||||
// ack возвращается по обратному пути; (pause) — backpressure при заполнении очередей.
|
||||
|
||||
|
||||
@@ -431,7 +431,6 @@ static void router_confirm_peer(struct ETCP_ROUTER_CONN* rconn, const struct SVC
|
||||
if (previous && router_conn_reset(rconn) != 0) { router_close_and_notify(rconn); return; }
|
||||
if (rconn->handshake_timer) { uasync_cancel_timeout(rconn->inst->ua, rconn->handshake_timer); rconn->handshake_timer = NULL; }
|
||||
rconn->peer_reset_id = peer_id;
|
||||
rconn->peer_sync_done = 1;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE,
|
||||
"router session: group=%016llx peer=%016llx svc=%u local=%016llx remote=%016llx previous=%016llx",
|
||||
(unsigned long long)rconn->group_id, (unsigned long long)rconn->remote_node_id, rconn->svc_id,
|
||||
@@ -446,9 +445,12 @@ static void router_send_close_to_service(struct ETCP_ROUTER_CONN* rconn) {
|
||||
etcp_recv_fn cb = inst->router_bindings.callbacks[rconn->svc_id];
|
||||
if (!cb) return;
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
if (!e) return;
|
||||
if (!e) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router close notification allocation failed svc=%u", rconn->svc_id); return; }
|
||||
e->dgram = u_malloc(ROUTER_SVC_HDR_SIZE);
|
||||
if (!e->dgram) { queue_entry_free(e); return; }
|
||||
if (!e->dgram) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router close notification payload allocation failed svc=%u", rconn->svc_id);
|
||||
queue_entry_free(e); return;
|
||||
}
|
||||
e->dgram[0] = rconn->svc_id;
|
||||
memcpy(e->dgram + ROUTER_SVC_SRC_OFF, &rconn->remote_node_id, 8);
|
||||
memcpy(e->dgram + ROUTER_SVC_DST_OFF, &inst->node_id, 8);
|
||||
@@ -522,7 +524,6 @@ static int router_conn_reset(struct ETCP_ROUTER_CONN* rconn) {
|
||||
queue_set_threshold(rconn->send_q, ROUTER_MAX_SEND_Q_PACKETS - 1, 0);
|
||||
queue_set_callback(rconn->incoming_q, router_incoming_q_cb, rconn);
|
||||
queue_set_threshold(rconn->incoming_q, 0, 0);
|
||||
rconn->incoming_data_ready = 0;
|
||||
rconn->receive_blocked = 0;
|
||||
rconn->peer_receive_blocked = 0;
|
||||
rconn->recv_conn = NULL;
|
||||
@@ -540,7 +541,7 @@ static int router_conn_reset(struct ETCP_ROUTER_CONN* rconn) {
|
||||
rconn->tx_seq = 0; rconn->tx_sent = 0; rconn->rx_seq = 0; rconn->tx_acked = 0;
|
||||
rconn->retrans_seq = 0; rconn->retrans_end = 0;
|
||||
rconn->last_sent_ack_seq = 0; rconn->last_ack_sent_tb = 0;
|
||||
rconn->send_blocked = 0; rconn->start_sent = 0; rconn->peer_sync_done = 0;
|
||||
rconn->send_blocked = 0; rconn->start_sent = 0;
|
||||
rconn->peer_reset_id = 0;
|
||||
rconn->no_route = 0; rconn->no_route_timer = NULL; rconn->no_ack_count = 0; rconn->closed = 0;
|
||||
rconn->c_pkts_sent = 0; rconn->c_pkts_send_err = 0; rconn->c_pkts_rcvd = 0;
|
||||
@@ -551,8 +552,7 @@ static int router_conn_reset(struct ETCP_ROUTER_CONN* rconn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Закрыть conn: уведомить локальный сервис, отправить CLOSE удалённой стороне, очистить
|
||||
// очереди/таймеры, удалить из реестра router_conns и отложить освобождение ll через call_soon.
|
||||
// Снять канал с реестра, уведомить сервис/пира, очистить очереди/таймеры; само ll освободить через call_soon.
|
||||
static void router_close_and_notify(struct ETCP_ROUTER_CONN* rconn) {
|
||||
if (!rconn || rconn->closed) return;
|
||||
struct UTUN_INSTANCE* inst = rconn->inst;
|
||||
@@ -799,7 +799,7 @@ static void router_retrans_timer_cb(void* arg) {
|
||||
}
|
||||
}
|
||||
|
||||
// Собрать+закодировать пакет в начале отправки и положить в send_q.
|
||||
// Скопировать plaintext и mode в send_q, выделить seq; кодирование выполняется при отправке после handshake.
|
||||
static int router_enqueue_send(struct ETCP_ROUTER_CONN* rconn, const uint8_t* payload, size_t len, int force, int mode) {
|
||||
uint8_t required = rconn->inst->router_bindings.required_crypto[rconn->svc_id];
|
||||
if ((mode & required) != required) {
|
||||
@@ -1061,8 +1061,7 @@ static int router_deliver_loopback(struct UTUN_INSTANCE* inst, uint64_t group_id
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Доставка: декодирует (подпись/шифрование) перед вызовом сервисного коллбэка.
|
||||
// wire = [SVC_ROUTE_HDR][payload][sig?] — финальный пакет, лежавший в recv_q.
|
||||
// Доставить уже проверенный plaintext из recv_q; криптографические проверки выполнены до постановки в очередь.
|
||||
static int router_deliver(struct ETCP_ROUTER_CONN* rconn, struct ETCP_CONN* conn,
|
||||
const uint8_t* wire, size_t wire_len) {
|
||||
struct UTUN_INSTANCE* inst = rconn->inst;
|
||||
@@ -1144,8 +1143,6 @@ static void router_incoming_q_cb(struct ll_queue* q, void* arg) {
|
||||
if (!e) { queue_resume_callback(q); return; }
|
||||
|
||||
uint32_t seq = *(uint32_t*)e->data;
|
||||
const uint8_t* wire = e->dgram;
|
||||
size_t wire_len = e->len;
|
||||
|
||||
if ((int32_t)(seq - rconn->rx_seq) < 0 || queue_find_data_by_index(rconn->recv_q, &seq)) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCPROUTE, "router_incoming_q: dup in recv_q seq=%u, dropping", seq);
|
||||
@@ -1153,7 +1150,10 @@ static void router_incoming_q_cb(struct ll_queue* q, void* arg) {
|
||||
}
|
||||
|
||||
struct ll_entry* rq = queue_entry_new(4);
|
||||
if (!rq) { queue_dgram_free(e); queue_entry_free(e); queue_resume_callback(q); return; }
|
||||
if (!rq) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router reorder entry allocation failed svc=%u seq=%u", rconn->svc_id, seq);
|
||||
queue_dgram_free(e); queue_entry_free(e); queue_resume_callback(q); return;
|
||||
}
|
||||
*(uint32_t*)rq->data = seq;
|
||||
rq->dgram = e->dgram; rq->len = e->len; e->dgram = NULL;
|
||||
queue_entry_free(e);
|
||||
@@ -1276,8 +1276,7 @@ static void router_forward_transit(struct UTUN_INSTANCE* inst, struct ll_entry*
|
||||
transit_queue_wait(tq);
|
||||
}
|
||||
|
||||
// Принять data-пакет: зафиксировать recv_conn, синхронизировать rx_seq при первом пакете сеанса,
|
||||
// отсеять out-of-bounds/дубликаты и положить пакет в incoming_q.
|
||||
// Принять данные согласованной сессии: зафиксировать recv_conn, проверить окно/дубликаты и положить в incoming_q.
|
||||
static void router_handle_data_packet(struct ETCP_ROUTER_CONN* rconn, struct ETCP_CONN* conn,
|
||||
uint32_t seq, const uint8_t* wire, size_t wire_len) {
|
||||
rconn->recv_conn = conn;
|
||||
@@ -1311,10 +1310,13 @@ static void router_handle_data_packet(struct ETCP_ROUTER_CONN* rconn, struct ETC
|
||||
return;
|
||||
}
|
||||
struct ll_entry* qe = queue_entry_new(4);
|
||||
if (!qe) return;
|
||||
if (!qe) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router incoming entry allocation failed svc=%u seq=%u", rconn->svc_id, seq); return; }
|
||||
*(uint32_t*)qe->data = seq;
|
||||
qe->dgram = u_malloc(wire_len);
|
||||
if (!qe->dgram) { queue_dgram_free(qe); queue_entry_free(qe); return; }
|
||||
if (!qe->dgram) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router incoming payload allocation failed svc=%u seq=%u bytes=%zu", rconn->svc_id, seq, wire_len);
|
||||
queue_dgram_free(qe); queue_entry_free(qe); return;
|
||||
}
|
||||
qe->len = wire_len; memcpy(qe->dgram, wire, wire_len);
|
||||
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCPROUTE, "router: incoming_q seq=%u rx_seq=%u from %016llx svc_id=%u",
|
||||
|
||||
@@ -156,7 +156,6 @@ struct ETCP_ROUTER_CONN {
|
||||
uint64_t challenge_sent_tb; // время отправки запроса, 0.1 ms
|
||||
void* handshake_timer; // таймер повторов согласования
|
||||
uint8_t start_sent; // получен первый ACK данных
|
||||
uint8_t peer_sync_done; // 1 = завершено подтверждение peer ID
|
||||
|
||||
// Ретрансмиты: inflight очередь
|
||||
struct ll_queue* inflight_q; // хеш по seq (4 байта), непрерывный блок без SACK
|
||||
@@ -165,7 +164,6 @@ struct ETCP_ROUTER_CONN {
|
||||
|
||||
// Очередь приёма входящего трафика (между сетью и recv_q)
|
||||
struct ll_queue* incoming_q; // FIFO очередь входящих пакетов
|
||||
uint8_t incoming_data_ready; // 1 = данные в incoming_q и callback был вызван
|
||||
uint8_t receive_blocked; // сервис временно не принимает следующую кодограмму
|
||||
uint8_t peer_receive_blocked; // последний ACK пира объявил паузу приёма
|
||||
void* receive_pump; // отложенное продолжение приёма
|
||||
|
||||
@@ -526,7 +526,7 @@ static int test_out_of_bounds(void) {
|
||||
|
||||
rx_reset(0xEE);
|
||||
uint8_t data[] = { TEST_SVC_ID, 0xEE, 0 };
|
||||
/* first packet syncs rx_seq (peer_sync_done), then OOB check works */
|
||||
/* После handshake первый DATA начинается с seq=0, затем проверяется граница окна. */
|
||||
inject(recv_cb, &inst, TEST_REMOTE_NODE, TEST_SVC_ID, 0, data + 1, 2, 0, ROUTER_FLAG_START);
|
||||
uint32_t bad_seq = ROUTER_MAX_INFLIGHT + 2;
|
||||
inject(recv_cb, &inst, TEST_REMOTE_NODE, TEST_SVC_ID, bad_seq, data + 1, 2, 0, 0);
|
||||
@@ -548,7 +548,6 @@ static int test_circular_wrap(void) {
|
||||
if (!c) FAIL("conn_get failed");
|
||||
|
||||
c->rx_seq = 0xFFFFFFFE;
|
||||
c->peer_sync_done = 1;// сессия уже установлена (seq вручную на границе wrap)
|
||||
rx_reset(0x11);
|
||||
rx.expected_seq = 0xFFFFFFFE;
|
||||
uint8_t data[] = { TEST_SVC_ID, 0x11, 0 };
|
||||
|
||||
Reference in new issue
Block a user