From e08956e5dca2b4c90d5558f646729df0df14bcd5 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 2 Sep 2026 23:59:41 +0300 Subject: [PATCH] =?UTF-8?q?etcp=5Frouter:=20fix=20NULL=20conn=20=D0=B2=20d?= =?UTF-8?q?eliver=20=D0=BF=D1=80=D0=B8=20=D0=BE=D1=82=D1=81=D1=83=D1=82?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D0=BF=D1=83=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BA=20=D1=83=D0=B7=D0=BB=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit router_handle_data_packet выбрасывал физический conn, а router_incoming_q_cb восстанавливал его через topo_group_find_conn_for_node, который возвращает NULL, когда у узла-источника нет пути в топологии. В итоге callback сервиса (routing, conn_mgr) получал conn=0x0. Теперь физический conn сохраняется в rconn->recv_conn и прокидывается в deliver. --- src/routing_layer/conn_mgr_core.c | 4 ++++ src/routing_layer/etcp_router.c | 7 ++++--- src/routing_layer/etcp_router.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/routing_layer/conn_mgr_core.c b/src/routing_layer/conn_mgr_core.c index f5c4be24..6f610999 100644 --- a/src/routing_layer/conn_mgr_core.c +++ b/src/routing_layer/conn_mgr_core.c @@ -726,6 +726,10 @@ void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id) { void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) { if (!entry || !entry->dgram || entry->len < 3) return; + if (!conn || !conn->instance) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "conn_mgr_router_recv: conn=%p", (void*)conn); + return; + } uint8_t* d = entry->dgram + 1; size_t len = entry->len - 1; uint8_t sub = d[1]; struct CONN_MGR* mgr = conn->instance->conn_mgr; if (mgr) { struct CONN_MGR_ENTRY* e = cm_find_entry(mgr, conn->peer_node_id); if (e && e->state == CONN_MGR_STATE_CONNECTED) e->last_traffic_tb = get_time_tb(); } diff --git a/src/routing_layer/etcp_router.c b/src/routing_layer/etcp_router.c index 772087b4..22f546d2 100644 --- a/src/routing_layer/etcp_router.c +++ b/src/routing_layer/etcp_router.c @@ -826,8 +826,7 @@ static void router_incoming_q_cb(struct ll_queue* q, void* arg) { queue_data_put_with_index(rconn->recv_q, rq); - struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_find(rconn->inst->topo_groups, rconn->group_id), rconn->remote_node_id);; - if (seq == rconn->rx_seq) router_try_assembly(rconn, conn); + if (seq == rconn->rx_seq) router_try_assembly(rconn, rconn->recv_conn); router_schedule_ack(rconn); queue_resume_callback(q); } @@ -991,7 +990,7 @@ static int router_check_peer_restart(struct UTUN_INSTANCE* inst, struct ETCP_ROU static void router_handle_data_packet(struct ETCP_ROUTER_CONN* rconn, struct ETCP_CONN* conn, uint32_t seq, const uint8_t* pl, size_t pl_len) { - (void)conn; + rconn->recv_conn = conn; rconn->last_dgram_ts = get_current_timestamp(); if (!rconn->peer_sync_done) { rconn->peer_sync_done = 1; rconn->rx_seq = seq; } @@ -1353,6 +1352,7 @@ void etcp_router_conn_restart(struct UTUN_INSTANCE* inst, uint64_t group_id, uin 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->recv_conn = NULL; rconn->tx_seq = 0; rconn->rx_seq = 0; @@ -1462,6 +1462,7 @@ struct ETCP_ROUTER_CONN* etcp_router_conn_get(struct UTUN_INSTANCE* inst, rconn->last_sent_ack_seq = 0; rconn->last_ack_sent_tb = 0; rconn->inst = inst; + rconn->recv_conn = NULL; rconn->ack_timer = NULL; rconn->idle_ack_timer = NULL; rconn->send_blocked = 0; diff --git a/src/routing_layer/etcp_router.h b/src/routing_layer/etcp_router.h index 84f9a744..56a1529c 100644 --- a/src/routing_layer/etcp_router.h +++ b/src/routing_layer/etcp_router.h @@ -88,6 +88,7 @@ struct ETCP_ROUTER_CONN { uint64_t last_ack_sent_tb; // время отправки последнего ACK (timebase 0.1ms) struct UTUN_INSTANCE* inst; + struct ETCP_CONN* recv_conn; // физический conn последнего принятого data-пакета (для deliver, не NULL) struct ll_queue* recv_q; // reorder очередь: hash по seq (4 байта, offset 0) void* ack_timer; // периодический таймер (10ms при consumer_ack) void* idle_ack_timer; // idle таймер (дослать последний ack)