Browse Source

invite: диагностика адресов в цепочке invite→etcp_connect

topo_upd
Evgeny 2 months ago
parent
commit
37ef08a015
  1. 15
      src/chat/chat_sync.c
  2. 17
      src/routing_layer/conn_mgr_core.c
  3. 12
      src/routing_layer/topo_node.c
  4. 30
      src/transport_layer/etcp_connect.c
  5. 15
      tools/chatgui/src/joindialog.cpp

15
src/chat/chat_sync.c

@ -748,6 +748,21 @@ static void cm_invite_trampoline(void* arg) {
} else { ap += 18; } } else { ap += 18; }
} }
{ char buf[512]; int off = 0; int n4 = 0, n6 = 0;
for (const struct TOPO_ADDR4* a4 = ni->v4_addrs; a4; a4 = a4->next) {
n4++;
off += snprintf(buf + off, sizeof(buf) - (size_t)off, "%s%d.%d.%d.%d:%d(p=%d)",
off ? "," : "", a4->addr[0], a4->addr[1], a4->addr[2], a4->addr[3], a4->port, a4->protocol);
}
for (const struct TOPO_ADDR6* a6 = ni->v6_addrs; a6; a6 = a6->next) {
n6++;
off += snprintf(buf + off, sizeof(buf) - (size_t)off, "%s%s:%d(p=%d)",
off ? "," : "", ip_to_str(a6->addr, AF_INET6).str, a6->port, a6->protocol);
}
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "channel invite: parsed node=0x%016llx addrs v4=%d v6=%d [%s]",
(unsigned long long)node_id, n4, n6, (n4 || n6) ? buf : "(none)");
}
if (!ni->v4_addrs && !ni->v6_addrs) { if (!ni->v4_addrs && !ni->v6_addrs) {
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "invite: no valid addrs for node=0x%016llx", (unsigned long long)node_id); DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "invite: no valid addrs for node=0x%016llx", (unsigned long long)node_id);
while (ni->v4_addrs) { struct TOPO_ADDR4* n = ni->v4_addrs->next; u_free(ni->v4_addrs); ni->v4_addrs = n; } while (ni->v4_addrs) { struct TOPO_ADDR4* n = ni->v4_addrs->next; u_free(ni->v4_addrs); ni->v4_addrs = n; }

17
src/routing_layer/conn_mgr_core.c

@ -1162,12 +1162,7 @@ int conn_mgr_open_invite(struct UTUN_INSTANCE* inst,
if (!h) { cm_invite_fail(inv); return -1; } inv->handle=h; if (out_handle) *out_handle=h; if (!h) { cm_invite_fail(inv); return -1; } inv->handle=h; if (out_handle) *out_handle=h;
queue_data_put_with_index(group->nodes, &nq->ll); queue_data_put_with_index(group->nodes, &nq->ll);
/* 6. etcp_connect — запускает UDP links + TCP STCP link через единый API */ /* 6. лог адресов ДО старта — виден даже при неудаче etcp_connect */
if (etcp_connect(inst, nq, cm_invite_etcp_cb, inv, ETCP_CONNECT_EARLY | ETCP_CONNECT_LATE) != 0) {
cm_invite_fail(inv); if (out_handle) *out_handle=NULL; return -1;
}
inv->overall_timer = uasync_set_timeout(inst->ua, CM_INVITE_DEFAULT_TIMEOUT_MS*10, inv, cm_invite_overall_timeout, "conn_mgr_invite");
{ {
char addrs[512] = ""; int aoff = 0; char addrs[512] = ""; int aoff = 0;
for (const struct TOPO_ADDR4* a = gni->v4_addrs; a; a = a->next) for (const struct TOPO_ADDR4* a = gni->v4_addrs; a; a = a->next)
@ -1175,10 +1170,18 @@ int conn_mgr_open_invite(struct UTUN_INSTANCE* inst,
a->addr[0], a->addr[1], a->addr[2], a->addr[3], (int)a->port, a->addr[0], a->addr[1], a->addr[2], a->addr[3], (int)a->port,
a->protocol == TOPO_PROTO_UDP ? "UDP" : a->protocol == TOPO_PROTO_TCP ? "TCP" : "?"); a->protocol == TOPO_PROTO_UDP ? "UDP" : a->protocol == TOPO_PROTO_TCP ? "TCP" : "?");
for (const struct TOPO_ADDR6* a6 = gni->v6_addrs; a6; a6 = a6->next) for (const struct TOPO_ADDR6* a6 = gni->v6_addrs; a6; a6 = a6->next)
aoff += snprintf(addrs + aoff, sizeof(addrs) - (size_t)aoff, " [v6]:%d(%s)", (int)a6->port, aoff += snprintf(addrs + aoff, sizeof(addrs) - (size_t)aoff, " %s:%d(%s)",
ip_to_str(a6->addr, AF_INET6).str, (int)a6->port,
a6->protocol == TOPO_PROTO_UDP ? "UDP" : a6->protocol == TOPO_PROTO_TCP ? "TCP" : "?"); a6->protocol == TOPO_PROTO_UDP ? "UDP" : a6->protocol == TOPO_PROTO_TCP ? "TCP" : "?");
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "invite: starting to 0x%016llx via%s timeout=%ds", DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "invite: starting to 0x%016llx via%s timeout=%ds",
(unsigned long long)nid, addrs, CM_INVITE_DEFAULT_TIMEOUT_MS/1000); (unsigned long long)nid, addrs, CM_INVITE_DEFAULT_TIMEOUT_MS/1000);
} }
/* 7. etcp_connect — запускает UDP links + TCP STCP link через единый API */
if (etcp_connect(inst, nq, cm_invite_etcp_cb, inv, ETCP_CONNECT_EARLY | ETCP_CONNECT_LATE) != 0) {
cm_invite_fail(inv); if (out_handle) *out_handle=NULL; return -1;
}
inv->overall_timer = uasync_set_timeout(inst->ua, CM_INVITE_DEFAULT_TIMEOUT_MS*10, inv, cm_invite_overall_timeout, "conn_mgr_invite");
return 0; return 0;
} }

12
src/routing_layer/topo_node.c

@ -119,6 +119,14 @@ struct TOPO_NODE* topo_node_registry_store(struct TOPO_GROUPS* groups, struct TO
if (!groups || !ni) return NULL; if (!groups || !ni) return NULL;
struct TOPO_NODE* existing = topo_node_registry_find(groups, ni->node_id); struct TOPO_NODE* existing = topo_node_registry_find(groups, ni->node_id);
if (existing) { if (existing) {
int n4 = topo_list_count((struct _topo_head*)ni->v4_addrs);
int n6 = topo_list_count((struct _topo_head*)ni->v6_addrs);
int e4 = topo_list_count((struct _topo_head*)existing->v4_addrs);
int e6 = topo_list_count((struct _topo_head*)existing->v6_addrs);
int drop4 = (e4 && n4), drop6 = (e6 && n6);
if (drop4 || drop6)
DEBUG_WARN(DEBUG_CATEGORY_BGP, "registry_store: node=%016llx EXISTS — dropping new addrs v4=%d v6=%d (existing v4=%d v6=%d)",
(unsigned long long)ni->node_id, drop4 ? n4 : 0, drop6 ? n6 : 0, e4, e6);
topo_node_ref(existing); topo_node_ref(existing);
if (!existing->v4_addrs && ni->v4_addrs) { existing->v4_addrs = ni->v4_addrs; ni->v4_addrs = NULL; } if (!existing->v4_addrs && ni->v4_addrs) { existing->v4_addrs = ni->v4_addrs; ni->v4_addrs = NULL; }
if (!existing->v6_addrs && ni->v6_addrs) { existing->v6_addrs = ni->v6_addrs; ni->v6_addrs = NULL; } if (!existing->v6_addrs && ni->v6_addrs) { existing->v6_addrs = ni->v6_addrs; ni->v6_addrs = NULL; }
@ -134,6 +142,10 @@ struct TOPO_NODE* topo_node_registry_store(struct TOPO_GROUPS* groups, struct TO
memcpy(qe->data, &ni->node_id, 8); memcpy(qe->data, &ni->node_id, 8);
memcpy(qe->data + 8, &ni, sizeof(ni)); memcpy(qe->data + 8, &ni, sizeof(ni));
queue_data_put_with_index(groups->node_registry, qe); queue_data_put_with_index(groups->node_registry, qe);
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "registry_store: node=%016llx NEW v4=%d v6=%d",
(unsigned long long)ni->node_id,
topo_list_count((struct _topo_head*)ni->v4_addrs),
topo_list_count((struct _topo_head*)ni->v6_addrs));
return ni; return ni;
} }

30
src/transport_layer/etcp_connect.c

@ -68,7 +68,7 @@ static void connect_cancel(struct ETCP_CONNECT* ctx) {
static void connect_create_links_v4(struct ETCP_CONNECT* ctx, struct TOPO_GROUP_NODE* node) { static void connect_create_links_v4(struct ETCP_CONNECT* ctx, struct TOPO_GROUP_NODE* node) {
if (!node) return; if (!node) return;
struct TOPO_NODE* ni = topo_node_registry_find(ctx->instance->topo_groups, node->node_id); struct TOPO_NODE* ni = topo_node_registry_find(ctx->instance->topo_groups, node->node_id);
if (!ni) { DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[etcp_connect] links_v4: ni NOT in registry for node=%016llx", (unsigned long long)node->node_id); return; } if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[etcp_connect] links_v4: ni NOT in registry for node=%016llx", (unsigned long long)node->node_id); return; }
int addr_count = 0, sock_count = 0, link_count = 0; int addr_count = 0, sock_count = 0, link_count = 0;
{ struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; while (s) { sock_count++; s = s->next; } } { struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; while (s) { sock_count++; s = s->next; } }
for (const struct TOPO_ADDR4* a = ni->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = ni->v4_addrs; a; a = a->next) {
@ -93,26 +93,30 @@ static void connect_create_links_v4(struct ETCP_CONNECT* ctx, struct TOPO_GROUP_
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] link_v4: %d.%d.%d.%d:%d proto=%d links=%d conn=[%s]", DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] link_v4: %d.%d.%d.%d:%d proto=%d links=%d conn=[%s]",
a->addr[0], a->addr[1], a->addr[2], a->addr[3], a->port, a->protocol, addr_links, ctx->conn->log_name); a->addr[0], a->addr[1], a->addr[2], a->addr[3], a->port, a->protocol, addr_links, ctx->conn->log_name);
} }
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] links_v4: TOTAL addrs=%d socks=%d links=%d for node=%016llx", DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] links_v4: TOTAL addrs=%d socks=%d links=%d%s for node=%016llx",
addr_count, sock_count, link_count, (unsigned long long)node->node_id); addr_count, sock_count, link_count, addr_count == 0 ? " (v4_addrs EMPTY)" : "", (unsigned long long)node->node_id);
} }
static void connect_create_links_v6(struct ETCP_CONNECT* ctx, struct TOPO_GROUP_NODE* node) { static void connect_create_links_v6(struct ETCP_CONNECT* ctx, struct TOPO_GROUP_NODE* node) {
if (!node) return; if (!node) return;
struct TOPO_NODE* ni = topo_node_registry_find(ctx->instance->topo_groups, node->node_id); struct TOPO_NODE* ni = topo_node_registry_find(ctx->instance->topo_groups, node->node_id);
if (!ni) return; if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[etcp_connect] links_v6: ni NOT in registry for node=%016llx", (unsigned long long)node->node_id); return; }
int addr_count = 0, sock_count = 0, link_count = 0;
{ struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; while (s) { sock_count++; s = s->next; } }
for (const struct TOPO_ADDR6* a = ni->v6_addrs; a; a = a->next) { for (const struct TOPO_ADDR6* a = ni->v6_addrs; a; a = a->next) {
if (a->port == 0) continue; addr_count++;
int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) continue; if (a->port == 0) { DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] link_v6: skip port==0 node=%016llx", (unsigned long long)node->node_id); continue; }
int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) { DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] link_v6: skip zero addr node=%016llx", (unsigned long long)node->node_id); continue; }
struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr, a->addr, 16); sin6.sin6_port = htons(a->port); memcpy(&sin6.sin6_addr, a->addr, 16); sin6.sin6_port = htons(a->port);
int is_ll = (a->addr[0] == 0xfe && (a->addr[1] & 0xc0) == 0x80); int is_ll = (a->addr[0] == 0xfe && (a->addr[1] & 0xc0) == 0x80);
int addr_links = 0;
if (!(a->protocol & TOPO_PROTO_TCP)) { if (!(a->protocol & TOPO_PROTO_TCP)) {
struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; struct ETCP_SOCKET* s = ctx->instance->etcp_sockets;
while (s) { if (s->local_addr.ss_family == AF_INET6) { while (s) { if (s->local_addr.ss_family == AF_INET6) {
if (is_ll) sin6.sin6_scope_id = s->netif_index; if (is_ll) sin6.sin6_scope_id = s->netif_index;
struct sockaddr_storage sa; memcpy(&sa, &sin6, sizeof(sin6)); struct sockaddr_storage sa; memcpy(&sa, &sin6, sizeof(sin6));
etcp_link_new(ctx->conn, s, &sa, 0); if (etcp_link_new(ctx->conn, s, &sa, 0)) { link_count++; addr_links++; }
} s = s->next; } } s = s->next; }
} }
if (a->protocol & TOPO_PROTO_TCP) { if (a->protocol & TOPO_PROTO_TCP) {
@ -124,10 +128,14 @@ static void connect_create_links_v6(struct ETCP_CONNECT* ctx, struct TOPO_GROUP_
struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; struct ETCP_SOCKET* s = ctx->instance->etcp_sockets;
while (s) { if (s->is_tcp && s->local_addr.ss_family == AF_INET6) { while (s) { if (s->is_tcp && s->local_addr.ss_family == AF_INET6) {
struct ETCP_LINK *tlink = etcp_link_new(ctx->conn, s, &sa, 0); struct ETCP_LINK *tlink = etcp_link_new(ctx->conn, s, &sa, 0);
if (tlink) { tlink->is_tcp = 1; etcp_tcp_link_start_connect(tlink, &sa, a->port); } if (tlink) { tlink->is_tcp = 1; etcp_tcp_link_start_connect(tlink, &sa, a->port); link_count++; addr_links++; }
} s = s->next; } } s = s->next; }
} }
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] link_v6: %s:%d proto=%d links=%d conn=[%s]",
ip_to_str(a->addr, AF_INET6).str, a->port, a->protocol, addr_links, ctx->conn->log_name);
} }
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] links_v6: TOTAL addrs=%d socks=%d links=%d%s for node=%016llx",
addr_count, sock_count, link_count, addr_count == 0 ? " (v6_addrs EMPTY)" : "", (unsigned long long)node->node_id);
} }
static void connect_bgp_ready_cb(struct ETCP_CONN* conn) { static void connect_bgp_ready_cb(struct ETCP_CONN* conn) {
@ -225,8 +233,10 @@ int etcp_connect(struct UTUN_INSTANCE* inst, struct TOPO_GROUP_NODE* node,
struct TOPO_NODE* ni = topo_node_registry_find(inst->topo_groups, node->node_id); struct TOPO_NODE* ni = topo_node_registry_find(inst->topo_groups, node->node_id);
if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP_CONNECT, "[etcp_connect] node not in registry"); return -1; } if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP_CONNECT, "[etcp_connect] node not in registry"); return -1; }
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[etcp_connect] registry OK node=%016llx pub=%016llx v4addrs=%p v4socks=%p", DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[etcp_connect] registry OK node=%016llx pub=%016llx v4addrs=%d v6addrs=%d",
(unsigned long long)node->node_id, *(uint64_t*)ni->public_key, (void*)ni->v4_addrs, (void*)ni->v4_sock_meta); (unsigned long long)node->node_id, *(uint64_t*)ni->public_key,
topo_list_count((struct _topo_head*)ni->v4_addrs),
topo_list_count((struct _topo_head*)ni->v6_addrs));
uint64_t node_id = ni->node_id; uint64_t node_id = ni->node_id;
if (node_id == 0) { if (node_id == 0) {

15
tools/chatgui/src/joindialog.cpp

@ -163,8 +163,19 @@ void JoinDialog::onConnectClicked() {
uint64_t nodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData()); uint64_t nodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData());
GUI_INFO("join: decoded invite ch=%llu pubkey=%016llx... nodeId=0x%016llx addrs=%d", QString addrDbg;
d.channelId, *(const uint64_t*)d.pubkey.constData(), nodeId, d.addrs.size()); for (const auto& a : d.addrs) {
if (a.family == 4 && a.address.size() == 4) {
const uint8_t* b = (const uint8_t*)a.address.constData();
addrDbg += QString("%1.%2.%3.%4").arg(b[0]).arg(b[1]).arg(b[2]).arg(b[3]);
} else {
addrDbg += QString("v6:%1").arg(QString(a.address.toHex()));
}
addrDbg += QString(":%1(p=%2) ").arg(a.port).arg(a.proto);
}
GUI_INFO("join: decoded invite ch=%llu pubkey=%016llx... nodeId=0x%016llx addrs=%d addr=%s",
d.channelId, *(const uint64_t*)d.pubkey.constData(), nodeId, d.addrs.size(),
addrDbg.trimmed().toUtf8().constData());
m_pendingNodeId = nodeId; m_pendingNodeId = nodeId;
m_pendingChannelId = d.channelId; m_pendingChannelId = d.channelId;

Loading…
Cancel
Save