nat: prioritize mapping candidates and label unknown NAT explicitly
This commit is contained in:
1 parent
6037819269
commit
79d8789410
3 files changed
+21
-7
No files matched your search
@@ -48,6 +48,7 @@ struct nat_wire {
|
||||
|
||||
struct nat_pair {
|
||||
uint64_t group, observer, helper;
|
||||
uint8_t helper_priority; /* Сначала публичный endpoint C, затем приватный, затем один наблюдатель. */
|
||||
uint8_t observer_endpoint[ROUTE_ADDR_WIRE_SIZE], helper_endpoint[ROUTE_ADDR_WIRE_SIZE];
|
||||
};
|
||||
struct nat_recheck_wire { uint8_t cmd, command, version, socket_id, address[ROUTE_ADDR_WIRE_SIZE]; };
|
||||
@@ -223,6 +224,8 @@ static int node_udp_endpoint(struct NAT_DETECTION *detector, const struct TOPO_N
|
||||
}
|
||||
|
||||
static int pair_after(struct nat_pair a, struct nat_pair b) {
|
||||
if (!a.group || !b.group) return a.group != 0;
|
||||
if (a.helper_priority != b.helper_priority) return a.helper_priority > b.helper_priority;
|
||||
if (a.group != b.group) return a.group > b.group;
|
||||
if (a.observer != b.observer) return a.observer > b.observer;
|
||||
if (a.helper != b.helper) return a.helper > b.helper;
|
||||
@@ -255,7 +258,7 @@ static int select_pair(struct nat_socket *state) {
|
||||
node_udp_endpoint(detector, bn, state->local.ss_family, 0, previous_b, &ba, &bs)) {
|
||||
if (!state->socket->is_tcp && route_ping_addr_encode(previous_b, &ba)) break;
|
||||
observers++;
|
||||
struct nat_pair observer_only = {.group = group->group_id, .observer = observer};
|
||||
struct nat_pair observer_only = {.group = group->group_id, .observer = observer, .helper_priority = 2};
|
||||
memcpy(observer_only.observer_endpoint, previous_b, sizeof(previous_b));
|
||||
if (!state->socket->is_tcp && pair_after(observer_only, state->cursor) &&
|
||||
(!single.group || pair_after(single, observer_only))) {
|
||||
@@ -271,7 +274,8 @@ static int select_pair(struct nat_socket *state) {
|
||||
for (; more_c; more_c = !state->socket->is_tcp &&
|
||||
node_udp_endpoint(detector, cn, state->local.ss_family, 1, previous_c, &ca, &cs)) {
|
||||
if (!state->socket->is_tcp && route_ping_addr_encode(previous_c, &ca)) break;
|
||||
struct nat_pair candidate = {.group = group->group_id, .observer = observer, .helper = helper};
|
||||
struct nat_pair candidate = {.group = group->group_id, .observer = observer, .helper = helper,
|
||||
.helper_priority = !public_address(detector, &ca)};
|
||||
memcpy(candidate.observer_endpoint, previous_b, sizeof(previous_b));
|
||||
memcpy(candidate.helper_endpoint, previous_c, sizeof(previous_c));
|
||||
if (state->using_fallback) {
|
||||
@@ -1286,7 +1290,7 @@ static void owner_start(struct nat_socket *state) {
|
||||
}
|
||||
if (!state->cycling) {
|
||||
state->cycling = 1; state->cursor = (struct nat_pair){0}; state->fallback = (struct nat_pair){0};
|
||||
state->using_fallback = 0; state->prefer_fresh = 1;
|
||||
state->using_fallback = 0; state->prefer_fresh = state->measured_profile.mapping != ADDRESS_MAP_UNKNOWN;
|
||||
state->cycle_deadline = get_time_tb() + NAT_ROUND_TB;
|
||||
}
|
||||
history_load(state);
|
||||
|
||||
@@ -61,7 +61,7 @@ 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","DEP","?","CONTACT"};
|
||||
static const char* nat[] = {"NET","DIR","EIM","DEP","NAT type=UNKNOWN","CONTACT"};
|
||||
const char* nt = (it->natType <= 5) ? nat[it->natType] : "?";
|
||||
if (!sub.isEmpty()) sub += " ";
|
||||
sub += nt;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "../../../lib/platform_compat.h"
|
||||
#include "../../../src/routing_layer/topo_node.h"
|
||||
|
||||
static QString hex16(uint64_t v) {
|
||||
return QString("%1").arg(v, 16, 16, QChar('0')).toUpper();
|
||||
@@ -49,7 +50,15 @@ 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_DEPENDENT"; case 4: return "UNKNOWN"; case 5: return "CONTACT_REQUIRED"; default: return QString("?%1").arg(t); }
|
||||
switch (t) {
|
||||
case ADDR_TYPE_NETIF: return "NETIF";
|
||||
case ADDR_TYPE_DIRECT: return "DIRECT";
|
||||
case ADDR_TYPE_NAT_EIM: return "NAT type=EIM";
|
||||
case ADDR_TYPE_NAT_STRICT: return "NAT type=STRICT";
|
||||
case ADDR_TYPE_NAT: return "NAT type=UNKNOWN";
|
||||
case ADDR_TYPE_CONTACT: return "CONTACT_REQUIRED";
|
||||
default: return QString("?%1").arg(t);
|
||||
}
|
||||
}
|
||||
|
||||
NodesPage::NodesPage(DbManager* db, QWidget* parent)
|
||||
@@ -199,7 +208,7 @@ void NodesPage::refreshNodes() {
|
||||
|
||||
sqlite3_stmt* na = nullptr;
|
||||
sqlite3_prepare_v2(d,
|
||||
"SELECT family, protocol, address, port, rtt, addr_type"
|
||||
"SELECT family, protocol, address, port, rtt, addr_type, address_kind"
|
||||
" FROM node_addresses WHERE node_id=? ORDER BY family, port",
|
||||
-1, &na, nullptr);
|
||||
if (na) {
|
||||
@@ -214,13 +223,14 @@ void NodesPage::refreshNodes() {
|
||||
int port = sqlite3_column_int(na, 3);
|
||||
int rtt = sqlite3_column_int(na, 4);
|
||||
int addrType = sqlite3_column_int(na, 5);
|
||||
int kind = sqlite3_column_int(na, 6);
|
||||
|
||||
if (addr && addrSz > 0) {
|
||||
dump += QString(" %1:%2 %3 %4 rtt=%5ms\n")
|
||||
.arg(addrStr(addr, family))
|
||||
.arg(port)
|
||||
.arg(protoStr(proto))
|
||||
.arg(addrTypeStr(addrType))
|
||||
.arg(kind == TOPO_ADDR_INTERFACE ? QStringLiteral("INTERFACE") : addrTypeStr(addrType))
|
||||
.arg(rtt > 0 ? QString::number(rtt / 10) : "-");
|
||||
}
|
||||
ac++;
|
||||
|
||||
Reference in new issue
Block a user