fix: auto_socket TCP duplicate sockets + NAT v4 address resolution

auto_socket.c: create_iface_tcp_socket returns stcp_server* instead of int,
ifa->v4_tcp/ifa->v6_tcp now properly track the created server, preventing
duplicate bind/listen on every reconcile_iface call.

etcp_connections.c: tcp_socket_add now resolves interface_addr via
get_interface_ip_by_index/get_interface_ipv6_addr_nl for any type (not just
PUBLIC), preventing NAT TCP v4 sockets from being destroyed due to INADDR_ANY.
This commit is contained in:
evgeny committed 2026-08-07 20:06:30 +03:00
1 parent de61a2dacc
commit 80e77f12c2
12 files changed
+202 -66

No files matched your search

@@ -22,6 +22,7 @@
#include "../../../src/utun_instance.h"
#include "../../../src/transport_layer/etcp.h"
#include "../../../src/transport_layer/etcp_connections.h"
#include "../../../src/transport_layer/auto_socket.h"
#include "../../../src/transport_layer/secure_channel.h"
#include <stdio.h>
#include <stdlib.h>
@@ -1060,6 +1061,8 @@ char* utun_bridge_get_local_sockets_json(void) {
json[0] = '[';
int first = 1;
bridge_log(BLEV_INFO, "getLocalSockets: tcp_sockets=%p etcp_sockets=%p conns=%d links=%d",
(void*)inst->tcp_sockets, (void*)inst->etcp_sockets, active_conns, active_links);
/* TCP sockets */
{ struct TCP_SOCKET* ts = inst->tcp_sockets;
while (ts) {
@@ -1074,7 +1077,7 @@ char* utun_bridge_get_local_sockets_json(void) {
port = ntohs(sin6->sin6_port);
inet_ntop(AF_INET6, &sin6->sin6_addr, ip_str, sizeof(ip_str));
}
int state = active_conns > 0 ? 2 : 0;
int state = 2; /* bound and listening */
const char* sep = first ? "" : ","; first = 0;
size_t needed = snprintf(NULL, 0, "%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"TCP\",\"st\":%d,\"lk\":%d}",
sep, ts->sock_id, ts->name, ip_str, port, state, active_links);
@@ -1101,7 +1104,7 @@ char* utun_bridge_get_local_sockets_json(void) {
inet_ntop(AF_INET6, &sin6->sin6_addr, ip_str, sizeof(ip_str));
}
int lk = es->links_queue ? queue_entry_count(es->links_queue) : 0;
int state = lk > 0 ? 2 : 0;
int state = 2; /* bound and listening */
const char* sep = first ? "" : ","; first = 0;
size_t needed = snprintf(NULL, 0, "%s{\"si\":%u,\"nm\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"pt\":\"UDP\",\"st\":%d,\"lk\":%d}",
sep, es->sock_id, es->name, ip_str, port, state, lk);
@@ -1117,6 +1120,12 @@ char* utun_bridge_get_local_sockets_json(void) {
return json;
}
void utun_bridge_on_network_change(void) {
if (!g_cc.inst) return;
auto_socket_on_network_change(g_cc.inst);
bridge_log(BLEV_DEBUG, "network change notified to auto_socket");
}
void utun_bridge_restart(const char* config_text) {
bridge_log(BLEV_INFO, "bridge restart: posting to instance");
#ifdef __ANDROID__
@@ -1914,4 +1923,12 @@ JNIEXPORT jstring JNICALL Java_com_utun_chat_data_NativeLib_nativeGetLocalSocket
return result;
}
/* ── Network change notification ── */
JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeOnNetworkChanged(
JNIEnv* env, jobject thiz) {
(void)env; (void)thiz;
utun_bridge_on_network_change();
}
#endif /* __ANDROID__ */
@@ -129,6 +129,10 @@ char* utun_bridge_get_member_links_json(uint64_t node_id);
char* utun_bridge_get_local_sockets_json(void);
/* ── Network change notification (ConnectivityManager → auto_socket) ── */
void utun_bridge_on_network_change(void);
#ifdef __cplusplus
}
#endif