refactor: split socket meta 'type' into config_type and nat_type — separate config (PUBLIC/NAT/PRIVATE) from detected NAT (EIM/STRICT/DIRECT) across NODEINFO, conn_mgr, route_bgp, route_node, etcpmon; win32 compat fixes (memmem, SHUT_WR, tun test_mode, tcp_proxy guards)
This commit is contained in:
1 parent
487cb8718e
commit
389ef00da6
15 files changed
+102
-43
No files matched your search
+10
-12
@@ -31,7 +31,7 @@ static void cm_start_local_scan(struct CONN_MGR_ENTRY* entry);
|
||||
static void cm_idle_timer_cb(void* arg);
|
||||
static void cm_deliver_result(struct CONN_MGR_ENTRY* entry, int result);
|
||||
static void cm_bg_ping_timer_cb(void* arg);
|
||||
static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_meta_type);
|
||||
static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_config_type, uint8_t target_nat_type);
|
||||
static uint16_t cm_get_node_min_rtt(struct NODEINFO_Q* nq);
|
||||
static int cm_has_direct_ip(struct NODEINFO_Q* nq);
|
||||
static int cm_has_local_addr(struct NODEINFO_Q* nq);
|
||||
@@ -333,14 +333,12 @@ static void cm_idle_timer_cb(void* arg) {
|
||||
entry->idle_timer = uasync_set_timeout(mgr->instance->ua, CONN_MGR_IDLE_CHECK_INTERVAL_TB, entry, cm_idle_timer_cb, "conn_mgr_idle");
|
||||
}
|
||||
|
||||
static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_meta_type) {
|
||||
uint8_t tt = target_meta_type;
|
||||
if (tt == NAT_VERIFIED_DIRECT) tt = CFG_SERVER_TYPE_PUBLIC;
|
||||
else if (tt >= NAT_VERIFIED_UNKNOWN) tt = CFG_SERVER_TYPE_PUBLIC;
|
||||
static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_config_type, uint8_t target_nat_type) {
|
||||
uint8_t tt = target_nat_type >= NAT_VERIFIED_UNKNOWN ? CFG_SERVER_TYPE_PUBLIC : target_config_type;
|
||||
uint8_t ot = our->type;
|
||||
if (ot == CFG_SERVER_TYPE_PUBLIC) return 1;
|
||||
if (ot == CFG_SERVER_TYPE_NAT && our->nat_type == NAT_TYPE_EIM && tt == CFG_SERVER_TYPE_PUBLIC) return 1;
|
||||
if (ot == CFG_SERVER_TYPE_NAT && our->nat_type == NAT_TYPE_EIM && tt == CFG_SERVER_TYPE_NAT) return 1;
|
||||
if (ot == CFG_SERVER_TYPE_NAT && our->nat_type == NAT_VERIFIED_EIM && tt == CFG_SERVER_TYPE_PUBLIC) return 1;
|
||||
if (ot == CFG_SERVER_TYPE_NAT && our->nat_type == NAT_VERIFIED_EIM && tt == CFG_SERVER_TYPE_NAT) return 1;
|
||||
if (ot == CFG_SERVER_TYPE_PRIVATE && tt == CFG_SERVER_TYPE_PRIVATE) return 2;
|
||||
return 0;
|
||||
}
|
||||
@@ -378,7 +376,7 @@ static int cm_has_direct_ip(struct NODEINFO_Q* nq) {
|
||||
if (addrs[i].type == ADDR_TYPE_REAL || addrs[i].type == ADDR_TYPE_NAT) {
|
||||
for (int j = 0; j < meta_count; j++) {
|
||||
if (metas[j].id == addrs[i].socket_id &&
|
||||
(metas[j].type == CFG_SERVER_TYPE_PUBLIC || metas[j].type == NAT_VERIFIED_EIM || metas[j].type == NAT_VERIFIED_DIRECT))
|
||||
(metas[j].config_type == CFG_SERVER_TYPE_PUBLIC || metas[j].nat_type == NAT_VERIFIED_EIM || metas[j].nat_type == NAT_VERIFIED_DIRECT))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -395,7 +393,7 @@ static int cm_has_local_addr(struct NODEINFO_Q* nq) {
|
||||
for (int i = 0; i < addr_count; i++) {
|
||||
if (addrs[i].type == ADDR_TYPE_INTERFACE) {
|
||||
for (int j = 0; j < meta_count; j++) {
|
||||
if (metas[j].id == addrs[i].socket_id && metas[j].type == CFG_SERVER_TYPE_PRIVATE)
|
||||
if (metas[j].id == addrs[i].socket_id && metas[j].config_type == CFG_SERVER_TYPE_PRIVATE)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -426,7 +424,7 @@ static void cm_start_local_scan(struct CONN_MGR_ENTRY* entry) {
|
||||
for (int i = 0; i < addr_count; i++) {
|
||||
if (addrs[i].type != ADDR_TYPE_INTERFACE) continue;
|
||||
for (int j = 0; j < meta_count; j++) {
|
||||
if (metas[j].id != addrs[i].socket_id || metas[j].type != CFG_SERVER_TYPE_PRIVATE) continue;
|
||||
if (metas[j].id != addrs[i].socket_id || metas[j].config_type != CFG_SERVER_TYPE_PRIVATE) continue;
|
||||
struct ETCP_SOCKET* s = entry->mgr->instance->etcp_sockets;
|
||||
while (s) {
|
||||
if (s->type == CFG_SERVER_TYPE_PRIVATE && s->local_addr.ss_family == AF_INET) {
|
||||
@@ -475,7 +473,7 @@ static void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry) {
|
||||
if (metas[j].id != addrs[i].socket_id) continue;
|
||||
struct ETCP_SOCKET* s = entry->mgr->instance->etcp_sockets;
|
||||
while (s) {
|
||||
int compat = cm_nat_compatible(s, metas[j].type);
|
||||
int compat = cm_nat_compatible(s, metas[j].config_type, metas[j].nat_type);
|
||||
if (compat && s->local_addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in sin;
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
@@ -591,7 +589,7 @@ static void cm_start_phase_reverse(struct CONN_MGR_ENTRY* entry) {
|
||||
if (addrs[i].type != ADDR_TYPE_REAL && addrs[i].type != ADDR_TYPE_NAT) continue;
|
||||
for (int j = 0; j < meta_count; j++) {
|
||||
if (metas[j].id == addrs[i].socket_id &&
|
||||
(metas[j].type == CFG_SERVER_TYPE_PUBLIC || metas[j].type == NAT_VERIFIED_EIM || metas[j].type == NAT_VERIFIED_DIRECT)) {
|
||||
(metas[j].config_type == CFG_SERVER_TYPE_PUBLIC || metas[j].nat_type == NAT_VERIFIED_EIM || metas[j].nat_type == NAT_VERIFIED_DIRECT)) {
|
||||
out_addrs[direct_count].type = addrs[i].type;
|
||||
memcpy(out_addrs[direct_count].ip, addrs[i].addr, 4);
|
||||
out_addrs[direct_count].port = htons(addrs[i].port);
|
||||
|
||||
@@ -985,6 +985,7 @@ static void send_socket_list(struct control_server* server, struct control_clien
|
||||
info[i].ip[sizeof(info[i].ip) - 1] = '\0';
|
||||
info[i].port = 0;
|
||||
}
|
||||
info[i].config_type = sock->type;
|
||||
info[i].nat_type = sock->nat_type;
|
||||
|
||||
/* NAT address from socket (set when INIT_RESPONSE received) */
|
||||
|
||||
@@ -699,7 +699,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
|
||||
e_sock->pkt_format_errors = 0;
|
||||
e_sock->type = type;
|
||||
e_sock->sock_id = instance->next_socket_id++;
|
||||
e_sock->nat_type = type; // initial type from config, updated after NAT detection
|
||||
e_sock->nat_type = NAT_TYPE_UNKNOWN; // только результат детекции NAT, серверные сокеты стартуют с unknown
|
||||
e_sock->mtu = mtu;
|
||||
e_sock->only_local = only_local;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Add Socket type=%d", type);
|
||||
|
||||
+2
-2
@@ -1023,8 +1023,8 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f
|
||||
int data_changed = 0;
|
||||
for (int i = 0; i < bgp->local_node->node.local_v4_sockets; i++) {
|
||||
if (meta[i].id == socket_id) {
|
||||
if (meta[i].type != verified_type) {
|
||||
meta[i].type = verified_type;
|
||||
if (meta[i].nat_type != verified_type) {
|
||||
meta[i].nat_type = verified_type;
|
||||
data_changed = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
+8
-6
@@ -173,7 +173,7 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
|
||||
const struct NODEINFO_IPV4_SOCKET_META* v4sm;
|
||||
int v4sm_cnt = get_node_v4_sockets_meta(nq, &v4sm);
|
||||
if (v4sm_cnt > 0) for (int i = 0; i < v4sm_cnt; i++) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sock[%d]: id=%u type=%u", i, v4sm[i].id, v4sm[i].type);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sock[%d]: id=%u config=%u nat=%u", i, v4sm[i].id, v4sm[i].config_type, v4sm[i].nat_type);
|
||||
}
|
||||
|
||||
const struct NODEINFO_IPV4_ADDR* v4a;
|
||||
@@ -190,7 +190,7 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
|
||||
const struct NODEINFO_IPV6_SOCKET_META* v6sm;
|
||||
int v6sm_cnt = get_node_v6_sockets_meta(nq, &v6sm);
|
||||
if (v6sm_cnt > 0) for (int i = 0; i < v6sm_cnt; i++) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sock[%d]: id=%u type=%u", i, v6sm[i].id, v6sm[i].type);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sock[%d]: id=%u config=%u nat=%u", i, v6sm[i].id, v6sm[i].config_type, v6sm[i].nat_type);
|
||||
}
|
||||
|
||||
const struct NODEINFO_IPV6_ADDR* v6a;
|
||||
@@ -321,7 +321,7 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
|
||||
const struct NODEINFO_IPV4_SOCKET_META* v4sm;
|
||||
int v4sm_cnt = get_node_v4_sockets_meta(nq, &v4sm);
|
||||
for (int i = 0; i < v4sm_cnt; i++)
|
||||
FMT_ADD(" v4sock[%d]: id=%u type=%u\n", i, v4sm[i].id, v4sm[i].type);
|
||||
FMT_ADD(" v4sock[%d]: id=%u config=%u nat=%u\n", i, v4sm[i].id, v4sm[i].config_type, v4sm[i].nat_type);
|
||||
|
||||
const struct NODEINFO_IPV4_ADDR* v4a;
|
||||
int v4a_cnt = get_node_v4_addrs(nq, &v4a);
|
||||
@@ -336,7 +336,7 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
|
||||
const struct NODEINFO_IPV6_SOCKET_META* v6sm;
|
||||
int v6sm_cnt = get_node_v6_sockets_meta(nq, &v6sm);
|
||||
for (int i = 0; i < v6sm_cnt; i++)
|
||||
FMT_ADD(" v6sock[%d]: id=%u type=%u\n", i, v6sm[i].id, v6sm[i].type);
|
||||
FMT_ADD(" v6sock[%d]: id=%u config=%u nat=%u\n", i, v6sm[i].id, v6sm[i].config_type, v6sm[i].nat_type);
|
||||
|
||||
const struct NODEINFO_IPV6_ADDR* v6a;
|
||||
int v6a_cnt = get_node_v6_addrs(nq, &v6a);
|
||||
@@ -518,7 +518,8 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
|
||||
while (e_sock) {
|
||||
if (e_sock->local_addr.ss_family == AF_INET) {
|
||||
meta[midx].id = e_sock->sock_id;
|
||||
meta[midx].type = e_sock->nat_type;
|
||||
meta[midx].config_type = e_sock->type;
|
||||
meta[midx].nat_type = e_sock->nat_type;
|
||||
midx++;
|
||||
}
|
||||
e_sock = e_sock->next;
|
||||
@@ -569,7 +570,8 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
|
||||
while (e_sock) {
|
||||
if (e_sock->local_addr.ss_family == AF_INET6) {
|
||||
meta6[m6idx].id = e_sock->sock_id;
|
||||
meta6[m6idx].type = e_sock->nat_type;
|
||||
meta6[m6idx].config_type = e_sock->type;
|
||||
meta6[m6idx].nat_type = e_sock->nat_type;
|
||||
m6idx++;
|
||||
}
|
||||
e_sock = e_sock->next;
|
||||
|
||||
+4
-2
@@ -91,7 +91,8 @@ struct NODEINFO {
|
||||
// метаданные одного сокета
|
||||
struct NODEINFO_IPV4_SOCKET_META {
|
||||
uint8_t id; // unique socket id (0-255)
|
||||
uint8_t type; // CFG_SERVER_TYPE_*/NAT_VERIFIED_*
|
||||
uint8_t config_type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE
|
||||
uint8_t nat_type; // NAT_TYPE_* / NAT_VERIFIED_*
|
||||
} __attribute__((packed));
|
||||
|
||||
// одна типизированная адресная запись (плоский список)
|
||||
@@ -104,7 +105,8 @@ struct NODEINFO_IPV4_ADDR {
|
||||
|
||||
struct NODEINFO_IPV6_SOCKET_META {
|
||||
uint8_t id; // unique socket id (0-255)
|
||||
uint8_t type; // CFG_SERVER_TYPE_*/NAT_VERIFIED_*
|
||||
uint8_t config_type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE
|
||||
uint8_t nat_type; // NAT_TYPE_* / NAT_VERIFIED_*
|
||||
} __attribute__((packed));
|
||||
|
||||
struct NODEINFO_IPV6_ADDR {
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include "../lib/mem.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -151,6 +153,7 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
|
||||
}
|
||||
} else {
|
||||
if (tun->ifname[0] == '\0') strncpy(tun->ifname, "tun_test", sizeof(tun->ifname)-1);
|
||||
#ifndef _WIN32
|
||||
int fds[2];
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "TUN %s test_mode socketpair failed: %s", tun->ifname, strerror(errno));
|
||||
@@ -159,6 +162,11 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
|
||||
}
|
||||
tun->fd = fds[0];
|
||||
tun->test_fd = fds[1];
|
||||
#else
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "TUN test_mode not supported on Windows");
|
||||
u_free(tun);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
tun->pool = memory_pool_init(sizeof(struct ll_entry), "tun_pool");
|
||||
@@ -244,6 +252,7 @@ struct tun_if* tun_init_nat(struct UASYNC* ua, const char* ifname, const char* i
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
#ifndef _WIN32
|
||||
int fds[2];
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "NAT TUN %s test_mode socketpair failed: %s", tun->ifname, strerror(errno));
|
||||
@@ -252,6 +261,11 @@ struct tun_if* tun_init_nat(struct UASYNC* ua, const char* ifname, const char* i
|
||||
}
|
||||
tun->fd = fds[0];
|
||||
tun->test_fd = fds[1];
|
||||
#else
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "NAT TUN test_mode not supported on Windows");
|
||||
u_free(tun);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
tun->pool = memory_pool_init(sizeof(struct ll_entry), "tun_pool");
|
||||
|
||||
@@ -156,11 +156,14 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
|
||||
|
||||
// TCP proxy server (exit node, optional) — must be before tcp_proxy_client so
|
||||
// tcp_proxy_client_create can overwrite the handler if it has remote mappings
|
||||
#ifndef _WIN32
|
||||
if (tcp_proxy_server_init(instance) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "Failed to initialize tcp_proxy_server (non-fatal)");
|
||||
}
|
||||
#endif
|
||||
|
||||
// TCP proxy client (from [tcp_proxy] config section)
|
||||
#ifndef _WIN32
|
||||
if (config->global.tcp_proxy_client_enabled || config->global.tcp_proxy_client_socks_enabled || config->global.tcp_proxy_client_http_proxy_enabled) {
|
||||
const char* tun_name = config->global.tcp_proxy_client_tun_name;
|
||||
const char* tun_ip = config->global.tcp_proxy_client_tun_ip;
|
||||
@@ -183,6 +186,7 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
|
||||
} else {
|
||||
instance->tcp_proxy_client = NULL;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -362,6 +366,7 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
|
||||
}
|
||||
|
||||
// Cleanup TCP proxy client module
|
||||
#ifndef _WIN32
|
||||
if (instance->tcp_proxy_client) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Destroying TCP proxy client module");
|
||||
tcp_proxy_client_destroy(instance->tcp_proxy_client);
|
||||
@@ -370,6 +375,7 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
|
||||
|
||||
// Cleanup TCP proxy server
|
||||
tcp_proxy_server_destroy(instance);
|
||||
#endif
|
||||
|
||||
// Cleanup routing module (unbinds from etcp_router before etcp_router_destroy)
|
||||
routing_destroy(instance);
|
||||
|
||||
Reference in new issue
Block a user