refactor: TCP socket addresses — sync to chat DB, topo_node, config file single source

- chat: collect_my_addrs extends to TCP + IPv6, chat_core_sync_my_addresses writes TCP addrs
- topo_node: replace CFG_SERVER with TCP_SOCKET for TCP addresses, simplify NAT logic
- etcp_connections: add IPv6 interface addr resolution for TCP sockets
- Android: INI config file as single source of truth for servers, remove JSON/Gson
- Android: filter temporary IPv6 addresses, fix restart with socket cleanup
- instance_lite: sync addresses after socket creation, proper restart cleanup
This commit is contained in:
evgeny committed 2026-08-03 13:57:42 +03:00
1 parent 740ed2a93a
commit ddf696bcf6
9 files changed
+338 -161

No files matched your search

+53 -9
View File
@@ -18,6 +18,7 @@
#include "../../lib/ll_queue.h"
#include "../../lib/platform_compat.h"
#include "../transport_layer/etcp.h"
#include "../transport_layer/etcp_connections.h"
#include <openssl/sha.h>
#include <openssl/evp.h>
@@ -52,24 +53,66 @@ static int channel_sign_join(const uint8_t* ch_x25519, const uint8_t* ch_ed25519
/* ─── сбор адресов текущего узла (для member_sync_put) ─── */
static int collect_my_addrs(uint8_t* buf, int max_addrs) {
int count = 0;
static int collect_my_addrs(uint8_t* buf, int max_buf_sz) {
int pos = 0, count = 0;
struct ETCP_SOCKET* s = g_cc.inst->etcp_sockets;
while (s && count < max_addrs) {
while (s) {
struct sockaddr_storage* sa = s->interface_addr.ss_family ? &s->interface_addr : NULL;
if (!sa) sa = s->local_addr.ss_family ? &s->local_addr : NULL;
if (sa && sa->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
buf[count * 8] = 4;
buf[count * 8 + 1] = s->sock_id;
memcpy(buf + count * 8 + 2, &sin->sin_addr, 4);
if (pos + 8 > max_buf_sz) break;
buf[pos++] = 4; buf[pos++] = s->sock_id;
memcpy(buf + pos, &sin->sin_addr, 4); pos += 4;
uint16_t port = ntohs(sin->sin_port);
buf[count * 8 + 6] = (uint8_t)(port >> 8);
buf[count * 8 + 7] = (uint8_t)(port & 0xFF);
buf[pos++] = (uint8_t)(port >> 8); buf[pos++] = (uint8_t)(port & 0xFF);
count++;
uint8_t* ip = (uint8_t*)&sin->sin_addr;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] collect_my_addrs UDP sock=%d %d.%d.%d.%d:%d",
CC_ID, s->sock_id, ip[0], ip[1], ip[2], ip[3], port);
} else if (sa && sa->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
if (pos + 20 > max_buf_sz) break;
buf[pos++] = 6; buf[pos++] = s->sock_id;
memcpy(buf + pos, &sin6->sin6_addr, 16); pos += 16;
uint16_t port = ntohs(sin6->sin6_port);
buf[pos++] = (uint8_t)(port >> 8); buf[pos++] = (uint8_t)(port & 0xFF);
count++;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] collect_my_addrs UDP v6 sock=%d port=%d",
CC_ID, s->sock_id, port);
}
s = s->next;
}
{ struct TCP_SOCKET* ts = g_cc.inst->tcp_sockets;
while (ts) {
struct sockaddr_storage* addr = ts->interface_addr.ss_family ? &ts->interface_addr : &ts->local_addr;
if (addr && addr->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
if (pos + 8 > max_buf_sz) break;
buf[pos++] = 4; buf[pos++] = ts->sock_id;
memcpy(buf + pos, &sin->sin_addr, 4); pos += 4;
uint16_t port = ntohs(sin->sin_port);
buf[pos++] = (uint8_t)(port >> 8); buf[pos++] = (uint8_t)(port & 0xFF);
count++;
uint8_t* ip = (uint8_t*)&sin->sin_addr;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] collect_my_addrs TCP sock=%d %d.%d.%d.%d:%d",
CC_ID, ts->sock_id, ip[0], ip[1], ip[2], ip[3], port);
} else if (addr && addr->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
if (pos + 20 > max_buf_sz) break;
buf[pos++] = 6; buf[pos++] = ts->sock_id;
memcpy(buf + pos, &sin6->sin6_addr, 16); pos += 16;
uint16_t port = ntohs(sin6->sin6_port);
buf[pos++] = (uint8_t)(port >> 8); buf[pos++] = (uint8_t)(port & 0xFF);
count++;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] collect_my_addrs TCP v6 sock=%d port=%d",
CC_ID, ts->sock_id, port);
}
ts = ts->next; }
}
return count;
}
@@ -140,7 +183,7 @@ void chat_core_create_channel(struct chat_channel_create* req) {
myid, g_cc.inst->my_keys.public_key,
join_ts, g_cc.inst->my_ed25519_privkey, join_sig);
uint8_t my_addrs[256]; int my_addr_cnt = collect_my_addrs(my_addrs, 16);
uint8_t my_addrs[256]; int my_addr_cnt = collect_my_addrs(my_addrs, (int)sizeof(my_addrs));
char juser3[256]; snprintf(juser3, sizeof(juser3), "{\"name\":\"%s\"}",
g_cc.inst->name[0] ? g_cc.inst->name : "");
@@ -151,6 +194,7 @@ void chat_core_create_channel(struct chat_channel_create* req) {
DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "%s: member_sync_put(self) FAILED ch=%s rc=%d",
CC_ID, req->channel_id, mrc);
}
chat_core_sync_my_addresses();
}
chat_event_post(CHAT_EVT_CHANNEL_UPDATED, data, 1 + ch_id_len);
-2
View File
@@ -135,8 +135,6 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
g_cc.initialized = 1;
chat_core_sync_my_addresses();
/* create media_files table */
media_index_init(g_cc.db);
+51 -7
View File
@@ -12,6 +12,7 @@
#include "../utun_instance.h"
#include "../transport_layer/etcp.h"
#include "../transport_layer/etcp_connections.h"
#include "../transport_layer/secure_channel.h"
#include "../ntp_time.h"
#include "../../lib/u_async.h"
@@ -113,7 +114,7 @@ void chat_core_sync_my_addresses(void) {
}
struct ETCP_SOCKET* sock = g_cc.inst->etcp_sockets;
int sock_count = 0, written = 0;
int sock_count = 0, written = 0, tcp_written = 0;
while (sock) {
sock_count++;
int sock_family = sock->local_addr.ss_family ? sock->local_addr.ss_family : 0;
@@ -149,13 +150,56 @@ void chat_core_sync_my_addresses(void) {
}
sqlite3_finalize(ins);
if (sock_count == 0)
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] etcp_sockets is NULL — NO sockets, addresses NOT written!", CC_ID);
else if (written == 0)
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] %d sockets found but 0 addresses written (all have no interface_addr nor local_addr)", CC_ID, sock_count);
{ sqlite3_stmt* tcp_ins = NULL;
sqlite3_prepare_v2(g_cc.db,
"INSERT OR REPLACE INTO node_addresses(node_id,family,protocol,address,port,addr_type,socket_id)"
" VALUES(?,?,2,?,?,0,?)", -1, &tcp_ins, NULL);
if (tcp_ins) {
struct TCP_SOCKET* ts = g_cc.inst->tcp_sockets;
int tcp_count = 0;
while (ts) { if (ts->type == CFG_SERVER_TYPE_PRIVATE || ts->type == CFG_SERVER_TYPE_LOCAL) { ts = ts->next; continue; }
tcp_count++;
struct sockaddr_storage* addr = ts->interface_addr.ss_family ? &ts->interface_addr : &ts->local_addr;
if (!addr || !addr->ss_family) { ts = ts->next; continue; }
if (addr->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
sqlite3_bind_int64(tcp_ins, 1, (sqlite3_int64)g_cc.my_node_id);
sqlite3_bind_int(tcp_ins, 2, 4);
sqlite3_bind_blob(tcp_ins, 3, &sin->sin_addr, 4, SQLITE_STATIC);
sqlite3_bind_int(tcp_ins, 4, (int)ntohs(sin->sin_port));
sqlite3_bind_int(tcp_ins, 5, (int)ts->sock_id);
sqlite3_step(tcp_ins); sqlite3_reset(tcp_ins);
uint8_t* ip = (uint8_t*)&sin->sin_addr;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] INSERT TCP my_node=0x%016llx sock=%d %d.%d.%d.%d:%d",
CC_ID, (unsigned long long)g_cc.my_node_id, ts->sock_id, ip[0], ip[1], ip[2], ip[3], (int)ntohs(sin->sin_port));
tcp_written++;
} else if (addr->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
sqlite3_bind_int64(tcp_ins, 1, (sqlite3_int64)g_cc.my_node_id);
sqlite3_bind_int(tcp_ins, 2, 6);
sqlite3_bind_blob(tcp_ins, 3, &sin6->sin6_addr, 16, SQLITE_STATIC);
sqlite3_bind_int(tcp_ins, 4, (int)ntohs(sin6->sin6_port));
sqlite3_bind_int(tcp_ins, 5, (int)ts->sock_id);
sqlite3_step(tcp_ins); sqlite3_reset(tcp_ins);
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] INSERT TCP v6 my_node=0x%016llx sock=%d port=%d",
CC_ID, (unsigned long long)g_cc.my_node_id, ts->sock_id, (int)ntohs(sin6->sin6_port));
tcp_written++;
}
ts = ts->next; }
sqlite3_finalize(tcp_ins);
if (tcp_written > 0)
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] TCP DONE: %d addresses written, my_node=0x%016llx",
CC_ID, tcp_written, (unsigned long long)g_cc.my_node_id);
}
}
if (sock_count == 0 && tcp_written == 0)
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] no sockets found — NO addresses written!", CC_ID);
else if (written == 0 && tcp_written == 0)
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] %d sockets found but 0 addresses written", CC_ID, sock_count);
else
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] DONE: %d of %d sockets written, my_node=0x%016llx",
CC_ID, written, sock_count, (unsigned long long)g_cc.my_node_id);
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] DONE: %d UDP + %d TCP = %d total, my_node=0x%016llx",
CC_ID, written, tcp_written, written + tcp_written, (unsigned long long)g_cc.my_node_id);
sqlite3_stmt* chk = NULL;
sqlite3_prepare_v2(g_cc.db, "SELECT COUNT(*) FROM node_addresses WHERE node_id=? AND addr_type=0", -1, &chk, NULL);
+66 -60
View File
@@ -14,6 +14,7 @@
#include "route_lib.h"
#include "etcp_debug.h"
#include "topo_node_sqlite.h"
#include "../transport_layer/etcp_connections.h"
#include "../lib/u_async.h"
void topo_node_ref(struct TOPO_NODE* ni) {
@@ -603,26 +604,19 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
if (group->group_type == TOPO_GROUP_TYPE_CHAT) { vc = 0; vc6 = 0; }
int sock_count = 0, addr_count = 0, sock6_count = 0, addr6_count = 0;
int tcp4_count = 0, tcp6_count = 0;
struct ETCP_SOCKET* e_sock = instance->etcp_sockets;
while (e_sock) {
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL) { e_sock = e_sock->next; continue; }
if (e_sock->local_addr.ss_family == AF_INET) {
sock_count++; addr_count++;
if (e_sock->nat_addr.ss_family == AF_INET) {
struct sockaddr_in* ns = (struct sockaddr_in*)&e_sock->nat_addr;
struct sockaddr_in* ls = (struct sockaddr_in*)&e_sock->local_addr;
struct sockaddr_in* ifs = (struct sockaddr_in*)&e_sock->interface_addr;
uint32_t ref_ip = ls->sin_addr.s_addr ? ls->sin_addr.s_addr : ifs->sin_addr.s_addr;
uint16_t ref_port = ntohs(ls->sin_addr.s_addr ? ls->sin_port : ifs->sin_port);
if (ns->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT && (ns->sin_addr.s_addr != ref_ip || ntohs(ns->sin_port) != ref_port))
addr_count++;
}
if (e_sock->nat_type == NAT_VERIFIED_DIRECT || ((e_sock->type == CFG_SERVER_TYPE_PUBLIC || e_sock->type == CFG_SERVER_TYPE_UNKNOWN) && e_sock->nat_type < NAT_VERIFIED_UNKNOWN)) addr_count++;
} else if (e_sock->local_addr.ss_family == AF_INET6) { sock6_count++; addr6_count++; }
if (e_sock->local_addr.ss_family == AF_INET) { sock_count++; addr_count++; }
else if (e_sock->local_addr.ss_family == AF_INET6) { sock6_count++; addr6_count++; }
e_sock = e_sock->next;
}
{ struct CFG_SERVER* srv = instance->config->servers;
while (srv) { if (srv->transport) { if (srv->ip.ss_family == AF_INET) addr_count++; else if (srv->ip.ss_family == AF_INET6) addr6_count++; } srv = srv->next; }
{ struct TCP_SOCKET* ts = instance->tcp_sockets;
while (ts) { if (ts->type == CFG_SERVER_TYPE_PRIVATE || ts->type == CFG_SERVER_TYPE_LOCAL) { ts = ts->next; continue; }
if (ts->interface_addr.ss_family == AF_INET || ts->local_addr.ss_family == AF_INET) { tcp4_count++; addr_count++; }
else if (ts->interface_addr.ss_family == AF_INET6 || ts->local_addr.ss_family == AF_INET6) { tcp6_count++; addr6_count++; }
ts = ts->next; }
}
int changed = 1; uint8_t old_ver = 0;
@@ -693,25 +687,19 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
struct sockaddr_in* local_sin = (struct sockaddr_in*)&e_sock->local_addr;
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr;
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr;
int use_local = (local_sin->sin_addr.s_addr != 0);
uint32_t ref_ip = use_local ? local_sin->sin_addr.s_addr : if_sin->sin_addr.s_addr;
uint16_t ref_port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
int nat_verified = (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT);
int nat_differs = (nat_verified && (nat_sin->sin_addr.s_addr != ref_ip || ntohs(nat_sin->sin_port) != ref_port));
{ struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool);
memcpy(a->addr, use_local ? &local_sin->sin_addr.s_addr : &if_sin->sin_addr.s_addr, 4);
a->port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
a->type = (!nat_differs && nat_verified) ? TOPO_ADDR_NAT : TOPO_ADDR_INTERFACE;
a->socket_id = (a->type == TOPO_ADDR_NAT) ? (e_sock->sock_id | 1) : e_sock->sock_id;
if (nat_verified) {
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id | 1;
} else {
int use_local = (local_sin->sin_addr.s_addr != 0);
memcpy(a->addr, use_local ? &local_sin->sin_addr.s_addr : &if_sin->sin_addr.s_addr, 4);
a->port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id;
}
a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a; }
if (nat_differs) {
struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool);
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id | 1; a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a;
}
} else if (e_sock->local_addr.ss_family == AF_INET6) {
{ struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(group->instance->topo_groups->v6_sock_meta_pool);
sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->nat_type = e_sock->nat_type;
@@ -724,20 +712,24 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
}
e_sock = e_sock->next;
}
{ struct CFG_SERVER* srv = instance->config->servers;
while (srv) { if (srv->transport && srv->ip.ss_family == AF_INET) {
struct sockaddr_in* tcp_sin = (struct sockaddr_in*)&srv->ip;
struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool);
memcpy(a->addr, &tcp_sin->sin_addr.s_addr, 4); a->port = ntohs(tcp_sin->sin_port);
a->type = TOPO_ADDR_INTERFACE; a->socket_id = 0; a->protocol = TOPO_PROTO_TCP;
a->next = ni->v4_addrs; ni->v4_addrs = a;
} else if (srv->transport && srv->ip.ss_family == AF_INET6) {
struct sockaddr_in6* tcp_sin6 = (struct sockaddr_in6*)&srv->ip;
struct TOPO_ADDR6* a6 = memory_pool_alloc(group->instance->topo_groups->v6_addr_pool);
memcpy(a6->addr, &tcp_sin6->sin6_addr, 16); a6->port = ntohs(tcp_sin6->sin6_port);
a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = 0; a6->protocol = TOPO_PROTO_TCP;
a6->next = ni->v6_addrs; ni->v6_addrs = a6;
} srv = srv->next; }
{ struct TCP_SOCKET* ts = instance->tcp_sockets;
while (ts) { if (ts->type == CFG_SERVER_TYPE_PRIVATE || ts->type == CFG_SERVER_TYPE_LOCAL) { ts = ts->next; continue; }
struct sockaddr_storage* addr = ts->interface_addr.ss_family ? &ts->interface_addr : &ts->local_addr;
if (!addr || !addr->ss_family) { ts = ts->next; continue; }
if (addr->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
{ struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool);
memcpy(a->addr, &sin->sin_addr.s_addr, 4); a->port = ntohs(sin->sin_port);
a->type = TOPO_ADDR_INTERFACE; a->socket_id = ts->sock_id; a->protocol = TOPO_PROTO_TCP;
a->next = ni->v4_addrs; ni->v4_addrs = a; }
} else if (addr->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
{ struct TOPO_ADDR6* a6 = memory_pool_alloc(group->instance->topo_groups->v6_addr_pool);
memcpy(a6->addr, &sin6->sin6_addr, 16); a6->port = ntohs(sin6->sin6_port);
a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = ts->sock_id; a6->protocol = TOPO_PROTO_TCP;
a6->next = ni->v6_addrs; ni->v6_addrs = a6; }
}
ts = ts->next; }
}
if (group->group_type != TOPO_GROUP_TYPE_CHAT && (vc || vc6)) {
@@ -758,8 +750,8 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
lq->subnets = r;
}
DEBUG_INFO(DEBUG_CATEGORY_BGP, "my_nodeinfo updated: v4s=%d v4a=%d v6s=%d v6a=%d v4sub=%d v6sub=%d ver=%d",
sock_count, addr_count, sock6_count, addr6_count, vc, vc6, ni->ver);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "my_nodeinfo updated: v4s=%d v4a=%d v6s=%d v6a=%d tcp4=%d tcp6=%d v4sub=%d v6sub=%d ver=%d",
sock_count, addr_count, sock6_count, addr6_count, tcp4_count, tcp6_count, vc, vc6, ni->ver);
if (group->group_type != TOPO_GROUP_TYPE_CHAT && instance->rt && !route_insert(instance->rt, lq))
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "failed to insert local routes");
} else {
@@ -793,24 +785,19 @@ void topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
struct sockaddr_in* local_sin = (struct sockaddr_in*)&e_sock->local_addr;
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr;
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr;
int use_local = (local_sin->sin_addr.s_addr != 0);
uint32_t ref_ip = use_local ? local_sin->sin_addr.s_addr : if_sin->sin_addr.s_addr;
uint16_t ref_port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
int nat_verified = (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT);
int nat_differs = (nat_verified && (nat_sin->sin_addr.s_addr != ref_ip || ntohs(nat_sin->sin_port) != ref_port));
{ struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
memcpy(a->addr, use_local ? &local_sin->sin_addr.s_addr : &if_sin->sin_addr.s_addr, 4);
a->port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
a->type = (!nat_differs && nat_verified) ? TOPO_ADDR_NAT : TOPO_ADDR_INTERFACE;
a->socket_id = (a->type == TOPO_ADDR_NAT) ? (e_sock->sock_id | 1) : e_sock->sock_id;
if (nat_verified) {
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id | 1;
} else {
int use_local = (local_sin->sin_addr.s_addr != 0);
memcpy(a->addr, use_local ? &local_sin->sin_addr.s_addr : &if_sin->sin_addr.s_addr, 4);
a->port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id;
}
a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a; }
if (nat_differs) {
struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id | 1; a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a;
}
} else if (e_sock->local_addr.ss_family == AF_INET6) {
{ struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(instance->topo_groups->v6_sock_meta_pool);
sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->nat_type = e_sock->nat_type;
@@ -823,6 +810,25 @@ void topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
}
e_sock = e_sock->next;
}
{ struct TCP_SOCKET* ts = instance->tcp_sockets;
while (ts) { if (ts->type == CFG_SERVER_TYPE_PRIVATE || ts->type == CFG_SERVER_TYPE_LOCAL) { ts = ts->next; continue; }
struct sockaddr_storage* addr = ts->interface_addr.ss_family ? &ts->interface_addr : &ts->local_addr;
if (!addr || !addr->ss_family) { ts = ts->next; continue; }
if (addr->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
{ struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
memcpy(a->addr, &sin->sin_addr.s_addr, 4); a->port = ntohs(sin->sin_port);
a->type = TOPO_ADDR_INTERFACE; a->socket_id = ts->sock_id; a->protocol = TOPO_PROTO_TCP;
a->next = ni->v4_addrs; ni->v4_addrs = a; }
} else if (addr->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
{ struct TOPO_ADDR6* a6 = memory_pool_alloc(instance->topo_groups->v6_addr_pool);
memcpy(a6->addr, &sin6->sin6_addr, 16); a6->port = ntohs(sin6->sin6_port);
a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = ts->sock_id; a6->protocol = TOPO_PROTO_TCP;
a6->next = ni->v6_addrs; ni->v6_addrs = a6; }
}
ts = ts->next; }
}
ni->ver = (ni->ver % 255) + 1;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "my addresses updated, new ver=%d", ni->ver);
+30 -4
View File
@@ -784,18 +784,46 @@ struct TCP_SOCKET* tcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SER
rs->sin_family = AF_INET; rs->sin_port = htons(53);
inet_pton(AF_INET, "8.8.8.8", &rs->sin_addr);
struct sockaddr_storage local;
if (get_outgoing_local_ip(&server->ip, &remote, &local) == 0)
if (get_outgoing_local_ip(&server->ip, &remote, &local) == 0) {
ts->interface_addr = local;
((struct sockaddr_in*)&ts->interface_addr)->sin_port = sin->sin_port;
}
}
} else if (server->ip.ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&server->ip;
memcpy(&ts->local_addr, sin6, sizeof(*sin6));
ts->interface_addr = ts->local_addr;
if (server->type == CFG_SERVER_TYPE_PUBLIC && memcmp(&sin6->sin6_addr, &in6addr_any, sizeof(struct in6_addr)) == 0) {
uint16_t v6if = (server->netif_index > 0) ? server->netif_index : get_default_route_netif_index(AF_INET6);
if (v6if > 0) {
uint8_t v6addr[16];
int got = get_interface_ipv6_addr_nl(v6if, 1, v6addr);
if (got != 0) got = get_interface_ipv6_addr_nl(v6if, 0, v6addr);
if (got == 0) {
struct sockaddr_in6* if6 = (struct sockaddr_in6*)&ts->interface_addr;
if6->sin6_family = AF_INET6; memcpy(&if6->sin6_addr, v6addr, 16);
}
}
if (ts->interface_addr.ss_family == 0) {
struct sockaddr_storage remote; memset(&remote, 0, sizeof(remote));
struct sockaddr_in6* rs6 = (struct sockaddr_in6*)&remote;
rs6->sin6_family = AF_INET6; rs6->sin6_port = htons(53);
inet_pton(AF_INET6, "2001:4860:4860::8888", &rs6->sin6_addr);
if (get_outgoing_local_ip(&server->ip, &remote, &ts->interface_addr) == 0)
((struct sockaddr_in6*)&ts->interface_addr)->sin6_port = sin6->sin6_port;
else
ts->interface_addr = ts->local_addr;
}
}
}
ts->next = instance->tcp_sockets;
instance->tcp_sockets = ts;
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "tcp_socket_add: %s type=%d sock_id=%u", ts->name, ts->type, ts->sock_id);
{ char loc_str[64] = "none", if_str[64] = "none";
if (ts->local_addr.ss_family) snprintf(loc_str, sizeof(loc_str), "%s", sockaddr_storage_to_str(&ts->local_addr).str);
if (ts->interface_addr.ss_family) snprintf(if_str, sizeof(if_str), "%s", sockaddr_storage_to_str(&ts->interface_addr).str);
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "tcp_socket_add: %s type=%d sock_id=%u local=%s iface=%s",
ts->name, ts->type, ts->sock_id, loc_str, if_str); }
return ts;
}
@@ -1406,8 +1434,6 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk
if (g) {
topo_group_update_my_nodeinfo(g->instance, g);
if (g->local_node && g->senders_list) {
struct TOPO_NODE* vni = topo_node_registry_find(g->instance->topo_groups, g->local_node->node_id);
if (vni) vni->ver = (vni->ver % 255) + 1;
struct ll_entry* se = g->senders_list->head;
while (se) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data;