From 501b636d19c76668040b01f7bb41e0a9c1f2b28e Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sun, 19 Jul 2026 08:33:33 +0300 Subject: [PATCH] topo_group: disable in chatgui; fix NAT detection for matching addresses - Add utun_instance_set_topo_group_enabled() flag (default=1, chatgui sets 0) - Move nat_detection create/destroy from topo_group.c to utun_instance.c (unconditional) - NAT detection: simplify third_node search (any connected node) - NAT detection: allow NULL topo_groups in receive_cbk and handlers - NAT detection: handle NAT_INFO without topo_group (update socket directly) - route_ping: make TOPO_GROUP optional in send_req_addr/handle_req - topo_node: when NAT verified and address matches interface, set entry type to NAT instead of INTERFACE + socket_id|1 - topo_node: detect nat_type change in changed computation for rebuild - test_nat_detection: fix socket_id check (|1 for NAT entries) - chatgui: call utun_instance_set_topo_group_enabled(0) --- src/nat_detection.c | 137 +++++++++++++++----------- src/route_ping.c | 16 +-- src/topo_group.c | 7 -- src/topo_node.c | 31 ++++-- src/utun_instance.c | 39 ++++++-- src/utun_instance.h | 1 + tests/test_nat_detection.c | 2 +- tools/chatgui/transport/utun_node.cpp | 1 + 8 files changed, 150 insertions(+), 84 deletions(-) diff --git a/src/nat_detection.c b/src/nat_detection.c index 0e2e4ef0..149da5ef 100644 --- a/src/nat_detection.c +++ b/src/nat_detection.c @@ -38,10 +38,7 @@ static struct ETCP_CONN* nat_check_find_third_node(struct NAT_DETECTION* nd, str struct ll_entry* e = nd->inst->connections->head; while (e) { struct conn_queue_entry* ce = (struct conn_queue_entry*)e->data; - if (ce->conn && ce->conn != exclude && ce->conn->links - && ce->conn->links->remote_only_local == 0 - && ce->conn->links->remote_type != CFG_SERVER_TYPE_PRIVATE - && ce->conn->links->remote_type != CFG_SERVER_TYPE_LOCAL) + if (ce->conn && ce->conn != exclude && ce->conn->links) return ce->conn; e = e->next; } @@ -91,8 +88,8 @@ static void nat_detection_start_link_check(struct NAT_DETECTION* nd, struct ETCP ip_to_str(&target_ip, AF_INET).str); return; } - struct TOPO_GROUP* group = topo_groups_get_default(nd->inst->topo_groups); - if (!group) return; + struct TOPO_GROUP* group = nd->inst->topo_groups + ? topo_groups_get_default(nd->inst->topo_groups) : NULL; struct nat_check_arg* arg = u_calloc(1, sizeof(struct nat_check_arg)); if (!arg) return; arg->link = link; arg->nat_ip = target_ip; arg->nat_port = target_port; @@ -117,8 +114,7 @@ static void nat_detection_start_link_check(struct NAT_DETECTION* nd, struct ETCP static void nat_detection_handle_nat_info(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { - if (!nd || !group || !from_conn || !data || len < sizeof(struct NATDET_MSG_NAT_INFO) - || !group->local_node || !group->local_node->node) return; + if (!nd || !from_conn || !data || len < sizeof(struct NATDET_MSG_NAT_INFO)) return; const struct NATDET_MSG_NAT_INFO* info = (const struct NATDET_MSG_NAT_INFO*)data; uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) @@ -132,8 +128,8 @@ static void nat_detection_handle_nat_info(struct NAT_DETECTION* nd, struct TOPO_ else if (info->nat_type == NAT_TYPE_DIRECT) verified_type = NAT_VERIFIED_DIRECT; else verified_type = NAT_VERIFIED_UNKNOWN; - int data_changed = 0; - { + if (group && group->local_node && group->local_node->node) { + int data_changed = 0; struct TOPO_SOCKMETA4* sm = group->local_node->node->v4_sock_meta; while (sm) { if (sm->id == socket_id) { @@ -142,48 +138,81 @@ static void nat_detection_handle_nat_info(struct NAT_DETECTION* nd, struct TOPO_ } sm = sm->next; } - } - struct ETCP_SOCKET* es = group->instance->etcp_sockets; - while (es) { - if (es->sock_id == socket_id) { - if (verified_type == NAT_VERIFIED_STRICT) { - struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; - nat_sin->sin_family = AF_INET; - nat_sin->sin_addr.s_addr = nat_ip; - nat_sin->sin_port = htons(nat_port); - es->nat_type = verified_type; - } else { + struct ETCP_SOCKET* es = group->instance->etcp_sockets; + while (es) { + if (es->sock_id == socket_id) { + if (verified_type == NAT_VERIFIED_STRICT) { + struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; + nat_sin->sin_family = AF_INET; + nat_sin->sin_addr.s_addr = nat_ip; + nat_sin->sin_port = htons(nat_port); + es->nat_type = verified_type; + } else { + struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; + uint32_t old_nat_ip = nat_sin->sin_addr.s_addr; + uint16_t old_nat_port = ntohs(nat_sin->sin_port); + nat_sin->sin_family = AF_INET; + nat_sin->sin_addr.s_addr = nat_ip; + nat_sin->sin_port = htons(nat_port); + if (old_nat_ip != nat_ip || old_nat_port != nat_port) data_changed = 1; + es->nat_type = verified_type; + } + break; + } + es = es->next; + } + + if (data_changed) { + int prev_v4a = topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs); + topo_group_update_my_nodeinfo(group->instance, group); + if (topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs) != prev_v4a) { + group->local_node->dirty = 1; + group->local_node->node->ver = (group->local_node->node->ver % 255) + 1; + group->local_node->last_ver = group->local_node->node->ver; + } + if (topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs) == prev_v4a) { + struct TOPO_ADDR4* a = group->local_node->node->v4_addrs; + while (a) { + if (a->type == TOPO_ADDR_INTERFACE && a->socket_id == socket_id) { + uint32_t a_ip; memcpy(&a_ip, a->addr, 4); + if (a_ip == nat_ip && a->port == nat_port) { + a->type = TOPO_ADDR_NAT; a->socket_id = socket_id | 1; + group->local_node->dirty = 1; + group->local_node->node->ver = (group->local_node->node->ver % 255) + 1; + group->local_node->last_ver = group->local_node->node->ver; + DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO matched interface addr, updated entry type to NAT sock=%d", socket_id); + } + break; + } + a = a->next; + } + } + if (group->local_node->dirty && group->senders_list) { + struct ll_entry* se = group->senders_list->head; + while (se) { + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data; + if (item && item->conn) + topo_group_send_nodeinfo(group, group->local_node, item->conn); + se = se->next; + } + } + } + } else { + struct ETCP_SOCKET* es = nd->inst->etcp_sockets; + while (es) { + if (es->sock_id == socket_id) { struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; - uint32_t old_nat_ip = nat_sin->sin_addr.s_addr; - uint16_t old_nat_port = ntohs(nat_sin->sin_port); nat_sin->sin_family = AF_INET; nat_sin->sin_addr.s_addr = nat_ip; nat_sin->sin_port = htons(nat_port); - if (old_nat_ip != nat_ip || old_nat_port != nat_port) data_changed = 1; es->nat_type = verified_type; + DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO socket=%s id=%d type=%d addr=%s:%u (no topo_group)", + es->name, socket_id, verified_type, + ip_to_str(&nat_ip, AF_INET).str, nat_port); + break; } - break; - } - es = es->next; - } - - if (data_changed) { - int prev_v4a = topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs); - topo_group_update_my_nodeinfo(group->instance, group); - if (topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs) != prev_v4a) { - group->local_node->dirty = 1; - group->local_node->node->ver = (group->local_node->node->ver % 255) + 1; - group->local_node->last_ver = group->local_node->node->ver; - } - if (group->local_node->dirty && group->senders_list) { - struct ll_entry* se = group->senders_list->head; - while (se) { - struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data; - if (item && item->conn) - topo_group_send_nodeinfo(group, group->local_node, item->conn); - se = se->next; - } + es = es->next; } } @@ -194,7 +223,8 @@ static void nat_detection_handle_nat_info(struct NAT_DETECTION* nd, struct TOPO_ static void nat_detection_handle_nat_check_req(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { - if (!nd || !group || !from_conn || !data || len < sizeof(struct NATDET_MSG_NAT_CHECK_REQ)) return; + if (!nd || !from_conn || !data || len < sizeof(struct NATDET_MSG_NAT_CHECK_REQ)) return; + (void)group; const struct NATDET_MSG_NAT_CHECK_REQ* req = (const struct NATDET_MSG_NAT_CHECK_REQ*)data; uint8_t socket_id = req->socket_id; struct ETCP_LINK* target_link = NULL; @@ -256,20 +286,17 @@ static void nat_detection_receive_cbk(struct ETCP_CONN* from_conn, struct ll_ent if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return; } struct UTUN_INSTANCE* instance = from_conn->instance; - if (!instance || !instance->nat_det || !instance->topo_groups) { - DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid instance/nat_det/topo_groups"); - queue_dgram_free(entry); queue_entry_free(entry); return; - } - struct TOPO_GROUP* group = topo_groups_get_default(instance->topo_groups); - if (!group) { - DEBUG_ERROR(DEBUG_CATEGORY_BGP, "no default group"); + if (!instance || !instance->nat_det) { + DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid instance/nat_det"); queue_dgram_free(entry); queue_entry_free(entry); return; } + struct TOPO_GROUP* group = instance->topo_groups + ? topo_groups_get_default(instance->topo_groups) : NULL; struct NAT_DETECTION* nd = instance->nat_det; uint8_t* data = entry->dgram; uint8_t subcmd = data[1]; - DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT recv %s from %s len=%zu", - nat_subcmd_name(subcmd), from_conn->log_name, entry->len); + DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT recv %s from %s len=%zu group=%s", + nat_subcmd_name(subcmd), from_conn->log_name, entry->len, group ? "yes" : "no"); if (subcmd == NATDET_SUBCMD_PING_REQ) route_ping_handle_req(nd, group, from_conn, data, entry->len); diff --git a/src/route_ping.c b/src/route_ping.c index d6ce3ef1..13804941 100644 --- a/src/route_ping.c +++ b/src/route_ping.c @@ -171,7 +171,8 @@ int route_ping_send_req_addr(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, uint8_t count, uint16_t interval_ms, uint16_t timeout_ms, uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg, const uint8_t* pubkey) { - if (!nd || !group || !to_conn || count == 0 || timeout_ms == 0) { + (void)group; + if (!nd || !to_conn || count == 0 || timeout_ms == 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); return -1; } @@ -326,8 +327,7 @@ void route_ping_handle_req(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { - (void)nd; - if (!group || !from_conn || !data || len < offsetof(struct NATDET_PING_REQ, pubkey)) { + if (!from_conn || !nd || !data || len < offsetof(struct NATDET_PING_REQ, pubkey)) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "ping req: bad args len=%zu", len); return; } @@ -347,8 +347,10 @@ void route_ping_handle_req(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, ctx->timeout_ms = req_pkt->timeout_ms; { - struct TOPO_NODEQ* req_nq = topo_node_find_by_id(group, from_conn->peer_node_id); - if (req_nq) req_nq->connectivity.ping_req_time = get_time_tb(); + if (group) { + struct TOPO_NODEQ* req_nq = topo_node_find_by_id(group, from_conn->peer_node_id); + if (req_nq) req_nq->connectivity.ping_req_time = get_time_tb(); + } } if (len >= sizeof(struct NATDET_PING_REQ)) { memcpy(ctx->pubkey, req_pkt->pubkey, SC_PUBKEY_SIZE); @@ -361,7 +363,7 @@ void route_ping_handle_req(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, sin->sin_port = req_pkt->target_port; /* порт в network byte order */ /* Ищем первый IPv4-сокет */ - struct ETCP_SOCKET* ls = group->instance->etcp_sockets; + struct ETCP_SOCKET* ls = (group ? group->instance : nd->inst)->etcp_sockets; while (ls) { if (ls->local_addr.ss_family == AF_INET) { ctx->local_sock = ls; @@ -382,7 +384,7 @@ void route_ping_handle_req(struct NAT_DETECTION* nd, struct TOPO_GROUP* group, /* Запускаем первый пинг (дальше цепочка через callback) */ int ret = etcp_send_ping_to_socket( - group->instance, + (group ? group->instance : nd->inst), ctx->local_sock, ctx->pubkey, &ctx->target_addr, diff --git a/src/topo_group.c b/src/topo_group.c index 59643061..cd755ed0 100644 --- a/src/topo_group.c +++ b/src/topo_group.c @@ -276,11 +276,6 @@ struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { instance->topo_groups = g; - g->instance->nat_det = nat_detection_create(instance); - if (!g->instance->nat_det) { - DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NAT detection creation failed"); - } - struct TOPO_GROUP* default_group = topo_group_create(instance, TOPO_GROUP_UTUN, TOPO_GROUP_TYPE_UTUN); if (!default_group) { memory_pool_destroy(g->v4_sock_meta_pool); memory_pool_destroy(g->v4_addr_pool); @@ -307,8 +302,6 @@ void topo_groups_destroy(struct UTUN_INSTANCE* instance) { etcp_unbind(instance, ETCP_ID_TOPO_ENTRY); route_connectivity_cancel_all(instance); - if (instance->nat_det) { nat_detection_destroy(instance->nat_det); instance->nat_det = NULL; } - struct TOPO_GROUPS* g = instance->topo_groups; struct ll_entry* ge; while ((ge = queue_data_get(g->group_list)) != NULL) { struct TOPO_GROUP* grp = (struct TOPO_GROUP*)ge; topo_group_destroy(grp); queue_entry_free(ge); } diff --git a/src/topo_node.c b/src/topo_node.c index 017f28ed..e73acc11 100644 --- a/src/topo_node.c +++ b/src/topo_node.c @@ -492,8 +492,13 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR if (e_sock->local_addr.ss_family == AF_INET) { sock_count++; addr_count++; if (e_sock->nat_addr.ss_family == AF_INET) { - struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; - if (nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT) addr_count++; + struct sockaddr_in* ns = (struct sockaddr_in*)&e_sock->nat_addr; + struct sockaddr_in* ls = (struct sockaddr_in*)&e_sock->local_addr; + struct sockaddr_in* ifs = (struct sockaddr_in*)&e_sock->interface_addr; + uint32_t ref_ip = ls->sin_addr.s_addr ? ls->sin_addr.s_addr : ifs->sin_addr.s_addr; + uint16_t ref_port = ntohs(ls->sin_addr.s_addr ? ls->sin_port : ifs->sin_port); + if (ns->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT && (ns->sin_addr.s_addr != ref_ip || ntohs(ns->sin_port) != ref_port)) + addr_count++; } if (e_sock->nat_type == NAT_VERIFIED_DIRECT || ((e_sock->type == CFG_SERVER_TYPE_PUBLIC || e_sock->type == CFG_SERVER_TYPE_UNKNOWN) && e_sock->nat_type < NAT_VERIFIED_UNKNOWN)) addr_count++; } else if (e_sock->local_addr.ss_family == AF_INET6) { sock6_count++; addr6_count++; } @@ -515,6 +520,16 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR || (vc6 != (group->local_node->subnets ? topo_list_count((struct _topo_head*)group->local_node->subnets->v6_subnets) : 0)) || (sock6_count != topo_list_count((struct _topo_head*)oni->v6_sock_meta)) || (addr6_count != topo_list_count((struct _topo_head*)oni->v6_addrs)); + if (!changed && oni->v4_sock_meta) { + struct ETCP_SOCKET* es = instance->etcp_sockets; + struct TOPO_SOCKMETA4* sm = oni->v4_sock_meta; + while (es && sm) { + if (es->type == CFG_SERVER_TYPE_PRIVATE || es->type == CFG_SERVER_TYPE_LOCAL) { es = es->next; continue; } + if (es->local_addr.ss_family != AF_INET) { es = es->next; continue; } + if (sm->nat_type != es->nat_type) { changed = 1; break; } + sm = sm->next; es = es->next; + } + } if (group->local_node && group->instance && group->instance->topo_groups) if (memcmp(oni->ed25519_public_key, group->ed25519_public_key, SC_PUBKEY_SIZE) != 0) changed = 1; } @@ -560,15 +575,19 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; int use_local = (local_sin->sin_addr.s_addr != 0); + uint32_t ref_ip = use_local ? local_sin->sin_addr.s_addr : if_sin->sin_addr.s_addr; + uint16_t ref_port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port); + int nat_verified = (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT); + int nat_differs = (nat_verified && (nat_sin->sin_addr.s_addr != ref_ip || ntohs(nat_sin->sin_port) != ref_port)); { struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); memcpy(a->addr, use_local ? &local_sin->sin_addr.s_addr : &if_sin->sin_addr.s_addr, 4); a->port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port); - a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id; a->protocol = TOPO_PROTO_UDP; + a->type = (!nat_differs && nat_verified) ? TOPO_ADDR_NAT : TOPO_ADDR_INTERFACE; + a->socket_id = (a->type == TOPO_ADDR_NAT) ? (e_sock->sock_id | 1) : e_sock->sock_id; + a->protocol = TOPO_PROTO_UDP; a->next = ni->v4_addrs; ni->v4_addrs = a; } - if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT - && (nat_sin->sin_addr.s_addr != (use_local ? local_sin->sin_addr.s_addr : if_sin->sin_addr.s_addr) - || nat_sin->sin_port != (use_local ? local_sin->sin_port : if_sin->sin_port))) { + if (nat_differs) { struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port); a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id | 1; a->protocol = TOPO_PROTO_UDP; diff --git a/src/utun_instance.c b/src/utun_instance.c index 2639702a..598cc2e6 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -9,6 +9,7 @@ #include "route_lib.h" #include "routing.h" #include "topo_group.h" +#include "nat_detection.h" #include "etcp_connections.h" #include "etcp.h" #include "conn_mgr.h" @@ -50,6 +51,14 @@ void utun_instance_set_tun_init_enabled(int enabled) { DEBUG_INFO(DEBUG_CATEGORY_TUN, "TUN initialization %s", enabled ? "enabled" : "disabled"); } +// Global flag to control topo_group initialization (enabled by default) +static int g_topo_group_enabled = 1; + +void utun_instance_set_topo_group_enabled(int enabled) { + g_topo_group_enabled = enabled ? 1 : 0; + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group initialization %s", enabled ? "enabled" : "disabled"); +} + static int local_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) { @@ -177,15 +186,23 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u if (socket_result == 1) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "Partial socket initialization - some servers failed to bind"); } - instance->topo_groups = topo_groups_init(instance); - if (!instance->topo_groups) { - DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to initialize BGP module"); - } else { - DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized"); - struct TOPO_GROUP* g = topo_groups_get_default(instance->topo_groups); - if (instance->rt && g && g->local_node) { - topo_group_update_my_nodeinfo(instance, g); + instance->nat_det = nat_detection_create(instance); + if (!instance->nat_det) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NAT detection creation failed"); } + + if (g_topo_group_enabled) { + instance->topo_groups = topo_groups_init(instance); + if (!instance->topo_groups) { + DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to initialize BGP module"); + } else { + DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized"); + struct TOPO_GROUP* g = topo_groups_get_default(instance->topo_groups); + if (instance->rt && g && g->local_node) { + topo_group_update_my_nodeinfo(instance, g); + } } + } else { + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group initialization disabled, skipping BGP module"); + instance->topo_groups = NULL; } instance->conn_mgr = conn_mgr_init(instance); @@ -483,6 +500,12 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "Destroying BGP module"); topo_groups_destroy(instance); } + + // Cleanup NAT detection + if (instance->nat_det) { + nat_detection_destroy(instance->nat_det); + instance->nat_det = NULL; + } // Cleanup firewall fw_free(&instance->fw); diff --git a/src/utun_instance.h b/src/utun_instance.h index fe6d0a8d..c4d71c3d 100644 --- a/src/utun_instance.h +++ b/src/utun_instance.h @@ -173,6 +173,7 @@ struct UTUN_INSTANCE *utun_instance_reload(struct UTUN_INSTANCE *instance, struc void utun_instance_run(struct UTUN_INSTANCE *instance); void utun_instance_stop(struct UTUN_INSTANCE *instance); void utun_instance_set_tun_init_enabled(int enabled); +void utun_instance_set_topo_group_enabled(int enabled); // Diagnostic function for memory leak analysis void utun_instance_diagnose_leaks(struct UTUN_INSTANCE* instance, const char* phase); diff --git a/tests/test_nat_detection.c b/tests/test_nat_detection.c index 338a35d7..f0446137 100644 --- a/tests/test_nat_detection.c +++ b/tests/test_nat_detection.c @@ -376,7 +376,7 @@ int main(void) { // Verify NAT addr in flat address list int nat_found = 0; for (const struct TOPO_ADDR4* a = topo_groups_get_default(inst_c1->topo_groups)->local_node->node->v4_addrs; a; a = a->next) { - if (a->type == TOPO_ADDR_NAT && a->socket_id == sock_c1->sock_id) { + if (a->type == TOPO_ADDR_NAT && a->socket_id == (sock_c1->sock_id | 1)) { uint32_t addr_ip; memcpy(&addr_ip, a->addr, 4); if (addr_ip != link_sc1->nat_ip || a->port != link_sc1->nat_port) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: NAT addr mismatch in local_node: addr=%08x nat_ip=%08x port=%u nat_port=%u", diff --git a/tools/chatgui/transport/utun_node.cpp b/tools/chatgui/transport/utun_node.cpp index 1518c702..9b4a7bae 100644 --- a/tools/chatgui/transport/utun_node.cpp +++ b/tools/chatgui/transport/utun_node.cpp @@ -239,6 +239,7 @@ void UtunNode::runLoop() { } utun_instance_set_tun_init_enabled(0); + utun_instance_set_topo_group_enabled(0); struct UASYNC* ua = uasync_create(); if (!ua) {