Fix: round-robin link selection + byte order fixes + local_node update
This commit is contained in:
1 parent
77fd7c19de
commit
c136db5666
4 files changed
+97
-77
No files matched your search
+56
-15
@@ -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;
|
||||
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);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "nat check result: type=%s for node %s", success ? "OPEN" : "RESTRICTED", link->etcp->log_name);
|
||||
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 (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return;
|
||||
// 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
|
||||
/* link->nat_ip и sin_addr.s_addr в network byte order,
|
||||
конвертируем в host order для API route_ping_send_req_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;
|
||||
target_ip = ntohl(link->nat_ip); /* network → host order */
|
||||
target_port = link->nat_port; /* уже в host order */
|
||||
} else {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr;
|
||||
target_ip = sin->sin_addr.s_addr;
|
||||
target_port = ntohs(sin->sin_port);
|
||||
target_ip = ntohl(sin->sin_addr.s_addr); /* network → host order */
|
||||
target_port = ntohs(sin->sin_port); /* network → host order */
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "NODEINFO from %s ignored (old ver %d <= %d)",
|
||||
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);
|
||||
}
|
||||
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->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->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) {
|
||||
@@ -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;
|
||||
|
||||
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) |
|
||||
(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;
|
||||
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],
|
||||
@@ -892,11 +920,15 @@ 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);
|
||||
dynamic += bgp->local_node->node.node_name_len;
|
||||
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++) {
|
||||
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];
|
||||
(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;
|
||||
@@ -919,14 +951,21 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f
|
||||
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) {
|
||||
bgp->local_node->dirty = 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) {
|
||||
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) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO sending NODEINFO to %s", item->conn->log_name);
|
||||
route_bgp_send_nodeinfo(bgp->local_node, item->conn);
|
||||
}
|
||||
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->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;
|
||||
pkt->nat_ip[3] = nat_ip & 0xFF;
|
||||
/* IP в пакете хранится в network byte order (big-endian bytes) */
|
||||
uint32_t nat_ip_be = htonl(nat_ip);
|
||||
pkt->nat_ip[0] = (nat_ip_be >> 24) & 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_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",
|
||||
@@ -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",
|
||||
conn->log_name, socket_id,
|
||||
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) {
|
||||
|
||||
+17
-52
@@ -123,15 +123,13 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn,
|
||||
req_pkt->count = count;
|
||||
req_pkt->interval_ms = interval_ms;
|
||||
req_pkt->timeout_ms = timeout_ms;
|
||||
memcpy(req_pkt->target_ipv4, &target_ip, 4);
|
||||
/* IP и порт хранятся в network byte order (big-endian) в пакете */
|
||||
uint32_t target_ip_be = htonl(target_ip);
|
||||
memcpy(req_pkt->target_ipv4, &target_ip_be, 4);
|
||||
req_pkt->target_port = htons(target_port);
|
||||
if (pubkey) {
|
||||
memcpy(req_pkt->pubkey, pubkey, SC_PUBKEY_SIZE);
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "SEND_REQ: target_ip host=0x%08x net=0x%02x%02x%02x%02x port host=%u net=%u",
|
||||
target_ip,
|
||||
req_pkt->target_ipv4[0], req_pkt->target_ipv4[1], req_pkt->target_ipv4[2], req_pkt->target_ipv4[3],
|
||||
target_port, req_pkt->target_port);
|
||||
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
if (!e) {
|
||||
@@ -279,14 +277,11 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
|
||||
memcpy(ctx->pubkey, req_pkt->pubkey, SC_PUBKEY_SIZE);
|
||||
}
|
||||
|
||||
/* Целевой адрес */
|
||||
/* Целевой адрес - в sockaddr храним в network byte order (как в пакете) */
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&ctx->target_addr;
|
||||
sin->sin_family = AF_INET;
|
||||
memcpy(&sin->sin_addr.s_addr, req_pkt->target_ipv4, 4);
|
||||
sin->sin_port = req_pkt->target_port;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "RECV_REQ: target_ip net_bytes=0x%02x%02x%02x%02x sin_addr=0x%08x port_net=%u port_host=%u",
|
||||
req_pkt->target_ipv4[0], req_pkt->target_ipv4[1], req_pkt->target_ipv4[2], req_pkt->target_ipv4[3],
|
||||
sin->sin_addr.s_addr, req_pkt->target_port, ntohs(req_pkt->target_port));
|
||||
memcpy(&sin->sin_addr.s_addr, req_pkt->target_ipv4, 4); /* network byte order */
|
||||
sin->sin_port = req_pkt->target_port; /* порт в network byte order */
|
||||
|
||||
/* Если target не указан — можно разрешить из nodeinfo */
|
||||
/*
|
||||
@@ -305,47 +300,6 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
|
||||
}
|
||||
*/
|
||||
|
||||
/* Если pubkey не указан — ищем по target_ip:port в nodeinfo */
|
||||
int pubkey_empty = 1;
|
||||
for (int i = 0; i < SC_PUBKEY_SIZE; i++) {
|
||||
if (ctx->pubkey[i] != 0) { pubkey_empty = 0; break; }
|
||||
}
|
||||
if (pubkey_empty) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "looking for pubkey for target %s:%u, nodes_count=%d",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port),
|
||||
bgp->nodes ? bgp->nodes->count : -1);
|
||||
struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL;
|
||||
while (e) {
|
||||
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e;
|
||||
const struct NODEINFO_IPV4_SOCKET* sockets;
|
||||
int sc = get_node_v4_sockets(nq, &sockets);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "checking node %016llx with %d sockets",
|
||||
(unsigned long long)nq->node.node_id, sc);
|
||||
for (int i = 0; i < sc; i++) {
|
||||
uint32_t socket_ip, target_ip;
|
||||
memcpy(&socket_ip, sockets[i].addr, 4);
|
||||
memcpy(&target_ip, req_pkt->target_ipv4, 4);
|
||||
if (socket_ip == target_ip || socket_ip == htonl(target_ip) ||
|
||||
htonl(socket_ip) == target_ip || htonl(socket_ip) == htonl(target_ip)) {
|
||||
memcpy(ctx->pubkey, nq->node.public_key, SC_PUBKEY_SIZE);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "resolved pubkey from nodeinfo for %s:%u",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
break;
|
||||
}
|
||||
}
|
||||
pubkey_empty = 1;
|
||||
for (int i = 0; i < SC_PUBKEY_SIZE; i++) {
|
||||
if (ctx->pubkey[i] != 0) { pubkey_empty = 0; break; }
|
||||
}
|
||||
if (!pubkey_empty) break;
|
||||
e = e->next;
|
||||
}
|
||||
if (pubkey_empty) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "pubkey not found for target %s:%u",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
}
|
||||
}
|
||||
|
||||
/* Ищем первый IPv4-сокет (как в старом коде) */
|
||||
struct ETCP_SOCKET* ls = bgp->instance->etcp_sockets;
|
||||
while (ls) {
|
||||
@@ -370,6 +324,17 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
|
||||
(unsigned)ctx->count_total,
|
||||
(unsigned)ctx->timeout_ms);
|
||||
|
||||
/* Отладка: показываем что передаем в etcp_send_ping_to_socket */
|
||||
{
|
||||
struct sockaddr_in* dbg_sin = (struct sockaddr_in*)&ctx->target_addr;
|
||||
uint8_t* k = ctx->pubkey;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "SEND_PING: family=%u addr=0x%08x port=%u pubkey=%02x%02x%02x%02x...%02x%02x",
|
||||
(unsigned)dbg_sin->sin_family,
|
||||
(unsigned)dbg_sin->sin_addr.s_addr,
|
||||
(unsigned)ntohs(dbg_sin->sin_port),
|
||||
k[0], k[1], k[2], k[3], k[60], k[61]);
|
||||
}
|
||||
|
||||
/* Запускаем первый пинг (дальше цепочка через callback) */
|
||||
int ret = etcp_send_ping_to_socket(
|
||||
bgp->instance,
|
||||
|
||||
Reference in new issue
Block a user