From 58eea06f60c6c08a0f3fdc0a082da837c9fab57c Mon Sep 17 00:00:00 2001 From: Evgeny Date: Wed, 15 Apr 2026 17:40:42 +0300 Subject: [PATCH] 1 --- src/route_bgp.c | 197 +++++++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 93 deletions(-) diff --git a/src/route_bgp.c b/src/route_bgp.c index a5d95eba..1061f278 100644 --- a/src/route_bgp.c +++ b/src/route_bgp.c @@ -114,6 +114,8 @@ static void route_bgp_broadcast_withdraw(struct ROUTE_BGP* bgp, uint64_t node_id // ============================================================================ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link); +static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); +static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* entry) { if (!from_conn || !entry || entry->len < 2) { @@ -158,100 +160,9 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* } else if (subcmd == ROUTE_SUBCMD_PING_RESP) { route_ping_handle_resp(bgp, from_conn, data, entry->len); } else if (subcmd == ROUTE_SUBCMD_NAT_INFO) { - if (entry->len >= sizeof(struct BGP_NAT_INFO) && bgp && bgp->local_node) { - const struct BGP_NAT_INFO* info = (const struct BGP_NAT_INFO*)data; - uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) | - (info->nat_ip[2] << 8) | info->nat_ip[3]; - uint16_t nat_port = ((info->nat_port >> 8) & 0xFF) | ((info->nat_port & 0xFF) << 8); - uint8_t socket_id = info->socket_id; - // Update socket in local_node and ETCP_SOCKET - uint8_t* dynamic = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO); - dynamic += bgp->local_node->node.node_name_len; - struct NODEINFO_IPV4_SOCKET* sockets = (struct NODEINFO_IPV4_SOCKET*)dynamic; - for (int i = 0; i < bgp->local_node->node.local_v4_sockets; i++) { - if (sockets[i].id == socket_id) { - uint8_t old_type = sockets[i].type; - 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; - uint8_t verified_type; - if (info->nat_type == NAT_TYPE_OPEN) { - verified_type = NAT_VERIFIED_OPEN; - } else if (info->nat_type == NAT_TYPE_RESTRICTED) { - verified_type = NAT_VERIFIED_RESTRICTED; - } else { - verified_type = NAT_VERIFIED_UNKNOWN; - } - sockets[i].type = verified_type; - // Update ETCP_SOCKET - struct ETCP_SOCKET* es = bgp->instance->etcp_sockets; - while (es) { - if (es->sock_id == socket_id) { - es->nat_type = verified_type; - break; - } - es = es->next; - } - // Check if NAT actually changed - only update nodeinfo if changed - if (old_ip != nat_ip || old_port != nat_port || old_type != verified_type) { - bgp->local_node->dirty = 1; - bgp->local_node->node.ver = (bgp->local_node->node.ver + 1) % 255 + 1; - // Broadcast updated nodeinfo to all peers immediately - if (bgp->senders_list) { - struct ll_entry* se = bgp->senders_list->head; - while (se) { - struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; - if (item && item->conn) { - route_bgp_send_nodeinfo(bgp->local_node, item->conn); - } - se = se->next; - } - } - } - break; - } - } - // Save nat_type to all links of this connection - struct ETCP_LINK* l = from_conn->links; - while (l) { - l->nat_type = info->nat_type; - l = l->next; - } - DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO from %s: socket_id=%u type=%s ip=%u.%u.%u.%u %s port=%u", - from_conn->log_name, socket_id, - info->nat_type == NAT_TYPE_OPEN ? "OPEN" : "RESTRICTED", - (info->nat_ip[0]), (info->nat_ip[1]), - (info->nat_ip[2]), (info->nat_ip[3]), ip_to_str(&info->nat_ip, AF_INET).str, - (unsigned)nat_port); - } + route_bgp_handle_nat_info(bgp, from_conn, data, entry->len); } else if (subcmd == ROUTE_SUBCMD_NAT_CHECK_REQ) { - if (entry->len >= sizeof(struct BGP_NAT_CHECK_REQ) && bgp) { - const struct BGP_NAT_CHECK_REQ* req = (const struct BGP_NAT_CHECK_REQ*)data; - uint8_t socket_id = req->socket_id; - // Find link by remote_socket_id in the connection - struct ETCP_LINK* target_link = NULL; - struct ETCP_LINK* l = from_conn->links; - while (l) { - if (l->remote_socket_id == socket_id) { - target_link = l; - break; - } - l = l->next; - } - if (!target_link) { - DEBUG_WARN(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: no link with remote_socket_id=%u", - from_conn->log_name, socket_id); - } else if (target_link->nat_check_status == NAT_CHECK_IN_PROGRESS) { - DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: check already in progress for socket_id=%u", - from_conn->log_name, socket_id); - } else { - DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: restarting NAT check for socket_id=%u", - from_conn->log_name, socket_id); - route_bgp_start_link_nat_check(bgp, target_link); - } - } + route_bgp_handle_nat_check_req(bgp, from_conn, data, entry->len); } queue_dgram_free(entry); @@ -958,6 +869,106 @@ static void route_bgp_handle_request_table(struct ROUTE_BGP* bgp, struct ETCP_CO route_bgp_add_to_senders(bgp, conn); } +static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { + if (!bgp || !from_conn || !data || len < sizeof(struct BGP_NAT_INFO) || !bgp->local_node) return; + + const struct BGP_NAT_INFO* info = (const struct BGP_NAT_INFO*)data; + uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) | + (info->nat_ip[2] << 8) | info->nat_ip[3]; + uint16_t nat_port = ((info->nat_port >> 8) & 0xFF) | ((info->nat_port & 0xFF) << 8); + uint8_t socket_id = info->socket_id; + + uint8_t* dynamic = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO); + dynamic += bgp->local_node->node.node_name_len; + struct NODEINFO_IPV4_SOCKET* sockets = (struct NODEINFO_IPV4_SOCKET*)dynamic; + for (int i = 0; i < bgp->local_node->node.local_v4_sockets; i++) { + if (sockets[i].id == socket_id) { + uint8_t old_type = sockets[i].type; + 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; + uint8_t verified_type; + if (info->nat_type == NAT_TYPE_OPEN) { + verified_type = NAT_VERIFIED_OPEN; + } else if (info->nat_type == NAT_TYPE_RESTRICTED) { + verified_type = NAT_VERIFIED_RESTRICTED; + } else { + verified_type = NAT_VERIFIED_UNKNOWN; + } + sockets[i].type = verified_type; + + struct ETCP_SOCKET* es = bgp->instance->etcp_sockets; + while (es) { + if (es->sock_id == socket_id) { + es->nat_type = verified_type; + break; + } + es = es->next; + } + + if (old_ip != nat_ip || old_port != nat_port || old_type != verified_type) { + bgp->local_node->dirty = 1; + bgp->local_node->node.ver = (bgp->local_node->node.ver + 1) % 255 + 1; + if (bgp->senders_list) { + struct ll_entry* se = bgp->senders_list->head; + while (se) { + struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; + if (item && item->conn) { + route_bgp_send_nodeinfo(bgp->local_node, item->conn); + } + se = se->next; + } + } + } + break; + } + } + + struct ETCP_LINK* l = from_conn->links; + while (l) { + l->nat_type = info->nat_type; + l = l->next; + } + + DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO from %s: socket_id=%u type=%s ip=%u.%u.%u.%u %s port=%u", + from_conn->log_name, socket_id, + info->nat_type == NAT_TYPE_OPEN ? "OPEN" : "RESTRICTED", + (info->nat_ip[0]), (info->nat_ip[1]), + (info->nat_ip[2]), (info->nat_ip[3]), ip_to_str(&info->nat_ip, AF_INET).str, + (unsigned)nat_port); +} + +static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { + if (!bgp || !from_conn || !data || len < sizeof(struct BGP_NAT_CHECK_REQ)) return; + + const struct BGP_NAT_CHECK_REQ* req = (const struct BGP_NAT_CHECK_REQ*)data; + uint8_t socket_id = req->socket_id; + + struct ETCP_LINK* target_link = NULL; + struct ETCP_LINK* l = from_conn->links; + while (l) { + if (l->remote_socket_id == socket_id) { + target_link = l; + break; + } + l = l->next; + } + + if (!target_link) { + DEBUG_WARN(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: no link with remote_socket_id=%u", + from_conn->log_name, socket_id); + } else if (target_link->nat_check_status == NAT_CHECK_IN_PROGRESS) { + DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: check already in progress for socket_id=%u", + from_conn->log_name, socket_id); + } else { + DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: restarting NAT check for socket_id=%u", + from_conn->log_name, socket_id); + route_bgp_start_link_nat_check(bgp, target_link); + } +} + void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t nat_ip, uint16_t nat_port, uint8_t nat_type) { if (!conn) return; struct BGP_NAT_INFO* pkt = u_calloc(1, sizeof(struct BGP_NAT_INFO));