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:
1 parent
740ed2a93a
commit
ddf696bcf6
9 files changed
+338
-161
No files matched your search
+53
-9
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user