nodeinfo: 2 адреса на сокет (до/после NAT) + типы адресов local/public/nat/nat_eim/nat_strict
- topo_node: сокет рекламирует INTERFACE (до NAT) + NAT (после NAT, EIM); strict/direct отдельным адресом не передаются - topo_node_sqlite: addr_type_classify различает NAT_VERIFIED_*; добавлен ADDR_TYPE_NAT (тип неизвестен), fallback больше не даёт DIRECT по IP - chat_member: бейдж NAT-типа по приоритету (public>nat_eim>nat>nat_strict>local) вместо MIN(addr_type) - GUI (desktop+android): адреса мембера с socket_id и ролью (local/public/nat/nat_eim/nat_strict)
This commit is contained in:
1 parent
a823898379
commit
7bba39ddcb
14 files changed
+82
-39
No files matched your search
+14
-4
@@ -170,8 +170,13 @@ int chat_core_get_member_list(const char* ch_id, uint8_t** out, int* count) {
|
||||
}
|
||||
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT node_id, MIN(rtt), MIN(addr_type) FROM node_addresses"
|
||||
" WHERE node_id IN (%s) AND rtt > 0 GROUP BY node_id", id_list);
|
||||
"SELECT node_id, MIN(rtt),"
|
||||
" CASE WHEN MAX(addr_type=1) THEN 1"
|
||||
" WHEN MAX(addr_type=2) THEN 2"
|
||||
" WHEN MAX(addr_type=4) THEN 4"
|
||||
" WHEN MAX(addr_type=3) THEN 3"
|
||||
" ELSE 0 END"
|
||||
" FROM node_addresses WHERE node_id IN (%s) AND rtt > 0 GROUP BY node_id", id_list);
|
||||
u_free(id_list);
|
||||
|
||||
if (sqlite3_prepare_v2(g_cc.db, sql, -1, &st, NULL) == SQLITE_OK) {
|
||||
@@ -262,8 +267,13 @@ int chat_core_get_single_member(const char* ch_id, uint64_t node_id, uint8_t* ou
|
||||
|
||||
/* RTT / NAT */
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT MIN(rtt), MIN(addr_type) FROM node_addresses"
|
||||
" WHERE node_id=? AND rtt > 0");
|
||||
"SELECT MIN(rtt),"
|
||||
" CASE WHEN MAX(addr_type=1) THEN 1"
|
||||
" WHEN MAX(addr_type=2) THEN 2"
|
||||
" WHEN MAX(addr_type=4) THEN 4"
|
||||
" WHEN MAX(addr_type=3) THEN 3"
|
||||
" ELSE 0 END"
|
||||
" FROM node_addresses WHERE node_id=? AND rtt > 0");
|
||||
if (sqlite3_prepare_v2(g_cc.db, sql, -1, &st, NULL) == SQLITE_OK) {
|
||||
sqlite3_bind_int64(st, 1, (sqlite3_int64)node_id);
|
||||
if (sqlite3_step(st) == SQLITE_ROW) {
|
||||
|
||||
@@ -193,7 +193,12 @@ void cm_candidate_ping_timer_cb(void* arg) {
|
||||
if (cm_has_active_conn(mgr->group, nid)) {
|
||||
struct ETCP_CONN* dc = topo_group_find_conn_for_node(mgr->group, nid);
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(mgr->instance->topo_groups, nq->node_id);
|
||||
if (ni && dc) etcp_send_ping(mgr->instance, ni->public_key, &dc->links->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_bg_ping_noop_cb, NULL, NULL, 0);
|
||||
if (ni && dc && dc->links) {
|
||||
if (dc->links->is_tcp)
|
||||
etcp_send_tcp_ping(mgr->instance, ni->public_key, &dc->links->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_bg_ping_noop_cb, NULL);
|
||||
else
|
||||
etcp_send_ping(mgr->instance, ni->public_key, &dc->links->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_bg_ping_noop_cb, NULL, NULL, 0);
|
||||
}
|
||||
} else route_connectivity_probe_node(mgr->instance, mgr->group, nq);
|
||||
}
|
||||
mgr->candidate_ping_timer = uasync_set_timeout(mgr->instance->ua, CONN_MGR_CANDIDATE_PING_TB, mgr, cm_candidate_ping_timer_cb, "conn_mgr_cand_ping");
|
||||
|
||||
@@ -938,19 +938,26 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
struct sockaddr_in* local_sin = (struct sockaddr_in*)&e_sock->local_addr;
|
||||
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr;
|
||||
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr;
|
||||
int nat_verified = (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT);
|
||||
/* адрес ДО NAT (локальный/интерфейсный) — рекламируем всегда */
|
||||
int use_local = (local_sin->sin_addr.s_addr != 0);
|
||||
uint32_t pre_ip = use_local ? local_sin->sin_addr.s_addr : if_sin->sin_addr.s_addr;
|
||||
uint16_t pre_port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
|
||||
{ struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
|
||||
if (nat_verified) {
|
||||
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
|
||||
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id;
|
||||
} else {
|
||||
int use_local = (local_sin->sin_addr.s_addr != 0);
|
||||
memcpy(a->addr, use_local ? &local_sin->sin_addr.s_addr : &if_sin->sin_addr.s_addr, 4);
|
||||
a->port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
|
||||
a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id;
|
||||
}
|
||||
memcpy(a->addr, &pre_ip, 4); a->port = pre_port;
|
||||
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
|
||||
&& 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);
|
||||
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
|
||||
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id;
|
||||
a->protocol = TOPO_PROTO_UDP;
|
||||
a->next = v4_head; v4_head = a;
|
||||
}
|
||||
} else if (e_sock->local_addr.ss_family == AF_INET6) {
|
||||
{ struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(instance->topo_groups->v6_sock_meta_pool);
|
||||
sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->nat_type = e_sock->nat_type;
|
||||
|
||||
@@ -49,6 +49,7 @@ struct UTUN_INSTANCE;
|
||||
#define ADDR_TYPE_DIRECT 1
|
||||
#define ADDR_TYPE_NAT_EIM 2
|
||||
#define ADDR_TYPE_NAT_STRICT 3
|
||||
#define ADDR_TYPE_NAT 4 /* за NAT, тип неизвестен */
|
||||
|
||||
#define PROBE_STATUS_NONE 0
|
||||
#define PROBE_STATUS_IN_PROGRESS 1
|
||||
|
||||
@@ -62,13 +62,16 @@ static int addr_type_from_ip(int family, const uint8_t* addr) {
|
||||
}
|
||||
|
||||
/* Итоговая классификация: конфиг + автоопределение + IP (всё локально). */
|
||||
static int addr_type_classify(int config_type, int nat_type, int family, const uint8_t* ip) {
|
||||
static int addr_type_classify(int config_type, int nat_type) {
|
||||
if (config_type == CFG_SERVER_TYPE_PUBLIC) return ADDR_TYPE_DIRECT;
|
||||
if (config_type == CFG_SERVER_TYPE_PRIVATE || config_type == CFG_SERVER_TYPE_LOCAL) return ADDR_TYPE_NETIF;
|
||||
if (nat_type == NAT_TYPE_EIM) return ADDR_TYPE_NAT_EIM;
|
||||
if (nat_type == NAT_TYPE_STRICT) return ADDR_TYPE_NAT_STRICT;
|
||||
if (nat_type == NAT_TYPE_DIRECT) return ADDR_TYPE_DIRECT;
|
||||
return addr_type_from_ip(family, ip);
|
||||
if (nat_type == NAT_VERIFIED_EIM) return ADDR_TYPE_NAT_EIM;
|
||||
if (nat_type == NAT_VERIFIED_STRICT) return ADDR_TYPE_NAT_STRICT;
|
||||
if (nat_type == NAT_VERIFIED_DIRECT) return ADDR_TYPE_DIRECT;
|
||||
return ADDR_TYPE_NAT; /* за NAT, тип неизвестен */
|
||||
}
|
||||
|
||||
static void smeta4_lookup(struct TOPO_SOCKMETA4* head, uint8_t sid, uint8_t* cfg, uint8_t* nat) {
|
||||
@@ -115,8 +118,8 @@ int topo_node_sqlite_addrs_put(sqlite3* db, uint64_t node_id, struct TOPO_NODE*
|
||||
int written = 0;
|
||||
for (const struct TOPO_ADDR4* a = ni->v4_addrs; a; a = a->next) {
|
||||
uint8_t cfg, nat; smeta4_lookup(ni->v4_sock_meta, a->socket_id, &cfg, &nat);
|
||||
int at = (a->type == TOPO_ADDR_INTERFACE) ? ADDR_TYPE_NETIF
|
||||
: addr_type_classify(cfg, nat, 4, a->addr);
|
||||
int at = (a->type == TOPO_ADDR_INTERFACE) ? addr_type_from_ip(4, a->addr)
|
||||
: addr_type_classify(cfg, nat);
|
||||
sqlite3_bind_int64(is, 1, (sqlite3_int64)node_id);
|
||||
sqlite3_bind_int(is, 2, 4);
|
||||
sqlite3_bind_int(is, 3, (int)a->protocol);
|
||||
@@ -136,7 +139,7 @@ int topo_node_sqlite_addrs_put(sqlite3* db, uint64_t node_id, struct TOPO_NODE*
|
||||
for (const struct TOPO_ADDR6* a = ni->v6_addrs; a; a = a->next) {
|
||||
uint8_t cfg, nat; smeta6_lookup(ni->v6_sock_meta, a->socket_id, &cfg, &nat);
|
||||
int at = (a->type == TOPO_ADDR_INTERFACE) ? ADDR_TYPE_NETIF
|
||||
: addr_type_classify(cfg, nat, 6, a->addr);
|
||||
: addr_type_classify(cfg, nat);
|
||||
sqlite3_bind_int64(is, 1, (sqlite3_int64)node_id);
|
||||
sqlite3_bind_int(is, 2, 6);
|
||||
sqlite3_bind_int(is, 3, (int)a->protocol);
|
||||
@@ -747,7 +750,7 @@ int topo_node_sqlite_nodeinfo_updated(sqlite3* db, uint64_t node_id) {
|
||||
}
|
||||
}
|
||||
|
||||
static const int at2type[] = { [ADDR_TYPE_NETIF]=1, [ADDR_TYPE_DIRECT]=1, [ADDR_TYPE_NAT_EIM]=2, [ADDR_TYPE_NAT_STRICT]=1 };
|
||||
static const int at2type[] = { [ADDR_TYPE_NETIF]=1, [ADDR_TYPE_DIRECT]=1, [ADDR_TYPE_NAT_EIM]=2, [ADDR_TYPE_NAT_STRICT]=1, [ADDR_TYPE_NAT]=2 };
|
||||
int base_type = (best_at < 0) ? 0 : at2type[best_at];
|
||||
|
||||
sqlite3_stmt* s = NULL;
|
||||
|
||||
@@ -1470,9 +1470,9 @@ int etcp_send_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bi
|
||||
return -1;
|
||||
}
|
||||
struct ETCP_SOCKET* e_sock = instance->etcp_sockets;
|
||||
while (e_sock && e_sock->local_addr.ss_family != addr->ss_family) e_sock = e_sock->next;
|
||||
while (e_sock && (e_sock->is_tcp || e_sock->local_addr.ss_family != addr->ss_family)) e_sock = e_sock->next;
|
||||
if (!e_sock) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "no socket for addr_family=%d", addr->ss_family);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "no UDP socket for addr_family=%d", addr->ss_family);
|
||||
return -2;
|
||||
}
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "ping N1 [%s]", sockaddr_storage_to_str(addr).str);
|
||||
|
||||
Reference in new issue
Block a user