Measure owned endpoint mapping and inbound reachability separately

This commit is contained in:
evgeny committed 2026-10-12 00:01:40 +02:00
1 parent b54307a0df
commit ff69552a61
51 files changed
+2620 -2483

No files matched your search

+8 -6
View File
@@ -214,19 +214,20 @@ int chat_core_get_member_list(struct UTUN_INSTANCE* inst, const char* ch_id, uin
}
snprintf(sql, sizeof(sql),
"SELECT node_id, MIN(rtt),"
"SELECT node_id, MIN(CASE WHEN rtt > 0 THEN rtt END),"
" CASE WHEN MAX(addr_type=1) THEN 1"
" WHEN MAX(addr_type=5) THEN 5"
" 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);
" FROM node_addresses WHERE node_id IN (%s) GROUP BY node_id", id_list);
u_free(id_list);
if (sqlite3_prepare_v2(cc->db, sql, -1, &st, NULL) == SQLITE_OK) {
while (sqlite3_step(st) == SQLITE_ROW) {
uint64_t nid = (uint64_t)sqlite3_column_int64(st, 0);
int rtt_val = sqlite3_column_int(st, 1);
int rtt_val = sqlite3_column_type(st, 1) == SQLITE_NULL ? 0xFFFF : sqlite3_column_int(st, 1);
int at = sqlite3_column_int(st, 2);
for (int i = 0; i < cnt; i++) {
if (members[i].node_id == nid) {
@@ -315,17 +316,18 @@ int chat_core_get_single_member(struct UTUN_INSTANCE* inst, const char* ch_id, u
/* RTT / NAT */
snprintf(sql, sizeof(sql),
"SELECT MIN(rtt),"
"SELECT MIN(CASE WHEN rtt > 0 THEN rtt END),"
" CASE WHEN MAX(addr_type=1) THEN 1"
" WHEN MAX(addr_type=5) THEN 5"
" 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");
" FROM node_addresses WHERE node_id=?");
if (sqlite3_prepare_v2(cc->db, sql, -1, &st, NULL) == SQLITE_OK) {
sqlite3_bind_int64(st, 1, (sqlite3_int64)node_id);
if (sqlite3_step(st) == SQLITE_ROW) {
int rtt_val = sqlite3_column_int(st, 0);
int rtt_val = sqlite3_column_type(st, 0) == SQLITE_NULL ? 0xFFFF : sqlite3_column_int(st, 0);
m.rtt = (uint16_t)(rtt_val > 0xFFFF ? 0xFFFF : rtt_val);
m.nat_type = (uint8_t)sqlite3_column_int(st, 1);
}
+34 -4
View File
@@ -20,8 +20,38 @@
#include "../routing_layer/topo_group.h"
#include <string.h>
static const char* nat_type_str(uint8_t t) {
switch (t) { case 0: return "UNKNOWN"; case 1: return "EIM"; case 2: return "STRICT"; case 3: return "DIRECT"; default: return "?"; }
struct address_profile_text { char text[80]; };
static struct address_profile_text link_address_profile_text(const struct ETCP_LINK *link) {
static const struct address_profile unknown = {0};
const struct address_profile *profile = &unknown;
const struct TOPO_NODE *peer = topo_node_registry_find(link->etcp->instance->topo_groups, link->etcp->peer_node_id);
uint8_t socket_id = link->remote_socket_id;
/* У входящего TCP source port относится к соединению, не к listener пира. */
if (link->is_tcp && link->is_server) peer = NULL;
if (peer && link->is_tcp && link->remote_addr.ss_family == AF_INET) {
const struct sockaddr_in *target = (const struct sockaddr_in *)&link->remote_addr;
const struct TOPO_ADDR4 *address = peer->v4_addrs;
while (address && (!(address->protocol & TOPO_PROTO_TCP) || address->port != ntohs(target->sin_port) ||
memcmp(address->addr, &target->sin_addr, 4))) address = address->next;
if (address) socket_id = address->socket_id; else peer = NULL;
} else if (peer && link->is_tcp && link->remote_addr.ss_family == AF_INET6) {
const struct sockaddr_in6 *target = (const struct sockaddr_in6 *)&link->remote_addr;
const struct TOPO_ADDR6 *address = peer->v6_addrs;
while (address && (!(address->protocol & TOPO_PROTO_TCP) || address->port != ntohs(target->sin6_port) ||
memcmp(address->addr, &target->sin6_addr, 16))) address = address->next;
if (address) socket_id = address->socket_id; else peer = NULL;
}
if (peer && link->remote_addr.ss_family == AF_INET) {
for (const struct TOPO_SOCKMETA4 *meta = peer->v4_sock_meta; meta; meta = meta->next)
if (meta->id == socket_id) { profile = &meta->address_profile; break; }
} else if (peer && link->remote_addr.ss_family == AF_INET6) {
for (const struct TOPO_SOCKMETA6 *meta = peer->v6_sock_meta; meta; meta = meta->next)
if (meta->id == socket_id) { profile = &meta->address_profile; break; }
}
struct address_profile_text result;
snprintf(result.text, sizeof(result.text), "%s/%s", address_mapping_name(profile->mapping), address_inbound_name(profile->inbound));
return result;
}
static void get_node_name(struct UTUN_INSTANCE* inst, uint64_t node_id, char* out, size_t sz) {
@@ -117,7 +147,7 @@ static void chat_core_collect_status(struct UTUN_INSTANCE* inst) {
link->is_tcp ? "TCP" : "UDP",
link->conn ? link->conn->name : "?",
link->link_status ? "UP" : "DOWN",
nat_type_str(link->nat_type),
link_address_profile_text(link).text,
rtt_str);
link = link->next; link_idx++;
}
@@ -282,7 +312,7 @@ static void collect_conn_metrics(struct UTUN_INSTANCE* inst, uint64_t peer_node_
"Keepalive: sent=%u recv=%u period=%ums\n"
"Inflight: %u / %u B (%u pkts)\n"
"Encrypt: sent=%zu err=%zu Decrypt: rcvd=%zu err=%zu\n",
link_idx, link->link_status ? "UP" : "DOWN", is_tcp_str, nat_type_str(link->nat_type),
link_idx, link->link_status ? "UP" : "DOWN", is_tcp_str, link_address_profile_text(link).text,
local_str, remote_str,
link->rtt_last / 10.0f, link->tt_last / 10.0f,
link->keepalive_sent_count, link->keepalive_recv_count, link->keepalive_interval,