Admit reverse-capable providers without requiring an outgoing-compatible address
This commit is contained in:
1 parent
22342b310c
commit
aa3fb9cac7
2 files changed
+43
-3
No files matched your search
@@ -361,7 +361,46 @@ int node_conn_direct_compatible(struct UTUN_INSTANCE* inst, uint64_t node_id) {
|
||||
if (conn && conn->state != 2 && !conn->close_requested && conn->links_up) return 1;
|
||||
struct TOPO_NODE* node = topo_node_registry_find(inst->topo_groups, node_id);
|
||||
if (!node) { DEBUG_DEBUG(DEBUG_CATEGORY_NCD, "[ncd] compatibility unknown snapshot node=%016llx", (unsigned long long)node_id); return 0; }
|
||||
return ncd_create_links(NULL, node, NULL, inst) > 0;
|
||||
if (ncd_create_links(NULL, node, NULL, inst) > 0) return 1;
|
||||
/* Входящее подключение тоже допустимо: REVERSE_REQ просит пира открыть наш опубликованный адрес.
|
||||
* TCP имеет собственный исходящий socket fallback; для UDP нужен известный UDP-сокет пира.
|
||||
* Это возможность попытки, не подтверждение маршрута/работоспособности скрытых сокетов пира. */
|
||||
const struct TOPO_NODE* self = topo_node_registry_find(inst->topo_groups, inst->node_id);
|
||||
if (!self) return 0;
|
||||
for (const struct TOPO_ADDR4* a = self->v4_addrs; a; a = a->next) {
|
||||
uint32_t ip; memcpy(&ip, a->addr, 4);
|
||||
if (!ip || !a->port) continue;
|
||||
const struct TOPO_SOCKMETA4* meta = self->v4_sock_meta;
|
||||
while (meta && meta->id != a->socket_id) meta = meta->next;
|
||||
uint8_t cfg = meta ? meta->config_type : CFG_SERVER_TYPE_UNKNOWN, nat = meta ? meta->nat_type : NAT_TYPE_UNKNOWN;
|
||||
if (sock_target_class(a->type, cfg, nat) != SOCK_TC_PUB) continue;
|
||||
if ((a->protocol & TOPO_PROTO_REALITY) && !topo_node_find_reality_sock(self, a->socket_id)) continue;
|
||||
if (a->protocol & TOPO_PROTO_TCP) return 1;
|
||||
if (!(a->protocol & TOPO_PROTO_UDP)) continue;
|
||||
for (const struct TOPO_ADDR4* remote = node->v4_addrs; remote; remote = remote->next) {
|
||||
if (!(remote->protocol & TOPO_PROTO_UDP)) continue;
|
||||
const struct TOPO_SOCKMETA4* rm = node->v4_sock_meta;
|
||||
while (rm && rm->id != remote->socket_id) rm = rm->next;
|
||||
struct sock_view view = {.has_inet = 1};
|
||||
view.is_eim = rm && (rm->nat_type == NAT_TYPE_EIM || rm->nat_type == NAT_VERIFIED_EIM);
|
||||
for (const struct TOPO_ADDR4* ra = node->v4_addrs; ra; ra = ra->next)
|
||||
if (ra->socket_id == remote->socket_id && ra->type == TOPO_ADDR_NAT) memcpy(&view.public_ip4, ra->addr, 4);
|
||||
if (sock_match(&view, a->type, cfg, nat, ip)) return 1;
|
||||
}
|
||||
}
|
||||
for (const struct TOPO_ADDR6* a = self->v6_addrs; a; a = a->next) {
|
||||
int nonzero = 0; for (unsigned i = 0; i < 16; i++) nonzero |= a->addr[i];
|
||||
if (!nonzero || !a->port || (a->addr[0] == 0xfe && (a->addr[1] & 0xc0) == 0x80)) continue;
|
||||
const struct TOPO_SOCKMETA6* meta = self->v6_sock_meta;
|
||||
while (meta && meta->id != a->socket_id) meta = meta->next;
|
||||
if (meta && (meta->config_type == CFG_SERVER_TYPE_PRIVATE || meta->config_type == CFG_SERVER_TYPE_LOCAL)) continue;
|
||||
if ((a->protocol & TOPO_PROTO_REALITY) && !topo_node_find_reality_sock(self, a->socket_id)) continue;
|
||||
if (a->protocol & TOPO_PROTO_TCP) return 1;
|
||||
if (!(a->protocol & TOPO_PROTO_UDP)) continue;
|
||||
for (const struct TOPO_ADDR6* remote = node->v6_addrs; remote; remote = remote->next)
|
||||
if (remote->protocol & TOPO_PROTO_UDP) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int node_conn_direct_update_node(struct UTUN_INSTANCE* inst, uint64_t node_id) {
|
||||
|
||||
@@ -44,8 +44,9 @@ struct ETCP_SOCKET;
|
||||
/* ─── Opaque handle ─── */
|
||||
struct NODE_CONN_DIRECT;
|
||||
|
||||
/* Совместимая пара адрес/сокет либо рабочий ETCP; без линков, handles, таймеров и сетевых проб.
|
||||
* Использует тот же обход, что open, включая IPv6 и TCP без слушающего сокета. Не доказывает достижимость. */
|
||||
/* Рабочий ETCP, совместимая исходящая пара либо возможность reverse на наш опубликованный адрес.
|
||||
* Без линков/handles/таймеров/проб. Исходящие пары — тот же обход, что open; reverse — sock_match/публикуемые адреса.
|
||||
* Учитывает IPv6 и исходящий TCP fallback; возможность попытки не доказывает достижимость. */
|
||||
int node_conn_direct_compatible(struct UTUN_INSTANCE* inst, uint64_t node_id);
|
||||
|
||||
/* ─── Callback events (единый callback на handle) ─── */
|
||||
|
||||
Reference in new issue
Block a user