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:
1 parent
1db4fe1f01
commit
e08956e5dc
3 files changed
+9
-3
No files matched your search
@@ -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(); }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user