From ceb6ee210371deb1916826eeac91ae34297de3e4 Mon Sep 17 00:00:00 2001 From: jeka Date: Wed, 25 Mar 2026 18:39:31 +0300 Subject: [PATCH] +ip change --- lib/ll_queue.c | 11 ++++------- src/etcp.c | 4 +++- src/etcp_connections.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/routing.c | 2 ++ 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/ll_queue.c b/lib/ll_queue.c index da32a80..a727d52 100644 --- a/lib/ll_queue.c +++ b/lib/ll_queue.c @@ -318,8 +318,8 @@ int queue_data_put(struct ll_queue* q, struct ll_entry* entry, uint32_t id) { q->callback(q, q->callback_arg); } - // Проверить ожидающие коллбэки - check_waiters(q); + // Проверить ожидающие коллбэки (надо только при заборе из очереди) +// check_waiters(q); #ifdef QUEUE_DEBUG queue_check_consistency(q);// !!!! for debug - AFTER callback @@ -371,11 +371,7 @@ int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry, uint32_t id } // Проверить ожидающие коллбэки - check_waiters(q); - -#ifdef QUEUE_DEBUG - queue_check_consistency(q);// !!!! for debug - AFTER callback -#endif +// check_waiters(q); #ifdef QUEUE_DEBUG queue_check_consistency(q);// !!!! for debug @@ -548,5 +544,6 @@ int queue_remove_data(struct ll_queue* q, struct ll_entry* entry) { #ifdef QUEUE_DEBUG queue_check_consistency(q);// !!!! for debug #endif + check_waiters(q); return 0; } diff --git a/src/etcp.c b/src/etcp.c index 8ee0555..0590d71 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -888,7 +888,7 @@ void etcp_output_try_assembly(struct ETCP_CONN* etcp) { struct ETCP_FRAGMENT* rx_pkt = (struct ETCP_FRAGMENT*)queue_find_data_by_id(etcp->recv_q, next_expected_id); if (!rx_pkt) { // No more contiguous packets found -// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] no packet found for id=%u, stopping", etcp->log_name, next_expected_id); + DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] no packet found for id=%u, stopping", etcp->log_name, next_expected_id); break; } @@ -897,7 +897,9 @@ void etcp_output_try_assembly(struct ETCP_CONN* etcp) { // Simply move ETCP_FRAGMENT from recv_q to output_queue - no data copying needed // Remove from recv_q first + DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "Remove from assembly queue"); queue_remove_data(etcp->recv_q, (struct ll_entry*)rx_pkt); + DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "move: ETCP -> PN"); // Add to output_queue using the same ETCP_FRAGMENT structure if (queue_data_put(etcp->output_queue, (struct ll_entry*)rx_pkt, next_expected_id) == 0) { diff --git a/src/etcp_connections.c b/src/etcp_connections.c index e81adcf..efb5702 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -345,6 +345,16 @@ static void remove_link(struct ETCP_SOCKET* e_sock, uint32_t hash) { e_sock->num_channels--; } +static int sockaddr_equal(const struct sockaddr_storage* a, const struct sockaddr_storage* b) { + if (!a || !b || a->ss_family != b->ss_family) return 0; + if (a->ss_family == AF_INET) { + const struct sockaddr_in *sa = (const struct sockaddr_in*)a; + const struct sockaddr_in *sb = (const struct sockaddr_in*)b; + return (sa->sin_addr.s_addr == sb->sin_addr.s_addr && sa->sin_port == sb->sin_port); + } + return 0; // IPv6 not fully supported yet +} + // надо править, используй sockaddr_hash struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sockaddr_storage* addr) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); @@ -356,6 +366,17 @@ struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sock return e_sock->links[idx]; } +struct ETCP_LINK* etcp_link_find_by_remote_id(struct ETCP_CONN* conn, uint8_t remote_link_id) { + DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); + if (!conn || remote_link_id == 0) return NULL; + struct ETCP_LINK* l = conn->links; + while (l) { + if (l->remote_link_id == remote_link_id) return l; + l = l->next; + } + return NULL; +} + int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); if (!etcp) return -1; @@ -931,13 +952,28 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) { else {// check keys если существующее подключение if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: peer key mismatch for node %016llx", (unsigned long long)peer_id); goto ec_fr; }// коллизия - peer id совпал а ключи разные. } + // Check if link already exists (for CHANNEL_INIT recovery) - struct ETCP_LINK* existing_link = etcp_link_find_by_addr(e_sock, &addr); + + struct ETCP_LINK* existing_link = etcp_link_find_by_remote_id(conn, ack_hdr->link_id); + uint8_t send_reset = 0; if (existing_link && existing_link->etcp == conn) {// существующий линк - // Link exists - reuse it for recovery link = existing_link; + if (!sockaddr_equal(&link->remote_addr, &addr)) { + DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] IP:port changed for remote_link_id=%d socket:[%s]", conn->log_name, ack_hdr->link_id, e_sock->name); + if (link->conn) remove_link(link->conn, link->ip_port_hash); // remove old connection from old socket + link->conn=e_sock; + memcpy(&link->remote_addr, &addr, sizeof(addr)); + link->ip_port_hash = sockaddr_hash(&addr); + if (insert_link(link->conn, link) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to reinsert link after addr change"); + goto ec_fr; + } + } + + // Link exists - reuse it for recovery link->remote_link_id = ack_hdr->link_id; // For CHANNEL_INIT (0x04): if link already initialized - no reset, otherwise reset diff --git a/src/routing.c b/src/routing.c index ecc06f5..46659af 100644 --- a/src/routing.c +++ b/src/routing.c @@ -52,6 +52,7 @@ static uint32_t extract_dst_ip(uint8_t* data, size_t len) { // entry format: static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry, uint64_t src_node_id) { + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, ""); if (!instance || !entry) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_pkt: invalid arguments: instance=%p entry=%p entry->len=%zu", (void*)instance, (void*)entry, entry ? entry->len : 0); @@ -210,6 +211,7 @@ static void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry, ui // Callback for packets from ETCP (via etcp_bind id=0) static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* pkt) { + DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, ""); if (!conn || !pkt) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "routing_pkt_from_etcp_cb: invalid arguments: conn=%p pkt=%p", (void*)conn, (void*)pkt);