conn: сопоставление сокетов по ролям (direct/nat/local) + hairpin; NTP-детект оффлайна

- sock_match: единая классификация сокетов (DIRECT/NAT/LOCAL) и адресов (PUB/PRIV/UNREACH)
- eim приравнен к direct; на приватный адрес — только с приватного интерфейса;
  оба EIM за одним NAT (одинаковый публичный IP) — только через LAN
- topo_node: LOCAL-сокеты рекламируются (INTERFACE), private скрыт,
  NAT-адрес не рекламируется для strict и при оффлайне
- ntp: флаг reachable по циклам + пере-анонс nodeinfo при смене доступности
- cm_direct_add_links / ncd_create_links / conn_match_candidate_sockets на sock_match
- test_sock_match: unit-тесты классификации и сопоставления
This commit is contained in:
evgeny committed 2026-09-13 16:48:00 +03:00
1 parent ff53c735dd
commit ddfffad1ed
13 files changed
+349 -107

No files matched your search

+6 -5
View File
@@ -930,7 +930,7 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
struct ETCP_SOCKET* e_sock = instance->etcp_sockets;
while (e_sock) {
if (e_sock->is_tcp) { e_sock = e_sock->next; continue; }
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL) { e_sock = e_sock->next; continue; }
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE) { e_sock = e_sock->next; continue; } /* private скрыт, LOCAL рекламируем (LAN) */
if (e_sock->local_addr.ss_family == AF_INET) {
{ struct TOPO_SOCKMETA4* sm = memory_pool_alloc(instance->topo_groups->v4_sock_meta_pool);
sm->id = e_sock->sock_id; sm->config_type = e_sock->type; sm->nat_type = e_sock->nat_type;
@@ -947,9 +947,10 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id;
a->protocol = TOPO_PROTO_UDP;
a->next = v4_head; v4_head = a; }
/* адрес ПОСЛЕ NAT — дополнительно, если NAT определён (EIM).
DIRECT (nat==интерфейс) и STRICT не рекламируем отдельным адресом. */
if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0
/* адрес ПОСЛЕ NAT — дополнительно, если NAT определён (EIM) и есть интернет.
DIRECT (nat==интерфейс), STRICT и оффлайн не рекламируем отдельным адресом. */
if (instance->ntp.reachable
&& e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0
&& e_sock->nat_type != NAT_VERIFIED_STRICT
&& e_sock->nat_type != NAT_VERIFIED_DIRECT) {
struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
@@ -972,7 +973,7 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
}
{ struct ETCP_SOCKET* ts = instance->etcp_sockets;
while (ts) { if (!ts->is_tcp) { ts = ts->next; continue; }
if (ts->type == CFG_SERVER_TYPE_PRIVATE || ts->type == CFG_SERVER_TYPE_LOCAL) { ts = ts->next; continue; }
if (ts->type == CFG_SERVER_TYPE_PRIVATE) { ts = ts->next; continue; } /* private скрыт, LOCAL рекламируем (LAN) */
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) {