diff --git a/src/route_bgp.c b/src/route_bgp.c index 8b299ace..cf583388 100644 --- a/src/route_bgp.c +++ b/src/route_bgp.c @@ -943,12 +943,12 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f DEBUG_INFO(DEBUG_CATEGORY_BGP, " checking socket %d: id=%u", i, sockets[i].id); if (sockets[i].id == socket_id) { uint8_t old_type = sockets[i].type; - /* addr[] хранится в network byte order (big-endian bytes) */ - uint32_t old_ip = (sockets[i].addr[0] << 24) | (sockets[i].addr[1] << 16) | - (sockets[i].addr[2] << 8) | sockets[i].addr[3]; - uint16_t old_port = sockets[i].port; - memcpy(sockets[i].addr, info->nat_ip, 4); - sockets[i].port = nat_port; + /* nat_addr[] хранится в network byte order (big-endian bytes) */ + uint32_t old_ip = (sockets[i].nat_addr[0] << 24) | (sockets[i].nat_addr[1] << 16) | + (sockets[i].nat_addr[2] << 8) | sockets[i].nat_addr[3]; + uint16_t old_port = sockets[i].nat_port; + memcpy(sockets[i].nat_addr, info->nat_ip, 4); + sockets[i].nat_port = nat_port; uint8_t verified_type; if (info->nat_type == NAT_TYPE_OPEN) { verified_type = NAT_VERIFIED_OPEN; diff --git a/src/route_node.c b/src/route_node.c index 8971ec5d..f51e9798 100644 --- a/src/route_node.c +++ b/src/route_node.c @@ -165,8 +165,16 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG bool same = true; while (e_sock) { if (e_sock->local_addr.ss_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)&e_sock->local_addr; - if (memcmp(sa->addr, &sin->sin_addr.s_addr, 4) != 0 || sa->port != ntohs(sin->sin_port) || + struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; + struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; + uint8_t nat_addr_cmp[4] = {0}; + uint16_t nat_port_cmp = 0; + if (e_sock->nat_addr.ss_family == AF_INET) { + memcpy(nat_addr_cmp, &nat_sin->sin_addr.s_addr, 4); + nat_port_cmp = ntohs(nat_sin->sin_port); + } + if (memcmp(sa->addr, &if_sin->sin_addr.s_addr, 4) != 0 || sa->port != ntohs(if_sin->sin_port) || + memcmp(sa->nat_addr, nat_addr_cmp, 4) != 0 || sa->nat_port != nat_port_cmp || sa->type != e_sock->nat_type || sa->id != e_sock->sock_id) { same = false; break; @@ -201,14 +209,22 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG e_sock = instance->etcp_sockets; while (e_sock) { if (e_sock->local_addr.ss_family == AF_INET) { - struct sockaddr_in* sin = (struct sockaddr_in*)&e_sock->local_addr; - memcpy(sa->addr, &sin->sin_addr.s_addr, 4); - sa->port = ntohs(sin->sin_port); + struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; + struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; + memcpy(sa->addr, &if_sin->sin_addr.s_addr, 4); + sa->port = ntohs(if_sin->sin_port); sa->type = e_sock->nat_type; sa->id = e_sock->sock_id; - DEBUG_INFO(DEBUG_CATEGORY_BGP, "NODEINFO socket: addr=0x%02x%02x%02x%02x port=%u (from sin_addr=0x%08x sin_port=%u)", + if (e_sock->nat_addr.ss_family == AF_INET) { + memcpy(sa->nat_addr, &nat_sin->sin_addr.s_addr, 4); + sa->nat_port = ntohs(nat_sin->sin_port); + } else { + memset(sa->nat_addr, 0, 4); + sa->nat_port = 0; + } + DEBUG_INFO(DEBUG_CATEGORY_BGP, "NODEINFO socket: addr=0x%02x%02x%02x%02x port=%u nat=0x%02x%02x%02x%02x:%u", sa->addr[0], sa->addr[1], sa->addr[2], sa->addr[3], sa->port, - sin->sin_addr.s_addr, ntohs(sin->sin_port)); + sa->nat_addr[0], sa->nat_addr[1], sa->nat_addr[2], sa->nat_addr[3], sa->nat_port); sa++; } e_sock = e_sock->next; diff --git a/src/route_node.h b/src/route_node.h index 9c880047..b0ed6e6b 100644 --- a/src/route_node.h +++ b/src/route_node.h @@ -27,10 +27,12 @@ struct NODEINFO { } __attribute__((packed)); struct NODEINFO_IPV4_SOCKET { - uint8_t addr[4];// network byte order - uint16_t port; - uint8_t type; // CFG_SERVER_TYPE_PUBLIC/PRIVATE/NAT - uint8_t id; // unique socket id (0-255) + uint8_t addr[4]; // interface IP (network byte order) + uint16_t port; // interface port + uint8_t type; // CFG_SERVER_TYPE_PUBLIC/PRIVATE/NAT + uint8_t id; // unique socket id (0-255) + uint8_t nat_addr[4]; // NAT IP (network byte order), 0 = не определён + uint16_t nat_port; // NAT port, 0 = не определён } __attribute__((packed)); struct NODEINFO_IPV6_SOCKET { diff --git a/tests/test_nat_detection.c b/tests/test_nat_detection.c index 5207369d..6d83fc7f 100644 --- a/tests/test_nat_detection.c +++ b/tests/test_nat_detection.c @@ -364,13 +364,13 @@ int main(void) { int found = 0; for (int i = 0; i < sock_count; i++) { if (sockets[i].id == sock_c1->sock_id) { - uint32_t s_ip = (sockets[i].addr[0] << 24) | (sockets[i].addr[1] << 16) | - (sockets[i].addr[2] << 8) | sockets[i].addr[3]; - if (s_ip != link_sc1->nat_ip || sockets[i].port != link_sc1->nat_port || + uint32_t s_ip = (sockets[i].nat_addr[0] << 24) | (sockets[i].nat_addr[1] << 16) | + (sockets[i].nat_addr[2] << 8) | sockets[i].nat_addr[3]; + if (s_ip != link_sc1->nat_ip || sockets[i].nat_port != link_sc1->nat_port || sockets[i].type != NAT_VERIFIED_OPEN) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: local_node socket not updated on C1: " "s_ip=0x%08x nat_ip=0x%08x s_port=%u nat_port=%u s_type=%u expected=%u", - s_ip, link_sc1->nat_ip, sockets[i].port, link_sc1->nat_port, + s_ip, link_sc1->nat_ip, sockets[i].nat_port, link_sc1->nat_port, sockets[i].type, NAT_VERIFIED_OPEN); goto cleanup; } diff --git a/tests/test_route_ping.c b/tests/test_route_ping.c index 5ab252d5..615da393 100644 --- a/tests/test_route_ping.c +++ b/tests/test_route_ping.c @@ -267,8 +267,16 @@ int main(void) { const struct NODEINFO_IPV4_SOCKET* sockets; int sc = get_node_v4_sockets(nq, &sockets); if (sc > 0) { - memcpy(&target_ip, sockets[0].addr, 4); /* network byte order */ - target_port = sockets[0].port; /* уже в host order */ + /* Используем NAT адрес если есть, иначе interface адрес */ + uint32_t nat_ip = (sockets[0].nat_addr[0] << 24) | (sockets[0].nat_addr[1] << 16) | + (sockets[0].nat_addr[2] << 8) | sockets[0].nat_addr[3]; + if (nat_ip != 0 && sockets[0].nat_port != 0) { + memcpy(&target_ip, sockets[0].nat_addr, 4); /* network byte order */ + target_port = sockets[0].nat_port; /* уже в host order */ + } else { + memcpy(&target_ip, sockets[0].addr, 4); /* network byte order */ + target_port = sockets[0].port; /* уже в host order */ + } } } if (target_ip == 0 || target_port == 0) {