nat: distinguish public interface addresses from unknown NAT candidates
This commit is contained in:
1 parent
37461bb938
commit
78f71ddbb0
3 files changed
+23
-4
No files matched your search
@@ -62,11 +62,13 @@ static int addr_type_from_ip(int family, const uint8_t* addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Итоговая классификация: конфиг + автоопределение + IP (всё локально). */
|
/* Итоговая классификация: конфиг + автоопределение + IP (всё локально). */
|
||||||
static int addr_type_classify(int config_type, int global, const struct address_profile *profile) {
|
static int addr_type_classify(int kind, int config_type, int global, const struct address_profile *profile) {
|
||||||
if (config_type == CFG_SERVER_TYPE_PRIVATE || config_type == CFG_SERVER_TYPE_LOCAL) return ADDR_TYPE_NETIF;
|
if (config_type == CFG_SERVER_TYPE_PRIVATE || config_type == CFG_SERVER_TYPE_LOCAL) return ADDR_TYPE_NETIF;
|
||||||
if (!profile) return ADDR_TYPE_NAT;
|
if (!profile) return ADDR_TYPE_NAT;
|
||||||
if (profile->mapping == ADDRESS_MAP_EIM) return ADDR_TYPE_NAT_EIM;
|
if (profile->mapping == ADDRESS_MAP_EIM) return ADDR_TYPE_NAT_EIM;
|
||||||
if (profile->mapping == ADDRESS_MAP_DEPENDENT) return ADDR_TYPE_NAT_STRICT;
|
if (profile->mapping == ADDRESS_MAP_DEPENDENT) return ADDR_TYPE_NAT_STRICT;
|
||||||
|
/* Публичный адрес интерфейса известен без определения входящих и не становится NAT из-за UNKNOWN. */
|
||||||
|
if (global && kind == TOPO_ADDR_INTERFACE && profile->mapping == ADDRESS_MAP_UNKNOWN) return ADDR_TYPE_NETIF;
|
||||||
if (!global) return config_type == CFG_SERVER_TYPE_NAT ? ADDR_TYPE_NAT : ADDR_TYPE_NETIF;
|
if (!global) return config_type == CFG_SERVER_TYPE_NAT ? ADDR_TYPE_NAT : ADDR_TYPE_NETIF;
|
||||||
if (profile->mapping == ADDRESS_MAP_UNCHANGED && profile->inbound == ADDRESS_IN_OPEN) return ADDR_TYPE_DIRECT;
|
if (profile->mapping == ADDRESS_MAP_UNCHANGED && profile->inbound == ADDRESS_IN_OPEN) return ADDR_TYPE_DIRECT;
|
||||||
if (profile->mapping == ADDRESS_MAP_UNCHANGED && profile->inbound == ADDRESS_IN_CONTACT) return ADDR_TYPE_CONTACT;
|
if (profile->mapping == ADDRESS_MAP_UNCHANGED && profile->inbound == ADDRESS_IN_CONTACT) return ADDR_TYPE_CONTACT;
|
||||||
@@ -109,7 +111,7 @@ static int address_row_put(sqlite3_stmt *statement, struct TOPO_NODE *node, uint
|
|||||||
uint8_t protocol, uint8_t config, const struct address_profile *profile) {
|
uint8_t protocol, uint8_t config, const struct address_profile *profile) {
|
||||||
static const struct address_profile unknown = {0};
|
static const struct address_profile unknown = {0};
|
||||||
if (!profile) profile = &unknown;
|
if (!profile) profile = &unknown;
|
||||||
int summary = addr_type_classify(config, addr_type_from_ip(family, address) == ADDR_TYPE_DIRECT, profile);
|
int summary = addr_type_classify(kind, config, addr_type_from_ip(family, address) == ADDR_TYPE_DIRECT, profile);
|
||||||
struct TOPO_ADDR_REALITY_OPTS reality;
|
struct TOPO_ADDR_REALITY_OPTS reality;
|
||||||
int has_reality = (protocol & TOPO_PROTO_REALITY) && reality_opts_build(node, socket_id, &reality);
|
int has_reality = (protocol & TOPO_PROTO_REALITY) && reality_opts_build(node, socket_id, &reality);
|
||||||
sqlite3_bind_int64(statement, 1, (sqlite3_int64)node_id);
|
sqlite3_bind_int64(statement, 1, (sqlite3_int64)node_id);
|
||||||
|
|||||||
@@ -83,6 +83,16 @@ static void test_compact_addresses(struct UTUN_INSTANCE *inst) {
|
|||||||
assert(sqlite3_column_int(statement, 4) == ADDR_TYPE_CONTACT && sqlite3_column_int(statement, 5) == TOPO_ADDR_REALITY_OPTS_SIZE);
|
assert(sqlite3_column_int(statement, 4) == ADDR_TYPE_CONTACT && sqlite3_column_int(statement, 5) == TOPO_ADDR_REALITY_OPTS_SIZE);
|
||||||
assert(sqlite3_step(statement) == SQLITE_DONE); sqlite3_finalize(statement);
|
assert(sqlite3_step(statement) == SQLITE_DONE); sqlite3_finalize(statement);
|
||||||
|
|
||||||
|
/* Публичный IP интерфейса не становится NAT UNKNOWN из-за отсутствия измерения входящих. */
|
||||||
|
struct address_profile known = node->v4_sock_meta->address_profile;
|
||||||
|
node->v4_sock_meta->address_profile = (struct address_profile){0};
|
||||||
|
assert(!topo_node_sqlite_addrs_put(db, inst->node_id, node));
|
||||||
|
assert(sqlite3_prepare_v2(db, "SELECT addr_type FROM node_addresses WHERE family=4", -1, &statement, NULL) == SQLITE_OK);
|
||||||
|
assert(sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_int(statement, 0) == ADDR_TYPE_NETIF);
|
||||||
|
sqlite3_finalize(statement);
|
||||||
|
node->v4_sock_meta->address_profile = known;
|
||||||
|
assert(!topo_node_sqlite_addrs_put(db, inst->node_id, node));
|
||||||
|
|
||||||
/* Две старые колонки отмечают прежний формат. Миграция не теряет IP/port, REALITY и максимум timestamp. */
|
/* Две старые колонки отмечают прежний формат. Миграция не теряет IP/port, REALITY и максимум timestamp. */
|
||||||
assert(sqlite3_exec(db, "ALTER TABLE node_addresses ADD COLUMN nat_evidence INTEGER DEFAULT 1;"
|
assert(sqlite3_exec(db, "ALTER TABLE node_addresses ADD COLUMN nat_evidence INTEGER DEFAULT 1;"
|
||||||
"ALTER TABLE node_addresses ADD COLUMN nat_checked INTEGER DEFAULT 1", NULL, NULL, NULL) == SQLITE_OK);
|
"ALTER TABLE node_addresses ADD COLUMN nat_checked INTEGER DEFAULT 1", NULL, NULL, NULL) == SQLITE_OK);
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ void NodesPage::refreshNodes() {
|
|||||||
|
|
||||||
sqlite3_stmt* na = nullptr;
|
sqlite3_stmt* na = nullptr;
|
||||||
sqlite3_prepare_v2(d,
|
sqlite3_prepare_v2(d,
|
||||||
"SELECT family, protocol, address, port, rtt, addr_type, address_kind"
|
"SELECT family, protocol, address, port, rtt, addr_type, address_kind, nat_mapping, nat_inbound"
|
||||||
" FROM node_addresses WHERE node_id=? ORDER BY family, port",
|
" FROM node_addresses WHERE node_id=? ORDER BY family, port",
|
||||||
-1, &na, nullptr);
|
-1, &na, nullptr);
|
||||||
if (na) {
|
if (na) {
|
||||||
@@ -224,13 +224,20 @@ void NodesPage::refreshNodes() {
|
|||||||
int rtt = sqlite3_column_int(na, 4);
|
int rtt = sqlite3_column_int(na, 4);
|
||||||
int addrType = sqlite3_column_int(na, 5);
|
int addrType = sqlite3_column_int(na, 5);
|
||||||
int kind = sqlite3_column_int(na, 6);
|
int kind = sqlite3_column_int(na, 6);
|
||||||
|
int mapping = sqlite3_column_int(na, 7), inbound = sqlite3_column_int(na, 8);
|
||||||
|
|
||||||
if (addr && addrSz > 0) {
|
if (addr && addrSz > 0) {
|
||||||
|
QString label = addrTypeStr(addrType);
|
||||||
|
if (kind == TOPO_ADDR_INTERFACE) {
|
||||||
|
label = QStringLiteral("INTERFACE");
|
||||||
|
if (mapping != ADDRESS_MAP_UNKNOWN || inbound != ADDRESS_IN_UNKNOWN)
|
||||||
|
label += QString(" mapping=%1 inbound=%2").arg(address_mapping_name(mapping), address_inbound_name(inbound));
|
||||||
|
}
|
||||||
dump += QString(" %1:%2 %3 %4 rtt=%5ms\n")
|
dump += QString(" %1:%2 %3 %4 rtt=%5ms\n")
|
||||||
.arg(addrStr(addr, family))
|
.arg(addrStr(addr, family))
|
||||||
.arg(port)
|
.arg(port)
|
||||||
.arg(protoStr(proto))
|
.arg(protoStr(proto))
|
||||||
.arg(kind == TOPO_ADDR_INTERFACE ? QStringLiteral("INTERFACE") : addrTypeStr(addrType))
|
.arg(label)
|
||||||
.arg(rtt > 0 ? QString::number(rtt / 10) : "-");
|
.arg(rtt > 0 ? QString::number(rtt / 10) : "-");
|
||||||
}
|
}
|
||||||
ac++;
|
ac++;
|
||||||
|
|||||||
Reference in new issue
Block a user