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:
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
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <QLabel>
|
||||
#include <QDateTime>
|
||||
#include <QFont>
|
||||
#include <QSet>
|
||||
#include "../../../lib/platform_compat.h"
|
||||
|
||||
extern "C" {
|
||||
@@ -16,6 +17,8 @@ extern "C" {
|
||||
#include "etcp.h"
|
||||
#include "etcp_connections.h"
|
||||
#include "../lib/socket_compat.h"
|
||||
#include "../lib/ll_queue.h"
|
||||
#include "stcp_link.h"
|
||||
}
|
||||
|
||||
QString AccountList::addrStr(const void* addr, int family) {
|
||||
@@ -211,6 +214,30 @@ void AccountList::updateDetailDisplay() {
|
||||
struct ETCP_CONN* conn = nullptr;
|
||||
if (m_inst) conn = instance_find_conn(m_inst, m_detailNodeId);
|
||||
|
||||
bool isSelf = m_db ? (m_detailNodeId == m_db->myNodeId()) : false;
|
||||
QSet<struct ETCP_LINK*> matchedLinks;
|
||||
|
||||
/* Count active TCP connections for own node (shared across all TCP sockets) */
|
||||
int ownTcpActiveLinks = 0;
|
||||
if (isSelf && m_inst) {
|
||||
if (m_inst->connections) {
|
||||
for (struct ll_entry* e = m_inst->connections->head; e; e = e->next) {
|
||||
struct conn_queue_entry* ce = (struct conn_queue_entry*)e->data;
|
||||
if (ce && ce->conn && ce->conn->initialized) {
|
||||
for (struct ETCP_LINK* lk = ce->conn->links; lk; lk = lk->next) {
|
||||
if (lk->is_tcp) { ownTcpActiveLinks++; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_inst->tcp_connections) {
|
||||
for (struct ll_entry* e = m_inst->tcp_connections->head; e; e = e->next) {
|
||||
struct tcp_conn_entry* te = (struct tcp_conn_entry*)e->data;
|
||||
if (te && te->etcp_conn && te->etcp_conn->initialized) ownTcpActiveLinks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& a : m_detailAddrs) {
|
||||
QString proto;
|
||||
switch (a.protocol) { case 1: proto = "UDP"; break; case 2: proto = "TCP"; break; default: proto = "UDP/TCP"; break; }
|
||||
@@ -231,6 +258,7 @@ void AccountList::updateDetailDisplay() {
|
||||
}
|
||||
if (lfm == a.family && lpo == (uint16_t)a.port && lip == addrStr(a.addr.constData(), a.family)) {
|
||||
linkColor = (lk->link_state == 3 && lk->link_status == 1) ? "#4CAF50" : "#E53935";
|
||||
matchedLinks.insert(lk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -243,8 +271,51 @@ void AccountList::updateDetailDisplay() {
|
||||
}
|
||||
}
|
||||
}
|
||||
lines.append(QString("<span style='color:%1;'>●</span> %2:%3:%4")
|
||||
.arg(linkColor, proto, addrStr(a.addr.constData(), a.family)).arg(a.port));
|
||||
|
||||
QString prefix;
|
||||
if (isSelf && m_inst) {
|
||||
int linkCount = 0;
|
||||
if (a.protocol == 1) {
|
||||
for (struct ETCP_SOCKET* sock = m_inst->etcp_sockets; sock; sock = sock->next) {
|
||||
uint16_t sp = 0;
|
||||
const struct sockaddr_storage* addr = sock->interface_addr.ss_family ? &sock->interface_addr : &sock->local_addr;
|
||||
if (addr->ss_family == AF_INET) sp = ntohs(((const struct sockaddr_in*)addr)->sin_port);
|
||||
else if (addr->ss_family == AF_INET6) sp = ntohs(((const struct sockaddr_in6*)addr)->sin6_port);
|
||||
if (sp == (uint16_t)a.port) {
|
||||
linkCount = sock->links_queue ? queue_entry_count(sock->links_queue) : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (a.protocol == 2) {
|
||||
linkCount = ownTcpActiveLinks;
|
||||
}
|
||||
if (linkCount > 0) prefix = QString("[%1] ").arg(linkCount);
|
||||
}
|
||||
|
||||
lines.append(QString("%1<span style='color:%2;'>●</span> %3:%4:%5")
|
||||
.arg(prefix, linkColor, proto, addrStr(a.addr.constData(), a.family)).arg(a.port));
|
||||
}
|
||||
|
||||
/* Show ETCP links that are not in DB (non-self) */
|
||||
if (conn) {
|
||||
for (struct ETCP_LINK* lk = conn->links; lk; lk = lk->next) {
|
||||
if (matchedLinks.contains(lk)) continue;
|
||||
const struct sockaddr_storage* sa = &lk->remote_addr;
|
||||
char ipbuf[INET6_ADDRSTRLEN]; QString lip; uint16_t lpo = 0;
|
||||
if (sa->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)sa;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, ipbuf, sizeof(ipbuf));
|
||||
lpo = ntohs(sin->sin_port); lip = QString::fromLocal8Bit(ipbuf);
|
||||
} else if (sa->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)sa;
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, ipbuf, sizeof(ipbuf));
|
||||
lpo = ntohs(sin6->sin6_port); lip = QString::fromLocal8Bit(ipbuf);
|
||||
} else { continue; }
|
||||
QString proto = lk->is_tcp ? "TCP" : "UDP";
|
||||
QString lc = (lk->link_state == 3 && lk->link_status == 1) ? "#4CAF50" : "#E53935";
|
||||
lines.append(QString("<span style='color:%1;'>●</span> %2:%3:%4 [link]")
|
||||
.arg(lc, proto, lip).arg(lpo));
|
||||
}
|
||||
}
|
||||
|
||||
m_detailText->setHtml(lines.join("<br>"));
|
||||
|
||||
Reference in new issue
Block a user