From 7bba39ddcb404495ec4ea9df6ff4fd80e420e52f Mon Sep 17 00:00:00 2001 From: evgeny Date: Sun, 13 Sep 2026 01:05:25 +0300 Subject: [PATCH] =?UTF-8?q?nodeinfo:=202=20=D0=B0=D0=B4=D1=80=D0=B5=D1=81?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=20=D1=81=D0=BE=D0=BA=D0=B5=D1=82=20(?= =?UTF-8?q?=D0=B4=D0=BE/=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20NAT)=20+=20=D1=82?= =?UTF-8?q?=D0=B8=D0=BF=D1=8B=20=D0=B0=D0=B4=D1=80=D0=B5=D1=81=D0=BE=D0=B2?= =?UTF-8?q?=20local/public/nat/nat=5Feim/nat=5Fstrict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- src/chat/chat_member.c | 18 ++++++++++--- src/routing_layer/conn_mgr_monitor.c | 7 ++++- src/routing_layer/topo_node.c | 27 ++++++++++++------- src/routing_layer/topo_node.h | 1 + src/routing_layer/topo_node_sqlite.c | 15 ++++++----- src/transport_layer/etcp_connections.c | 4 +-- .../java/com/utun/chat/data/ChatRepository.kt | 7 ++++- .../utun/chat/ui/screens/MemberListScreen.kt | 2 +- .../jni_bridge/android_jni_bridge.c | 11 ++++---- tools/chatgui/src/accountlist.cpp | 19 +++++++++---- tools/chatgui/src/accountlist.h | 1 + tools/chatgui/src/memberlistmodel.cpp | 4 +-- tools/chatgui/src/nodespage.cpp | 2 +- tools/chatgui/transport/node_config.cpp | 3 ++- 14 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/chat/chat_member.c b/src/chat/chat_member.c index 781cb845..0b9f2b4e 100644 --- a/src/chat/chat_member.c +++ b/src/chat/chat_member.c @@ -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) { diff --git a/src/routing_layer/conn_mgr_monitor.c b/src/routing_layer/conn_mgr_monitor.c index ba4e98a7..c0577827 100644 --- a/src/routing_layer/conn_mgr_monitor.c +++ b/src/routing_layer/conn_mgr_monitor.c @@ -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"); diff --git a/src/routing_layer/topo_node.c b/src/routing_layer/topo_node.c index 3e631917..22875b9b 100644 --- a/src/routing_layer/topo_node.c +++ b/src/routing_layer/topo_node.c @@ -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; diff --git a/src/routing_layer/topo_node.h b/src/routing_layer/topo_node.h index b09b1404..160988f3 100644 --- a/src/routing_layer/topo_node.h +++ b/src/routing_layer/topo_node.h @@ -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 diff --git a/src/routing_layer/topo_node_sqlite.c b/src/routing_layer/topo_node_sqlite.c index d7252205..d507738b 100644 --- a/src/routing_layer/topo_node_sqlite.c +++ b/src/routing_layer/topo_node_sqlite.c @@ -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; diff --git a/src/transport_layer/etcp_connections.c b/src/transport_layer/etcp_connections.c index 49ce37d8..35fde3c4 100644 --- a/src/transport_layer/etcp_connections.c +++ b/src/transport_layer/etcp_connections.c @@ -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); diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt index fa045539..16073230 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/ChatRepository.kt @@ -87,7 +87,11 @@ data class MemberDetail(val nodeId: Long, val name: String = "", val bgpNodes: Int = 0) data class MemberAddr(val family: Int = 0, val protocol: String = "", val address: String = "", - val port: Int = 0, val socketId: Int = 0, val rtt: Int = 0) + val port: Int = 0, val socketId: Int = 0, val addrType: Int = 0, val rtt: Int = 0) { + val roleLabel: String get() = when (addrType) { + 0 -> "local"; 1 -> "public"; 2 -> "nat_eim"; 3 -> "nat_strict"; 4 -> "nat"; else -> "?$addrType" + } +} data class LinkStatus(val linkId: Int = 0, val localFamily: Int = 0, val localAddr: String = "", val localPort: Int = 0, val remoteFamily: Int = 0, val remoteAddr: String = "", val remotePort: Int = 0, @@ -428,6 +432,7 @@ class ChatRepository { address = a.optString("ad", ""), port = a.optInt("po", 0), socketId = a.optInt("si", 0), + addrType = a.optInt("at", 0), rtt = a.optInt("rt", 0) )) } diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/MemberListScreen.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/MemberListScreen.kt index 066ab154..e8ec6d52 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/MemberListScreen.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/MemberListScreen.kt @@ -325,7 +325,7 @@ private fun MemberDetailCard( Text("Addresses:", fontSize = 13.sp, fontWeight = FontWeight.Medium) detail.addresses.forEach { a -> Text( - text = "${a.protocol} ${a.address}:${a.port}", + text = "[sock${a.socketId}] ${a.protocol} ${a.address}:${a.port} ${a.roleLabel}", fontFamily = FontFamily.Monospace, fontSize = 13.sp, color = Color.DarkGray diff --git a/tools/chatgui-android/jni_bridge/android_jni_bridge.c b/tools/chatgui-android/jni_bridge/android_jni_bridge.c index a75e29a4..79d95566 100644 --- a/tools/chatgui-android/jni_bridge/android_jni_bridge.c +++ b/tools/chatgui-android/jni_bridge/android_jni_bridge.c @@ -673,8 +673,8 @@ char* utun_bridge_get_member_detail_json(const char* channel_id, uint64_t node_i snprintf(buf + pos, sizeof(buf) - pos, ",\"adr\":["); pos += strlen(buf + pos); if (sqlite3_prepare_v2(db, - "SELECT family, protocol, address, port, socket_id, COALESCE(rtt,0)" - " FROM node_addresses WHERE node_id=? ORDER BY family, port", + "SELECT family, protocol, address, port, socket_id, addr_type, COALESCE(rtt,0)" + " FROM node_addresses WHERE node_id=? ORDER BY socket_id, addr_type, family, port", -1, &st, NULL) == SQLITE_OK) { sqlite3_bind_int64(st, 1, (sqlite3_int64)node_id); int af = 1; @@ -685,7 +685,8 @@ char* utun_bridge_get_member_detail_json(const char* channel_id, uint64_t node_i int addr_len = sqlite3_column_bytes(st, 2); int port = sqlite3_column_int(st, 3); int sid = sqlite3_column_int(st, 4); - int rtt = sqlite3_column_int(st, 5); + int at = sqlite3_column_int(st, 5); + int rtt = sqlite3_column_int(st, 6); char addr_str[64] = ""; if (addr && addr_len >= (family == 4 ? 4 : 16)) { @@ -700,8 +701,8 @@ char* utun_bridge_get_member_detail_json(const char* channel_id, uint64_t node_i const char* pn; switch (proto) { case 1: pn = "UDP"; break; case 2: pn = "TCP"; break; default: pn = "UDP/TCP"; break; } pos += (size_t)snprintf(buf + pos, sizeof(buf) - pos, - "%s{\"fm\":%d,\"pt\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"si\":%d,\"rt\":%d}", - af ? "" : ",", family, pn, addr_str[0] ? addr_str : "?", port, sid, rtt); + "%s{\"fm\":%d,\"pt\":\"%s\",\"ad\":\"%s\",\"po\":%d,\"si\":%d,\"at\":%d,\"rt\":%d}", + af ? "" : ",", family, pn, addr_str[0] ? addr_str : "?", port, sid, at, rtt); af = 0; } sqlite3_finalize(st); diff --git a/tools/chatgui/src/accountlist.cpp b/tools/chatgui/src/accountlist.cpp index 805a570c..8e9c4437 100644 --- a/tools/chatgui/src/accountlist.cpp +++ b/tools/chatgui/src/accountlist.cpp @@ -31,6 +31,10 @@ static void memberDetailCb(const uint8_t* data, int len) { g_detailTarget->onMemberDetailData(nodeId, data, len); } +static QString addrRoleStr(int t) { + switch (t) { case 0: return "local"; case 1: return "public"; case 2: return "nat_eim"; case 3: return "nat_strict"; case 4: return "nat"; default: return QString("?%1").arg(t); } +} + QString AccountList::addrStr(const void* addr, int family) { if (family == 4) { const uint8_t* a = (const uint8_t*)addr; @@ -233,7 +237,7 @@ void AccountList::showMemberDetail(quint64 nodeId) { sqlite3_stmt* na = nullptr; sqlite3_prepare_v2(d, - "SELECT family, protocol, address, port, socket_id FROM node_addresses WHERE node_id=?", + "SELECT family, protocol, address, port, socket_id, addr_type FROM node_addresses WHERE node_id=?", -1, &na, nullptr); if (na) { sqlite3_bind_int64(na, 1, (sqlite3_int64)nodeId); @@ -246,6 +250,7 @@ void AccountList::showMemberDetail(quint64 nodeId) { if (adr && sz > 0) a.addr = QByteArray((const char*)adr, sz); a.port = sqlite3_column_int(na, 3); a.socket_id = sqlite3_column_int(na, 4); + a.addr_type = sqlite3_column_int(na, 5); if (!a.addr.isEmpty()) m_detailAddrs.append(a); } sqlite3_finalize(na); @@ -253,7 +258,8 @@ void AccountList::showMemberDetail(quint64 nodeId) { std::sort(m_detailAddrs.begin(), m_detailAddrs.end(), [](const DetailAddress& a, const DetailAddress& b) { - if (a.ifname != b.ifname) return a.ifname < b.ifname; + if (a.socket_id != b.socket_id) return a.socket_id < b.socket_id; + if (a.addr_type != b.addr_type) return a.addr_type < b.addr_type; if (a.addr != b.addr) return a.addr < b.addr; if (a.protocol != b.protocol) return a.protocol < b.protocol; return a.port < b.port; @@ -333,7 +339,8 @@ void AccountList::onMemberDetailData(uint64_t nodeId, const uint8_t* data, int l } std::sort(m_detailAddrs.begin(), m_detailAddrs.end(), [](const DetailAddress& a, const DetailAddress& b) { - if (a.ifname != b.ifname) return a.ifname < b.ifname; + if (a.socket_id != b.socket_id) return a.socket_id < b.socket_id; + if (a.addr_type != b.addr_type) return a.addr_type < b.addr_type; if (a.addr != b.addr) return a.addr < b.addr; if (a.protocol != b.protocol) return a.protocol < b.protocol; return a.port < b.port; @@ -365,11 +372,13 @@ void AccountList::updateDetailDisplay() { for (const auto& a : m_detailAddrs) { QString proto; switch (a.protocol) { case 1: proto = "UDP"; break; case 2: proto = "TCP"; break; default: proto = "?"; break; } - lines.append(QString(" %1 %2 %3:%4") + lines.append(QString(" [sock%1] %2 %3 %4:%5 %6") + .arg(a.socket_id) .arg(proto) .arg(a.ifname) .arg(addrStr(a.addr.constData(), a.family)) - .arg(a.port)); + .arg(a.port) + .arg(addrRoleStr(a.addr_type))); } } diff --git a/tools/chatgui/src/accountlist.h b/tools/chatgui/src/accountlist.h index e8e77f66..a51bce05 100644 --- a/tools/chatgui/src/accountlist.h +++ b/tools/chatgui/src/accountlist.h @@ -19,6 +19,7 @@ struct DetailAddress { QByteArray addr; int port; int socket_id; + int addr_type; QString ifname; }; diff --git a/tools/chatgui/src/memberlistmodel.cpp b/tools/chatgui/src/memberlistmodel.cpp index 9321e8cf..baf79a3e 100644 --- a/tools/chatgui/src/memberlistmodel.cpp +++ b/tools/chatgui/src/memberlistmodel.cpp @@ -39,8 +39,8 @@ QVariant MemberListModel::data(const QModelIndex& index, int role) const { QString sub; if (it->rtt >= 0) sub += QString("rtt=%1ms").arg(it->rtt / 10); if (it->natType >= 0) { - static const char* nat[] = {"NET","DIR","EIM","STR"}; - const char* nt = (it->natType <= 3) ? nat[it->natType] : "?"; + static const char* nat[] = {"NET","DIR","EIM","STR","NAT"}; + const char* nt = (it->natType <= 4) ? nat[it->natType] : "?"; if (!sub.isEmpty()) sub += " "; sub += nt; } diff --git a/tools/chatgui/src/nodespage.cpp b/tools/chatgui/src/nodespage.cpp index 68a0d559..980fe869 100644 --- a/tools/chatgui/src/nodespage.cpp +++ b/tools/chatgui/src/nodespage.cpp @@ -47,7 +47,7 @@ QString NodesPage::protoStr(int protocol) { } static QString addrTypeStr(int t) { - switch (t) { case 0: return "NETIF"; case 1: return "DIRECT"; case 2: return "NAT_EIM"; case 3: return "NAT_STRICT"; default: return QString("?%1").arg(t); } + switch (t) { case 0: return "NETIF"; case 1: return "DIRECT"; case 2: return "NAT_EIM"; case 3: return "NAT_STRICT"; case 4: return "NAT"; default: return QString("?%1").arg(t); } } NodesPage::NodesPage(DbManager* db, QWidget* parent) diff --git a/tools/chatgui/transport/node_config.cpp b/tools/chatgui/transport/node_config.cpp index 7511e76f..bac5ff5f 100644 --- a/tools/chatgui/transport/node_config.cpp +++ b/tools/chatgui/transport/node_config.cpp @@ -30,7 +30,8 @@ static const QSet SERVER_KEYS = { }; static const QSet CLIENT_KEYS = { - "peer_public_key", "link", "keepalive" + "peer_public_key", "link", "keepalive", + "reality", "server_name", "short_id", "public_key", "version", "fingerprint" }; static const QSet CONTROL_KEYS = {