Browse Source

stcp: multiple servers support via linked list in UTUN_INSTANCE

- Replace instance->stcp_server (single pointer) with stcp_servers linked list
- Add stcp_server_list_add/destroy_all/count API in stcp_link.h/c
- Fix port extraction for both AF_INET and AF_INET6 in init_sockets
- Filter out 0.0.0.0 and [::] addresses in chat_profile.c TCP address sync
- Add type=public to servers in node_config.cpp saveFull()
topo_upd
evgeny 2 months ago
parent
commit
3deaa0eabe
  1. 2
      src/chat/chat_profile.c
  2. 24
      src/transport_layer/etcp_connections.c
  3. 2
      src/transport_layer/etcp_dump.c
  4. 27
      src/transport_layer/stcp_link.c
  5. 5
      src/transport_layer/stcp_link.h
  6. 7
      src/utun_instance.c
  7. 3
      src/utun_instance.h
  8. 3
      tools/chatgui/transport/node_config.cpp

2
src/chat/chat_profile.c

@ -163,6 +163,7 @@ void chat_core_sync_my_addresses(void) {
if (!addr || !addr->ss_family) { ts = ts->next; continue; }
if (addr->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
if (sin->sin_addr.s_addr == 0) { ts = ts->next; continue; } // skip 0.0.0.0
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);
@ -175,6 +176,7 @@ void chat_core_sync_my_addresses(void) {
tcp_written++;
} else if (addr->ss_family == AF_INET6) {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
if (memcmp(&sin6->sin6_addr, &in6addr_any, 16) == 0) { ts = ts->next; continue; } // skip ::
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);

24
src/transport_layer/etcp_connections.c

@ -213,7 +213,9 @@ void etcp_link_restart_init_timer(struct ETCP_LINK* link) {
void etcp_link_enter_init(struct ETCP_LINK* link) {//
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!link) return;
int old_state = link->link_state;
link->link_state = 1; // handshake
etcp_fire_link_status_cbk(link, old_state, link->link_status);
if (link->is_server != 0) return;
etcp_link_send_init(link,1,0);// init with reset
etcp_link_restart_init_timer(link);
@ -222,7 +224,9 @@ void etcp_link_enter_init(struct ETCP_LINK* link) {//
void etcp_link_enter_reinit(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!link) return;
int old_state = link->link_state;
link->link_state = 2; // reconnect
etcp_fire_link_status_cbk(link, old_state, link->link_status);
etcp_on_link_down(link->etcp);
if (link->is_server != 0) return;
etcp_conn_reinit(link->etcp);
@ -324,7 +328,9 @@ static void keepalive_timer_cb(void* arg) {
if (elapsed > timeout_units) {
if (link->recv_keepalive != 0) {
link->recv_keepalive = 0;
int old_link_status = link->link_status;
link->link_status = 0;
etcp_fire_link_status_cbk(link, link->link_state, old_link_status);
etcp_on_link_down(link->etcp);
DEBUG_INFO(DEBUG_CATEGORY_KEEPALIVE, "[%s] Conn:%s Link down: link_id=%d state=%d init=%d ka=%d remote_ka=%d tmo: %llu>%llu els=%llums", link->etcp->log_name, link->conn?link->conn->name:"???", link->local_link_id, link->link_state, link->initialized, link->recv_keepalive, link->remote_keepalive, (unsigned long long)timeout_units, (unsigned long long)elapsed, (unsigned long long)(elapsed/10));
DEBUG_WARN(DEBUG_CATEGORY_KEEPALIVE, "[%s] Link %p (local_id=%d) recv status changed to DOWN - no packets for %llu ms", link->etcp->log_name, link, link->local_link_id, (unsigned long long)(elapsed/10));
@ -1475,7 +1481,7 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk
memory_pool_free(e_sock->instance->pkt_pool, pkt);
link->initialized = 1;
link->link_state = 3;
{ int old_state = link->link_state; link->link_state = 3; etcp_fire_link_status_cbk(link, old_state, link->link_status); }
if (link->init_timer) {
uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer);
link->init_timer = NULL;
@ -1579,7 +1585,7 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D
etcp_update_log_name(link->etcp);
link->initialized = 1;// получен init response (client)
link->link_state = 3; // connected
{ int old_state = link->link_state; link->link_state = 3; etcp_fire_link_status_cbk(link, old_state, link->link_status); }
if (link->init_timer) {
uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer);
link->init_timer = NULL;
@ -2057,6 +2063,8 @@ process_decrypted:
int was_up = link->link_status;
link->link_status = link->remote_keepalive && link->recv_keepalive;
if (link->link_status != was_up)
etcp_fire_link_status_cbk(link, link->link_state, was_up);
if (link->link_status && !was_up && link->initialized) {
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] Link %d status popped UP: recv_ka=%d remote_ka=%d state=%d init=%d → calling loadbalancer_link_ready", link->etcp->log_name, link->local_link_id, link->recv_keepalive, link->remote_keepalive, link->link_state, link->initialized);
loadbalancer_link_ready(link);
@ -2091,7 +2099,7 @@ process_decrypted:
if (link->link_state == 2) {// из recovery получен нормальный пакет - восстанавливаем линк в нормальный режим
start_keepalive_timer(link);
etcp_link_send_keepalive(link); // Start keepalive timer
link->link_state = 3; // connected
{ int old_state = link->link_state; link->link_state = 3; etcp_fire_link_status_cbk(link, old_state, link->link_status); }
}
@ -2120,7 +2128,7 @@ ec_fr:
int init_sockets(struct UTUN_INSTANCE* instance) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!instance || !instance->config) return -1;
if (instance->etcp_sockets || instance->stcp_server) {
if (instance->etcp_sockets || instance->stcp_servers) {
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Sockets already initialized, skipping");
return 0;
}
@ -2179,14 +2187,16 @@ int init_sockets(struct UTUN_INSTANCE* instance) {
// TCP transport: create stcp_server instead of UDP socket
if (server->transport) {
uint16_t port = ntohs(((struct sockaddr_in*)&server->ip)->sin_port);
uint16_t port = 0;
if (server->ip.ss_family == AF_INET) port = ntohs(((struct sockaddr_in*)&server->ip)->sin_port);
else if (server->ip.ss_family == AF_INET6) port = ntohs(((struct sockaddr_in6*)&server->ip)->sin6_port);
struct stcp_link_config scfg = {.ua = instance->ua, .my_keys = &instance->my_keys, .inst = instance};
struct stcp_server *tsrv = stcp_server_listen(&scfg, port, tcp_server_on_link, instance);
if (!tsrv) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create TCP server for %s", server->name);
fail_count++;
} else {
instance->stcp_server = tsrv;
stcp_server_list_add(instance, tsrv);
tcp_socket_add(instance, server);
success_count++;
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "TCP server %s on port %u", server->name, port);
@ -2233,7 +2243,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
int socket_result = 0;
// If sockets already exist (created by init_sockets), check stored status
if (instance->etcp_sockets || instance->stcp_server) {
if (instance->etcp_sockets || instance->stcp_servers) {
if (instance->socket_init_status == 1) {
socket_result = 1;
}

2
src/transport_layer/etcp_dump.c

@ -193,7 +193,7 @@ void etcp_dump_sockets(struct UTUN_INSTANCE* instance) {
s = s->next; idx++;
}
if (idx == 0) DHDR("--- NO SOCKETS ---");
if (instance->stcp_server) DLOG("TCP: stcp_server ACTIVE");
if (instance->stcp_servers) DLOG("TCP: stcp_servers count=%d", stcp_server_list_count(instance));
if (instance->tcp_connections)
DLOG("TCP: tcp_connections queue %d entries", queue_entry_count(instance->tcp_connections));
DHDR("=== END DUMP SOCKETS ===");

27
src/transport_layer/stcp_link.c

@ -15,6 +15,7 @@
#include <netdb.h>
struct stcp_server {
struct stcp_server *next; // linked list in UTUN_INSTANCE
struct stcp_server *srv; // stcp_server from stcp_server.h
struct stcp_link_config cfg;
stcp_server_on_link_cb on_link;
@ -236,3 +237,29 @@ void stcp_link_set_on_close(struct stcp_link *link, void (*cb)(struct stcp_link
link->on_close_cb = cb;
link->close_arg = arg;
}
void stcp_server_list_add(struct UTUN_INSTANCE *inst, struct stcp_server *srv) {
if (!inst || !srv) return;
srv->next = inst->stcp_servers;
inst->stcp_servers = srv;
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "stcp_server_list_add: %p total=%d", (void*)srv, stcp_server_list_count(inst));
}
void stcp_server_list_destroy_all(struct UTUN_INSTANCE *inst) {
if (!inst) return;
int count = 0;
while (inst->stcp_servers) {
struct stcp_server *next = inst->stcp_servers->next;
stcp_link_server_destroy(inst->stcp_servers);
inst->stcp_servers = next;
count++;
}
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "stcp_server_list_destroy_all: destroyed %d servers", count);
}
int stcp_server_list_count(struct UTUN_INSTANCE *inst) {
if (!inst) return 0;
int n = 0;
for (struct stcp_server *s = inst->stcp_servers; s; s = s->next) n++;
return n;
}

5
src/transport_layer/stcp_link.h

@ -37,6 +37,11 @@ struct stcp_server *stcp_server_listen(struct stcp_link_config *cfg, uint16_t po
stcp_server_on_link_cb on_link, void *arg);
void stcp_link_server_destroy(struct stcp_server *srv);
/* Server list management (multiple servers per instance) */
void stcp_server_list_add(struct UTUN_INSTANCE *inst, struct stcp_server *srv);
void stcp_server_list_destroy_all(struct UTUN_INSTANCE *inst);
int stcp_server_list_count(struct UTUN_INSTANCE *inst);
// ====== TCP client link ======
struct stcp_link *stcp_link_connect(struct stcp_link_config *cfg);

7
src/utun_instance.c

@ -560,11 +560,8 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
// Cleanup firewall
fw_free(&instance->fw);
// Cleanup TCP server
if (instance->stcp_server) {
stcp_link_server_destroy(instance->stcp_server);
instance->stcp_server = NULL;
}
// Cleanup TCP servers
stcp_server_list_destroy_all(instance);
// Cleanup networks queue
if (instance->networks) {

3
src/utun_instance.h

@ -125,6 +125,7 @@ struct UTUN_INSTANCE {
// Callback chain for new ETCP connections
struct etcp_inst_cbk_entry* new_conn_cbks;
struct etcp_link_status_cbk_entry* link_status_cbks;
struct etcp_status_cbk_entry* conn_status_cbks; // instance-level: NEW/UP/DOWN/DELETE
struct etcp_socket_cbk_entry* socket_cbks; // instance-level: socket ADDR/STATUS changes
struct nodeinfo_cbk_entry* nodeinfo_cbks; // глобальная подписка на изменения nodeinfo
@ -137,7 +138,7 @@ struct UTUN_INSTANCE {
// Active sockets (UDP)
struct ETCP_SOCKET* etcp_sockets;// linked-list
struct TCP_SOCKET* tcp_sockets; // linked-list [TCP-only]
struct stcp_server *stcp_server; // TCP server (single for now)
struct stcp_server *stcp_servers; // TCP servers linked list (via stcp_link.c)
void* socket_monitor; // SOCKET_MONITOR* (opaque, transport_layer/socket_monitor.c)
// Pending one-shot pings (for callback on PONG or timeout)

3
tools/chatgui/transport/node_config.cpp

@ -328,7 +328,8 @@ bool NodeConfig::saveFull() {
for (auto& srv : m_servers) {
out << "[server:" << srv.first << "]\n";
out << "addr=" << srv.second << "\n\n";
out << "addr=" << srv.second << "\n";
out << "type=public\n\n";
}
for (auto& cli : m_clients) {

Loading…
Cancel
Save