Browse Source

NODEINFO: Add nat_addr/nat_port fields, use interface_addr for addr/port

congestion
Evgeny 5 months ago
parent
commit
a3063ea47a
  1. 12
      src/route_bgp.c
  2. 30
      src/route_node.c
  3. 10
      src/route_node.h
  4. 8
      tests/test_nat_detection.c
  5. 12
      tests/test_route_ping.c

12
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;

30
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;

10
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 {

8
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;
}

12
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) {

Loading…
Cancel
Save