From f5e18891bcea47b11f6c8d0c4dd7b4afa985cc5c Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 1 Aug 2026 20:03:21 +0300 Subject: [PATCH] =?UTF-8?q?chat=5Fsync:=20invite=20=E2=80=94=20process=20I?= =?UTF-8?q?Pv6=20addresses=20from=20invite=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cm_invite_trampoline() previously skipped all IPv6 addresses from invite links (if (family != 4) continue). Now: - DB save: save IPv6 addresses to node_addresses with family=6 - TOPO_NODE: create TOPO_ADDR6 entries, populate ni->v6_addrs - ncd_create_links already handles IPv6 sockets correctly - Condition check includes v6_addrs alongside v4_addrs - Cleanup frees v6_addrs chain --- src/chat/chat_sync.c | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/chat/chat_sync.c b/src/chat/chat_sync.c index cdb23925..311dcd65 100644 --- a/src/chat/chat_sync.c +++ b/src/chat/chat_sync.c @@ -629,12 +629,19 @@ static void cm_invite_trampoline(void* arg) { for (int i = 0; i < inv->addr_count; i++) { uint8_t family = *ap++; ap++; /* skip sock_id */ uint8_t proto = *ap++; /* read proto */ - if (family != 4) { ap += 18; continue; } - sqlite3_bind_int64(st, 1, (sqlite3_int64)node_id); sqlite3_bind_int(st, 2, 4); sqlite3_bind_int(st, 3, proto); - sqlite3_bind_blob(st, 4, ap, 4, SQLITE_STATIC); ap += 4; - uint16_t port = ((uint16_t)ap[0] << 8) | ap[1]; ap += 2; - sqlite3_bind_int(st, 5, (int)port); sqlite3_bind_int(st, 6, 1); /* addr_type=1 (DIRECT) */ - sqlite3_step(st); sqlite3_reset(st); + if (family == 4) { + sqlite3_bind_int64(st, 1, (sqlite3_int64)node_id); sqlite3_bind_int(st, 2, 4); sqlite3_bind_int(st, 3, proto); + sqlite3_bind_blob(st, 4, ap, 4, SQLITE_STATIC); ap += 4; + uint16_t port = ((uint16_t)ap[0] << 8) | ap[1]; ap += 2; + sqlite3_bind_int(st, 5, (int)port); sqlite3_bind_int(st, 6, 1); + sqlite3_step(st); sqlite3_reset(st); + } else if (family == 6) { + sqlite3_bind_int64(st, 1, (sqlite3_int64)node_id); sqlite3_bind_int(st, 2, 6); sqlite3_bind_int(st, 3, proto); + sqlite3_bind_blob(st, 4, ap, 16, SQLITE_STATIC); ap += 16; + uint16_t port = ((uint16_t)ap[0] << 8) | ap[1]; ap += 2; + sqlite3_bind_int(st, 5, (int)port); sqlite3_bind_int(st, 6, 1); + sqlite3_step(st); sqlite3_reset(st); + } else { ap += 18; } } sqlite3_finalize(st); } @@ -656,16 +663,24 @@ static void cm_invite_trampoline(void* arg) { for (int i = 0; i < inv->addr_count; i++) { uint8_t family = *ap++; uint8_t sock_id = *ap++; uint8_t proto = *ap++; uint16_t port = 0; - if (family == 4) { const uint8_t* a = ap; port = ((uint16_t)ap[4] << 8) | ap[5]; } - DEBUG_DEBUG(DEBUG_CATEGORY_DB_SYNC, "%s: invite addr[%d] family=%d proto=%d sock=%d %d.%d.%d.%d:%d", - CS_ID, i, family, proto, sock_id, ap[0], ap[1], ap[2], ap[3], port); - if (family != 4) { ap += 18; continue; } - struct TOPO_ADDR4* a4 = u_calloc(1, sizeof(*a4)); - if (!a4) break; - memcpy(a4->addr, ap, 4); ap += 4; - a4->port = ((uint16_t)ap[0] << 8) | ap[1]; ap += 2; - a4->type = TOPO_ADDR_NAT; a4->protocol = proto; - a4->next = ni->v4_addrs; ni->v4_addrs = a4; + if (family == 4) { port = ((uint16_t)ap[4] << 8) | ap[5]; } + DEBUG_DEBUG(DEBUG_CATEGORY_DB_SYNC, "%s: invite addr[%d] family=%d proto=%d sock=%d port=%d", + CS_ID, i, family, proto, sock_id, port); + if (family == 4) { + struct TOPO_ADDR4* a4 = u_calloc(1, sizeof(*a4)); + if (!a4) break; + memcpy(a4->addr, ap, 4); ap += 4; + a4->port = ((uint16_t)ap[0] << 8) | ap[1]; ap += 2; + a4->type = TOPO_ADDR_NAT; a4->protocol = proto; + a4->next = ni->v4_addrs; ni->v4_addrs = a4; + } else if (family == 6) { + struct TOPO_ADDR6* a6 = u_calloc(1, sizeof(*a6)); + if (!a6) break; + memcpy(a6->addr, ap, 16); ap += 16; + a6->port = ((uint16_t)ap[0] << 8) | ap[1]; ap += 2; + a6->type = TOPO_ADDR_NAT; a6->protocol = proto; + a6->next = ni->v6_addrs; ni->v6_addrs = a6; + } else { ap += 18; } } struct ETCP_CONN* existing = instance_find_conn(inst, node_id); @@ -685,19 +700,20 @@ static void cm_invite_trampoline(void* arg) { } else { DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "%s: invite conn in progress node=0x%016llx, waiting UP", CS_ID, (unsigned long long)node_id); } - } else if (inst->topo_groups && ni->v4_addrs) { + } else if (inst->topo_groups && (ni->v4_addrs || ni->v6_addrs)) { struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, channel_id); if (g && g->conn_mgr) { conn_mgr_open_invite(inst, channel_id, ni, node_id, NULL, NULL, NULL); DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC, "%s: invite connect posted node=0x%016llx", CS_ID, (unsigned long long)node_id); } } else { - DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "%s: invite no addrs topo=%p v4=%p", CS_ID, - (void*)inst->topo_groups, (void*)ni->v4_addrs); + DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "%s: invite no addrs topo=%p v4=%p v6=%p", CS_ID, + (void*)inst->topo_groups, (void*)ni->v4_addrs, (void*)ni->v6_addrs); } /* free caller-owned ni */ while (ni->v4_addrs) { struct TOPO_ADDR4* n = ni->v4_addrs->next; u_free(ni->v4_addrs); ni->v4_addrs = n; } + while (ni->v6_addrs) { struct TOPO_ADDR6* n = ni->v6_addrs->next; u_free(ni->v6_addrs); ni->v6_addrs = n; } u_free(ni); u_free(w); }