diff --git a/src/chat/chat_sync.c b/src/chat/chat_sync.c index a3702430..a08f46f6 100644 --- a/src/chat/chat_sync.c +++ b/src/chat/chat_sync.c @@ -748,6 +748,21 @@ static void cm_invite_trampoline(void* arg) { } 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) { 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; } diff --git a/src/routing_layer/conn_mgr_core.c b/src/routing_layer/conn_mgr_core.c index ee1bf947..5dc6be87 100644 --- a/src/routing_layer/conn_mgr_core.c +++ b/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; queue_data_put_with_index(group->nodes, &nq->ll); - /* 6. 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"); + /* 6. лог адресов ДО старта — виден даже при неудаче etcp_connect */ { char addrs[512] = ""; int aoff = 0; 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->protocol == TOPO_PROTO_UDP ? "UDP" : a->protocol == TOPO_PROTO_TCP ? "TCP" : "?"); 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" : "?"); 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); } + + /* 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; } diff --git a/src/routing_layer/topo_node.c b/src/routing_layer/topo_node.c index 6a51d878..33d87d1b 100644 --- a/src/routing_layer/topo_node.c +++ b/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; struct TOPO_NODE* existing = topo_node_registry_find(groups, ni->node_id); 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); 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; } @@ -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 + 8, &ni, sizeof(ni)); 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; } diff --git a/src/transport_layer/etcp_connect.c b/src/transport_layer/etcp_connect.c index ffc99ded..8ec685c0 100644 --- a/src/transport_layer/etcp_connect.c +++ b/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) { if (!node) return; 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; { 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) { @@ -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]", 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", - addr_count, sock_count, link_count, (unsigned long long)node->node_id); + 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, 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) { if (!node) return; 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) { - if (a->port == 0) continue; - int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) continue; + addr_count++; + 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; 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 addr_links = 0; if (!(a->protocol & TOPO_PROTO_TCP)) { struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; while (s) { if (s->local_addr.ss_family == AF_INET6) { if (is_ll) sin6.sin6_scope_id = s->netif_index; 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; } } 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; 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); - 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; } } + 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) { @@ -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); 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", - (unsigned long long)node->node_id, *(uint64_t*)ni->public_key, (void*)ni->v4_addrs, (void*)ni->v4_sock_meta); + 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, + 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; if (node_id == 0) { diff --git a/tools/chatgui/src/joindialog.cpp b/tools/chatgui/src/joindialog.cpp index 445b4a68..df86461d 100644 --- a/tools/chatgui/src/joindialog.cpp +++ b/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()); - GUI_INFO("join: decoded invite ch=%llu pubkey=%016llx... nodeId=0x%016llx addrs=%d", - d.channelId, *(const uint64_t*)d.pubkey.constData(), nodeId, d.addrs.size()); + QString addrDbg; + 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_pendingChannelId = d.channelId;