|
|
|
|
@ -113,6 +113,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_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* entry) { |
|
|
|
|
if (!from_conn || !entry || entry->len < 2) { |
|
|
|
|
if (entry) { |
|
|
|
|
@ -156,28 +158,100 @@ 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)) { |
|
|
|
|
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); |
|
|
|
|
uint16_t nat_port_be = info->nat_port; |
|
|
|
|
// Save nat_type to all links of this connection and their sockets
|
|
|
|
|
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; |
|
|
|
|
if (l->conn) { |
|
|
|
|
l->conn->nat_type = info->nat_type; |
|
|
|
|
} |
|
|
|
|
l = l->next; |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO from %s: type=%s ip=%u.%u.%u.%u port=%u", |
|
|
|
|
from_conn->log_name, |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO from %s: socket_id=%u type=%s ip=%u.%u.%u.%u 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]), |
|
|
|
|
(unsigned)nat_port); |
|
|
|
|
} |
|
|
|
|
} 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); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
queue_dgram_free(entry); |
|
|
|
|
@ -323,8 +397,6 @@ void route_bgp_destroy(struct UTUN_INSTANCE* instance) {
|
|
|
|
|
instance->bgp = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void route_bgp_start_nat_check(struct ROUTE_BGP* bgp, struct NODEINFO_Q* node, struct ETCP_CONN* via_conn); |
|
|
|
|
|
|
|
|
|
void route_bgp_new_conn(struct ETCP_CONN* conn) { |
|
|
|
|
if (!conn) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: conn is NULL"); |
|
|
|
|
@ -347,16 +419,17 @@ void route_bgp_new_conn(struct ETCP_CONN* conn) {
|
|
|
|
|
|
|
|
|
|
route_bgp_add_to_senders(bgp, conn); |
|
|
|
|
|
|
|
|
|
// Try to start NAT checks for nodes waiting for a third node
|
|
|
|
|
if (bgp->nodes) { |
|
|
|
|
struct ll_entry* e = bgp->nodes->head; |
|
|
|
|
while (e) { |
|
|
|
|
struct NODEINFO_Q* node = (struct NODEINFO_Q*)e; |
|
|
|
|
if (node->nat_check_status == NAT_CHECK_WAITING) { |
|
|
|
|
route_bgp_start_nat_check(bgp, node, conn); |
|
|
|
|
// Scan ALL connections and ALL links in instance - start NAT check if not started
|
|
|
|
|
struct ETCP_CONN* c = conn->instance->connections; |
|
|
|
|
while (c) { |
|
|
|
|
struct ETCP_LINK* l = c->links; |
|
|
|
|
while (l) { |
|
|
|
|
if (l->initialized && l->conn && l->nat_check_status == NAT_CHECK_NONE) { |
|
|
|
|
route_bgp_start_link_nat_check(bgp, l); |
|
|
|
|
} |
|
|
|
|
e = e->next; |
|
|
|
|
l = l->next; |
|
|
|
|
} |
|
|
|
|
c = c->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
route_bgp_send_table_request(bgp, conn); |
|
|
|
|
@ -559,29 +632,27 @@ int nodeinfo_dyn_size(struct NODEINFO* node) {
|
|
|
|
|
|
|
|
|
|
// NAT check context
|
|
|
|
|
struct nat_check_arg { |
|
|
|
|
struct NODEINFO_Q* node; |
|
|
|
|
struct ETCP_CONN* client_conn; |
|
|
|
|
struct ETCP_LINK* link; |
|
|
|
|
uint32_t nat_ip; |
|
|
|
|
uint16_t nat_port; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void nat_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent, uint8_t count_ok, |
|
|
|
|
uint32_t recv_ip, uint16_t recv_port, void* arg) { |
|
|
|
|
static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent, uint8_t count_ok, |
|
|
|
|
uint32_t recv_ip, uint16_t recv_port, void* arg) { |
|
|
|
|
(void)avg_rtt; (void)count_sent; (void)count_ok; (void)recv_ip; (void)recv_port; |
|
|
|
|
struct nat_check_arg* na = (struct nat_check_arg*)arg; |
|
|
|
|
if (!na || !na->node) { u_free(na); return; } |
|
|
|
|
if (!na || !na->link) { u_free(na); return; } |
|
|
|
|
struct ETCP_LINK* link = na->link; |
|
|
|
|
uint8_t nat_type = success ? NAT_TYPE_OPEN : NAT_TYPE_RESTRICTED; |
|
|
|
|
na->node->nat_type = nat_type; |
|
|
|
|
na->node->nat_check_status = success ? NAT_CHECK_OPEN : NAT_CHECK_RESTRICTED; |
|
|
|
|
// Save nat_type to all links of client connection
|
|
|
|
|
if (na->client_conn) { |
|
|
|
|
struct ETCP_LINK* l = na->client_conn->links; |
|
|
|
|
while (l) { l->nat_type = nat_type; l = l->next; } |
|
|
|
|
} |
|
|
|
|
route_bgp_send_nat_info(na->client_conn, na->nat_ip, na->nat_port, nat_type); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "nat_check_cb: node=%016llx type=%s success=%d", |
|
|
|
|
(unsigned long long)na->node->node.node_id, |
|
|
|
|
success ? "OPEN" : "RESTRICTED", success); |
|
|
|
|
link->nat_type = nat_type; |
|
|
|
|
link->nat_check_status = success ? NAT_CHECK_OPEN : NAT_CHECK_RESTRICTED; |
|
|
|
|
// Send NAT_INFO to peer (via their connection)
|
|
|
|
|
if (link->etcp) { |
|
|
|
|
uint8_t socket_id = link->remote_socket_id; |
|
|
|
|
route_bgp_send_nat_info(link->etcp, socket_id, na->nat_ip, na->nat_port, nat_type); |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "link=%p type=%s success=%d", |
|
|
|
|
(void*)link, success ? "OPEN" : "RESTRICTED", success); |
|
|
|
|
u_free(na); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -610,43 +681,51 @@ static void route_bgp_extract_nat_addr(struct ETCP_CONN* conn, uint32_t* nat_ip,
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void route_bgp_start_nat_check(struct ROUTE_BGP* bgp, struct NODEINFO_Q* node, struct ETCP_CONN* via_conn) { |
|
|
|
|
if (!bgp || !node || !via_conn) return; |
|
|
|
|
if (node->nat_check_status != NAT_CHECK_NONE && node->nat_check_status != NAT_CHECK_WAITING) return; |
|
|
|
|
// Find client connection
|
|
|
|
|
struct ETCP_CONN* client_conn = NULL; |
|
|
|
|
if (node->paths && node->paths->head) { |
|
|
|
|
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)node->paths->head; |
|
|
|
|
client_conn = path->conn; |
|
|
|
|
} |
|
|
|
|
if (!client_conn) return; |
|
|
|
|
// Extract NAT address from client connection
|
|
|
|
|
uint32_t nat_ip; uint16_t nat_port; |
|
|
|
|
route_bgp_extract_nat_addr(client_conn, &nat_ip, &nat_port); |
|
|
|
|
if (nat_ip == 0 || nat_port == 0) return; |
|
|
|
|
// Save NAT address to node
|
|
|
|
|
node->nat_ip = nat_ip; |
|
|
|
|
node->nat_port = nat_port; |
|
|
|
|
static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) { |
|
|
|
|
if (!bgp || !link || !link->conn || !link->etcp) return; |
|
|
|
|
if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return; |
|
|
|
|
// Find third node to send ping through
|
|
|
|
|
struct ETCP_CONN* third_conn = route_bgp_find_third_node(bgp, link->etcp); |
|
|
|
|
if (!third_conn) { |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: no third node found for link"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// Get target address - use nat_ip/nat_port if set, otherwise use remote_addr
|
|
|
|
|
uint32_t target_ip; |
|
|
|
|
uint16_t target_port; |
|
|
|
|
if (link->nat_ip != 0 && link->nat_port != 0) { |
|
|
|
|
target_ip = link->nat_ip; |
|
|
|
|
target_port = link->nat_port; |
|
|
|
|
} else { |
|
|
|
|
struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr; |
|
|
|
|
target_ip = ntohl(sin->sin_addr.s_addr); |
|
|
|
|
target_port = ntohs(sin->sin_port); |
|
|
|
|
} |
|
|
|
|
// Allocate callback arg
|
|
|
|
|
struct nat_check_arg* arg = u_calloc(1, sizeof(struct nat_check_arg)); |
|
|
|
|
if (!arg) return; |
|
|
|
|
arg->node = node; |
|
|
|
|
arg->client_conn = client_conn; |
|
|
|
|
arg->nat_ip = nat_ip; |
|
|
|
|
arg->nat_port = nat_port; |
|
|
|
|
// Send ping request via third node (with embedded pubkey for NAT detection)
|
|
|
|
|
int ret = route_ping_send_req_addr(bgp, via_conn, node->node.node_id, nat_ip, nat_port, |
|
|
|
|
3, 500, 1000, 5000, nat_check_cb, arg, |
|
|
|
|
node->node.public_key); |
|
|
|
|
arg->link = link; |
|
|
|
|
arg->nat_ip = target_ip; |
|
|
|
|
arg->nat_port = target_port; |
|
|
|
|
// Use peer public key from the connection's crypto context
|
|
|
|
|
const uint8_t* pubkey = link->etcp->crypto_ctx.peer_key_set ? link->etcp->crypto_ctx.peer_public_key : NULL; |
|
|
|
|
if (!pubkey) { |
|
|
|
|
u_free(arg); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: no peer pubkey for link=%p", (void*)link); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// Send ping via third node - embed peer pubkey for NAT detection
|
|
|
|
|
int ret = route_ping_send_req_addr(bgp, third_conn, link->etcp->peer_node_id, target_ip, target_port, |
|
|
|
|
3, 500, 1000, 5000, nat_link_check_cb, arg, |
|
|
|
|
pubkey); |
|
|
|
|
if (ret == 0) { |
|
|
|
|
node->nat_check_status = NAT_CHECK_IN_PROGRESS; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_start_nat_check: started for node=%016llx via=%s", |
|
|
|
|
(unsigned long long)node->node.node_id, via_conn->log_name); |
|
|
|
|
link->nat_check_status = NAT_CHECK_IN_PROGRESS; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: started for link=%p via=%s", |
|
|
|
|
(void*)link, third_conn->log_name); |
|
|
|
|
} else { |
|
|
|
|
node->nat_check_status = NAT_CHECK_WAITING; |
|
|
|
|
u_free(arg); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "route_bgp_start_nat_check: failed to start for node=%016llx", |
|
|
|
|
(unsigned long long)node->node.node_id); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: failed to start for link=%p", |
|
|
|
|
(void*)link); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -712,18 +791,6 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co
|
|
|
|
|
route_bgp_remove_path_by_hop(nodeinfo1, from->peer_node_id); |
|
|
|
|
route_bgp_add_path(nodeinfo1, from, hop_list, nodeinfo1->node.hop_count); |
|
|
|
|
|
|
|
|
|
// Start NAT check for direct peers
|
|
|
|
|
if (nodeinfo1->node.hop_count == 1 && nodeinfo1->nat_check_status == NAT_CHECK_NONE) { |
|
|
|
|
struct ETCP_CONN* third = route_bgp_find_third_node(bgp, from); |
|
|
|
|
if (third) { |
|
|
|
|
route_bgp_start_nat_check(bgp, nodeinfo1, third); |
|
|
|
|
} else { |
|
|
|
|
nodeinfo1->nat_check_status = NAT_CHECK_WAITING; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT check queued (no third node yet) for node=%016llx", |
|
|
|
|
(unsigned long long)node_id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (bgp->instance->rt) { |
|
|
|
|
route_insert(bgp->instance->rt, nodeinfo1); |
|
|
|
|
} |
|
|
|
|
@ -887,12 +954,13 @@ static void route_bgp_handle_request_table(struct ROUTE_BGP* bgp, struct ETCP_CO
|
|
|
|
|
route_bgp_add_to_senders(bgp, conn); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint32_t nat_ip, uint16_t nat_port, uint8_t nat_type) { |
|
|
|
|
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)); |
|
|
|
|
if (!pkt) return; |
|
|
|
|
pkt->cmd = ETCP_ID_ROUTE_ENTRY; |
|
|
|
|
pkt->subcmd = ROUTE_SUBCMD_NAT_INFO; |
|
|
|
|
pkt->socket_id = socket_id; |
|
|
|
|
pkt->nat_ip[0] = (nat_ip >> 24) & 0xFF; |
|
|
|
|
pkt->nat_ip[1] = (nat_ip >> 16) & 0xFF; |
|
|
|
|
pkt->nat_ip[2] = (nat_ip >> 8) & 0xFF; |
|
|
|
|
@ -908,8 +976,28 @@ void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint32_t nat_ip, uint16_t n
|
|
|
|
|
e->dgram = (uint8_t*)pkt; |
|
|
|
|
e->len = sizeof(struct BGP_NAT_INFO); |
|
|
|
|
etcp_send(conn, e); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_info to %s: type=%s ip=%08x port=%u", |
|
|
|
|
conn->log_name, |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_info to %s: socket_id=%u type=%s ip=%08x port=%u", |
|
|
|
|
conn->log_name, socket_id, |
|
|
|
|
nat_type == NAT_TYPE_OPEN ? "OPEN" : "RESTRICTED", |
|
|
|
|
(unsigned)nat_ip, (unsigned)nat_port); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { |
|
|
|
|
if (!conn) return; |
|
|
|
|
struct BGP_NAT_CHECK_REQ* pkt = u_calloc(1, sizeof(struct BGP_NAT_CHECK_REQ)); |
|
|
|
|
if (!pkt) return; |
|
|
|
|
pkt->cmd = ETCP_ID_ROUTE_ENTRY; |
|
|
|
|
pkt->subcmd = ROUTE_SUBCMD_NAT_CHECK_REQ; |
|
|
|
|
pkt->socket_id = socket_id; |
|
|
|
|
|
|
|
|
|
struct ll_entry* e = queue_entry_new(0); |
|
|
|
|
if (!e) { |
|
|
|
|
u_free(pkt); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
e->dgram = (uint8_t*)pkt; |
|
|
|
|
e->len = sizeof(struct BGP_NAT_CHECK_REQ); |
|
|
|
|
etcp_send(conn, e); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_check_req to %s: socket_id=%u", |
|
|
|
|
conn->log_name, socket_id); |
|
|
|
|
} |
|
|
|
|
|