etcp_router: fix NULL conn в deliver при отсутствии пути к узлу

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.
This commit is contained in:
evgeny committed 2026-09-02 23:59:41 +03:00
1 parent 1db4fe1f01
commit e08956e5dc
3 files changed
+9 -3

No files matched your search

+4
View File
@@ -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(); }
+4 -3
View File
@@ -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;
+1
View File
@@ -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)