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

+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);