|
|
|
@ -567,8 +567,7 @@ static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent, |
|
|
|
uint8_t socket_id = link->remote_socket_id; |
|
|
|
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); |
|
|
|
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", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "nat check result: type=%s for node %s", success ? "OPEN" : "RESTRICTED", link->etcp->log_name); |
|
|
|
(void*)link, success ? "OPEN" : "RESTRICTED", success); |
|
|
|
|
|
|
|
u_free(na); |
|
|
|
u_free(na); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -597,7 +596,7 @@ static void route_bgp_extract_nat_addr(struct ETCP_CONN* conn, uint32_t* nat_ip, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) { |
|
|
|
static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) {// проверяем тип нат для линка link
|
|
|
|
if (!bgp || !link || !link->conn || !link->etcp) return; |
|
|
|
if (!bgp || !link || !link->conn || !link->etcp) return; |
|
|
|
if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return; |
|
|
|
if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return; |
|
|
|
// Find third node to send ping through
|
|
|
|
// Find third node to send ping through
|
|
|
|
@ -608,15 +607,17 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Get target address - use nat_ip/nat_port if set, otherwise use remote_addr
|
|
|
|
// Get target address - use nat_ip/nat_port if set, otherwise use remote_addr
|
|
|
|
|
|
|
|
/* link->nat_ip и sin_addr.s_addr в network byte order,
|
|
|
|
|
|
|
|
конвертируем в host order для API route_ping_send_req_addr */ |
|
|
|
uint32_t target_ip; |
|
|
|
uint32_t target_ip; |
|
|
|
uint16_t target_port; |
|
|
|
uint16_t target_port; |
|
|
|
if (link->nat_ip != 0 && link->nat_port != 0) { |
|
|
|
if (link->nat_ip != 0 && link->nat_port != 0) { |
|
|
|
target_ip = link->nat_ip; |
|
|
|
target_ip = ntohl(link->nat_ip); /* network → host order */ |
|
|
|
target_port = link->nat_port; |
|
|
|
target_port = link->nat_port; /* уже в host order */ |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr; |
|
|
|
struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr; |
|
|
|
target_ip = sin->sin_addr.s_addr; |
|
|
|
target_ip = ntohl(sin->sin_addr.s_addr); /* network → host order */ |
|
|
|
target_port = ntohs(sin->sin_port); |
|
|
|
target_port = ntohs(sin->sin_port); /* network → host order */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!bgp->allow_nat_check_local && is_local_subnet(target_ip)) { |
|
|
|
if (!bgp->allow_nat_check_local && is_local_subnet(target_ip)) { |
|
|
|
@ -674,6 +675,11 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co |
|
|
|
struct NODEINFO_Q* nodeinfo1 = route_bgp_get_node(bgp, node_id); |
|
|
|
struct NODEINFO_Q* nodeinfo1 = route_bgp_get_node(bgp, node_id); |
|
|
|
uint8_t new_ver = ni->ver; |
|
|
|
uint8_t new_ver = ni->ver; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NODEINFO from %s node=%016llx new_ver=%d local_ver=%d local_node=%p nodeinfo1=%p", |
|
|
|
|
|
|
|
from->log_name, (unsigned long long)node_id, new_ver, |
|
|
|
|
|
|
|
nodeinfo1 ? nodeinfo1->last_ver : 0, |
|
|
|
|
|
|
|
(void*)bgp->local_node, (void*)nodeinfo1); |
|
|
|
|
|
|
|
|
|
|
|
if (nodeinfo1 && (int8_t)(nodeinfo1->last_ver-new_ver)>=0) { |
|
|
|
if (nodeinfo1 && (int8_t)(nodeinfo1->last_ver-new_ver)>=0) { |
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "NODEINFO from %s ignored (old ver %d <= %d)", |
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "NODEINFO from %s ignored (old ver %d <= %d)", |
|
|
|
from->log_name, new_ver, nodeinfo1->last_ver); |
|
|
|
from->log_name, new_ver, nodeinfo1->last_ver); |
|
|
|
@ -701,6 +707,24 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co |
|
|
|
queue_data_put_with_index(bgp->nodes, &nodeinfo1->ll, offsetof(struct NODEINFO_Q, node.node_id)-sizeof(struct ll_entry), 8); |
|
|
|
queue_data_put_with_index(bgp->nodes, &nodeinfo1->ll, offsetof(struct NODEINFO_Q, node.node_id)-sizeof(struct ll_entry), 8); |
|
|
|
} |
|
|
|
} |
|
|
|
else memcpy(&nodeinfo1->node, ni, sizeof(struct NODEINFO) + dyn_size); |
|
|
|
else memcpy(&nodeinfo1->node, ni, sizeof(struct NODEINFO) + dyn_size); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Если это наш local_node (по node_id), обновляем его данные */ |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Checking local_node update: node_id=%016llx my_id=%016llx local_node=%p", |
|
|
|
|
|
|
|
(unsigned long long)node_id, (unsigned long long)bgp->instance->node_id, (void*)bgp->local_node); |
|
|
|
|
|
|
|
if (node_id == bgp->instance->node_id && bgp->local_node) { |
|
|
|
|
|
|
|
/* Копируем динамическую часть (сокеты, подсети) из nodeinfo1 в local_node */ |
|
|
|
|
|
|
|
uint8_t* dyn_src = (uint8_t*)&nodeinfo1->node + sizeof(struct NODEINFO); |
|
|
|
|
|
|
|
uint8_t* dyn_dst = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO); |
|
|
|
|
|
|
|
int dyn_sz = nodeinfo1->node.node_name_len +
|
|
|
|
|
|
|
|
nodeinfo1->node.local_v4_sockets * sizeof(struct NODEINFO_IPV4_SOCKET) + |
|
|
|
|
|
|
|
nodeinfo1->node.local_v6_sockets * sizeof(struct NODEINFO_IPV6_SOCKET) + |
|
|
|
|
|
|
|
nodeinfo1->node.local_v4_subnets * sizeof(struct NODEINFO_IPV4_SUBNET) + |
|
|
|
|
|
|
|
nodeinfo1->node.local_v6_subnets * sizeof(struct NODEINFO_IPV6_SUBNET); |
|
|
|
|
|
|
|
memcpy(dyn_dst, dyn_src, dyn_sz); |
|
|
|
|
|
|
|
bgp->local_node->node.ver = nodeinfo1->node.ver; |
|
|
|
|
|
|
|
bgp->local_node->last_ver = new_ver; |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Updated local_node from NODEINFO for node %016llx", (unsigned long long)node_id); |
|
|
|
|
|
|
|
} |
|
|
|
nodeinfo1->paths = paths; |
|
|
|
nodeinfo1->paths = paths; |
|
|
|
nodeinfo1->last_ver = new_ver; |
|
|
|
nodeinfo1->last_ver = new_ver; |
|
|
|
|
|
|
|
|
|
|
|
@ -811,7 +835,10 @@ void route_bgp_send_nodeinfo(struct NODEINFO_Q* node, struct ETCP_CONN* conn) { |
|
|
|
e->dgram = p; |
|
|
|
e->dgram = p; |
|
|
|
e->len = ps; |
|
|
|
e->len = ps; |
|
|
|
|
|
|
|
|
|
|
|
etcp_send(conn, e); |
|
|
|
int ret = etcp_send(conn, e); |
|
|
|
|
|
|
|
if (ret != 0) { |
|
|
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NODEINFO failed: %d", ret); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void route_bgp_add_to_senders(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { |
|
|
|
static void route_bgp_add_to_senders(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { |
|
|
|
@ -881,9 +908,10 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f |
|
|
|
if (!bgp || !from_conn || !data || len < sizeof(struct BGP_NAT_INFO) || !bgp->local_node) return; |
|
|
|
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; |
|
|
|
const struct BGP_NAT_INFO* info = (const struct BGP_NAT_INFO*)data; |
|
|
|
|
|
|
|
/* IP в пакете в network byte order (big-endian bytes), конвертируем в host order */ |
|
|
|
uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) | |
|
|
|
uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) | |
|
|
|
(info->nat_ip[2] << 8) | info->nat_ip[3]; |
|
|
|
(info->nat_ip[2] << 8) | info->nat_ip[3]; |
|
|
|
uint16_t nat_port = ntohs(info->nat_port); |
|
|
|
uint16_t nat_port = ntohs(info->nat_port); /* порт из network byte order */ |
|
|
|
uint8_t socket_id = info->socket_id; |
|
|
|
uint8_t socket_id = info->socket_id; |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO recv: ip_bytes=0x%02x%02x%02x%02x ip_host=0x%08x port_net=%u port_host=%u", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO recv: ip_bytes=0x%02x%02x%02x%02x ip_host=0x%08x port_net=%u port_host=%u", |
|
|
|
info->nat_ip[0], info->nat_ip[1], info->nat_ip[2], info->nat_ip[3], |
|
|
|
info->nat_ip[0], info->nat_ip[1], info->nat_ip[2], info->nat_ip[3], |
|
|
|
@ -892,9 +920,13 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f |
|
|
|
uint8_t* dynamic = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO); |
|
|
|
uint8_t* dynamic = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO); |
|
|
|
dynamic += bgp->local_node->node.node_name_len; |
|
|
|
dynamic += bgp->local_node->node.node_name_len; |
|
|
|
struct NODEINFO_IPV4_SOCKET* sockets = (struct NODEINFO_IPV4_SOCKET*)dynamic; |
|
|
|
struct NODEINFO_IPV4_SOCKET* sockets = (struct NODEINFO_IPV4_SOCKET*)dynamic; |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO updating local_node: sockets_count=%d looking for socket_id=%u", |
|
|
|
|
|
|
|
bgp->local_node->node.local_v4_sockets, socket_id); |
|
|
|
for (int i = 0; i < bgp->local_node->node.local_v4_sockets; i++) { |
|
|
|
for (int i = 0; i < bgp->local_node->node.local_v4_sockets; i++) { |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, " checking socket %d: id=%u", i, sockets[i].id); |
|
|
|
if (sockets[i].id == socket_id) { |
|
|
|
if (sockets[i].id == socket_id) { |
|
|
|
uint8_t old_type = sockets[i].type; |
|
|
|
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) | |
|
|
|
uint32_t old_ip = (sockets[i].addr[0] << 24) | (sockets[i].addr[1] << 16) | |
|
|
|
(sockets[i].addr[2] << 8) | sockets[i].addr[3]; |
|
|
|
(sockets[i].addr[2] << 8) | sockets[i].addr[3]; |
|
|
|
uint16_t old_port = sockets[i].port; |
|
|
|
uint16_t old_port = sockets[i].port; |
|
|
|
@ -919,14 +951,21 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f |
|
|
|
es = es->next; |
|
|
|
es = es->next; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO update: socket_id=%u old_ip=0x%08x nat_ip=0x%08x old_port=%u nat_port=%u old_type=%u verified_type=%u changed=%d", |
|
|
|
|
|
|
|
socket_id, old_ip, nat_ip, old_port, nat_port, old_type, verified_type, |
|
|
|
|
|
|
|
(old_ip != nat_ip || old_port != nat_port || old_type != verified_type) ? 1 : 0); |
|
|
|
if (old_ip != nat_ip || old_port != nat_port || old_type != verified_type) { |
|
|
|
if (old_ip != nat_ip || old_port != nat_port || old_type != verified_type) { |
|
|
|
bgp->local_node->dirty = 1; |
|
|
|
bgp->local_node->dirty = 1; |
|
|
|
bgp->local_node->node.ver = (bgp->local_node->node.ver + 1) % 255 + 1; |
|
|
|
bgp->local_node->node.ver = (bgp->local_node->node.ver + 1) % 255 + 1; |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO triggered NODEINFO send, ver=%d senders=%d", |
|
|
|
|
|
|
|
bgp->local_node->node.ver, |
|
|
|
|
|
|
|
bgp->senders_list ? queue_entry_count(bgp->senders_list) : 0); |
|
|
|
if (bgp->senders_list) { |
|
|
|
if (bgp->senders_list) { |
|
|
|
struct ll_entry* se = bgp->senders_list->head; |
|
|
|
struct ll_entry* se = bgp->senders_list->head; |
|
|
|
while (se) { |
|
|
|
while (se) { |
|
|
|
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; |
|
|
|
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; |
|
|
|
if (item && item->conn) { |
|
|
|
if (item && item->conn) { |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO sending NODEINFO to %s", item->conn->log_name); |
|
|
|
route_bgp_send_nodeinfo(bgp->local_node, item->conn); |
|
|
|
route_bgp_send_nodeinfo(bgp->local_node, item->conn); |
|
|
|
} |
|
|
|
} |
|
|
|
se = se->next; |
|
|
|
se = se->next; |
|
|
|
@ -987,10 +1026,12 @@ void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t |
|
|
|
pkt->cmd = ETCP_ID_ROUTE_ENTRY; |
|
|
|
pkt->cmd = ETCP_ID_ROUTE_ENTRY; |
|
|
|
pkt->subcmd = ROUTE_SUBCMD_NAT_INFO; |
|
|
|
pkt->subcmd = ROUTE_SUBCMD_NAT_INFO; |
|
|
|
pkt->socket_id = socket_id; |
|
|
|
pkt->socket_id = socket_id; |
|
|
|
pkt->nat_ip[0] = (nat_ip >> 24) & 0xFF; |
|
|
|
/* IP в пакете хранится в network byte order (big-endian bytes) */ |
|
|
|
pkt->nat_ip[1] = (nat_ip >> 16) & 0xFF; |
|
|
|
uint32_t nat_ip_be = htonl(nat_ip); |
|
|
|
pkt->nat_ip[2] = (nat_ip >> 8) & 0xFF; |
|
|
|
pkt->nat_ip[0] = (nat_ip_be >> 24) & 0xFF; |
|
|
|
pkt->nat_ip[3] = nat_ip & 0xFF; |
|
|
|
pkt->nat_ip[1] = (nat_ip_be >> 16) & 0xFF; |
|
|
|
|
|
|
|
pkt->nat_ip[2] = (nat_ip_be >> 8) & 0xFF; |
|
|
|
|
|
|
|
pkt->nat_ip[3] = nat_ip_be & 0xFF; |
|
|
|
pkt->nat_port = htons(nat_port); |
|
|
|
pkt->nat_port = htons(nat_port); |
|
|
|
pkt->nat_type = nat_type; |
|
|
|
pkt->nat_type = nat_type; |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO send: ip_host=0x%08x ip_bytes=0x%02x%02x%02x%02x port_host=%u port_net=%u", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO send: ip_host=0x%08x ip_bytes=0x%02x%02x%02x%02x port_host=%u port_net=%u", |
|
|
|
@ -1008,7 +1049,7 @@ void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_info to %s: socket_id=%u type=%s ip=%s port=%u", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_info to %s: socket_id=%u type=%s ip=%s port=%u", |
|
|
|
conn->log_name, socket_id, |
|
|
|
conn->log_name, socket_id, |
|
|
|
nat_type == NAT_TYPE_OPEN ? "OPEN" : "RESTRICTED", |
|
|
|
nat_type == NAT_TYPE_OPEN ? "OPEN" : "RESTRICTED", |
|
|
|
ip_to_str(&nat_ip, AF_INET).str, (unsigned)nat_port); |
|
|
|
ip_to_str(pkt->nat_ip, AF_INET).str, (unsigned)nat_port); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { |
|
|
|
void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { |
|
|
|
|