Browse Source

Keep connection attempts available for STUN hints and verify signed provenance

master
evgeny 22 hours ago
parent
commit
164a3a1f0f
  1. 3
      src/routing_layer/sock_match.c
  2. 9
      tests/test_nat_detection.c
  3. 8
      tests/test_sock_match.c

3
src/routing_layer/sock_match.c

@ -12,7 +12,8 @@
uint8_t sock_target_class(uint8_t address_type, uint8_t config_type, const struct address_profile *profile, uint8_t sock_target_class(uint8_t address_type, uint8_t config_type, const struct address_profile *profile,
int public_address, uint64_t now_us) { int public_address, uint64_t now_us) {
if (!public_address || config_type == CFG_SERVER_TYPE_PRIVATE || config_type == CFG_SERVER_TYPE_LOCAL) return SOCK_TC_PRIV; if (!public_address || config_type == CFG_SERVER_TYPE_PRIVATE || config_type == CFG_SERVER_TYPE_LOCAL) return SOCK_TC_PRIV;
if (address_type == TOPO_ADDR_NAT && profile && profile->mapping == ADDRESS_MAP_DEPENDENT) return SOCK_TC_UNREACH; if (address_type == TOPO_ADDR_NAT && profile && profile->source == ADDRESS_SOURCE_ETCP &&
profile->mapping == ADDRESS_MAP_DEPENDENT) return SOCK_TC_UNREACH;
if (!address_profile_fresh(profile, now_us)) return SOCK_TC_PROBE; if (!address_profile_fresh(profile, now_us)) return SOCK_TC_PROBE;
if (profile->inbound == ADDRESS_IN_OPEN) return SOCK_TC_PUB; if (profile->inbound == ADDRESS_IN_OPEN) return SOCK_TC_PUB;
if (profile->inbound == ADDRESS_IN_CONTACT) return SOCK_TC_CONTACT; if (profile->inbound == ADDRESS_IN_CONTACT) return SOCK_TC_CONTACT;

9
tests/test_nat_detection.c

@ -26,24 +26,29 @@ static void check_snapshot(struct UTUN_INSTANCE *owner, struct ETCP_SOCKET *sock
assert(meta && meta->address_profile.evidence_id == socket->address_profile.evidence_id && assert(meta && meta->address_profile.evidence_id == socket->address_profile.evidence_id &&
meta->address_profile.checked_at == socket->address_profile.checked_at && meta->address_profile.checked_at == socket->address_profile.checked_at &&
meta->address_profile.mapping == socket->address_profile.mapping && meta->address_profile.mapping == socket->address_profile.mapping &&
meta->address_profile.inbound == socket->address_profile.inbound); meta->address_profile.inbound == socket->address_profile.inbound &&
meta->address_profile.source == ADDRESS_SOURCE_ETCP);
struct address_profile saved = meta->address_profile; struct address_profile saved = meta->address_profile;
meta->address_profile.checked_at++; meta->address_profile.checked_at++;
assert(topo_node_verify(node) < 0); assert(topo_node_verify(node) < 0);
meta->address_profile = saved; meta->address_profile = saved;
meta->address_profile.source = ADDRESS_SOURCE_STUN;
assert(topo_node_verify(node) < 0);
meta->address_profile = saved;
meta->address_profile.inbound = ADDRESS_IN_CONTACT; meta->address_profile.inbound = ADDRESS_IN_CONTACT;
assert(topo_node_verify(node) < 0); assert(topo_node_verify(node) < 0);
meta->address_profile = saved; assert(topo_node_verify(node) == 0); meta->address_profile = saved; assert(topo_node_verify(node) == 0);
sqlite3_stmt *statement = NULL; sqlite3_stmt *statement = NULL;
assert(sqlite3_prepare_v2(owner->topo_sqlite_db, assert(sqlite3_prepare_v2(owner->topo_sqlite_db,
"SELECT nat_mapping,nat_inbound,nat_evidence,nat_checked FROM node_addresses WHERE node_id=? AND socket_id=?", "SELECT nat_mapping,nat_inbound,nat_evidence,nat_checked,nat_source FROM node_addresses WHERE node_id=? AND socket_id=?",
-1, &statement, NULL) == SQLITE_OK); -1, &statement, NULL) == SQLITE_OK);
sqlite3_bind_int64(statement, 1, (sqlite3_int64)owner->node_id); sqlite3_bind_int(statement, 2, socket->sock_id); sqlite3_bind_int64(statement, 1, (sqlite3_int64)owner->node_id); sqlite3_bind_int(statement, 2, socket->sock_id);
assert(sqlite3_step(statement) == SQLITE_ROW); assert(sqlite3_step(statement) == SQLITE_ROW);
assert(sqlite3_column_int(statement, 0) == saved.mapping && sqlite3_column_int(statement, 1) == saved.inbound); assert(sqlite3_column_int(statement, 0) == saved.mapping && sqlite3_column_int(statement, 1) == saved.inbound);
assert((uint64_t)sqlite3_column_int64(statement, 2) == saved.evidence_id); assert((uint64_t)sqlite3_column_int64(statement, 2) == saved.evidence_id);
assert((uint64_t)sqlite3_column_int64(statement, 3) == saved.checked_at); assert((uint64_t)sqlite3_column_int64(statement, 3) == saved.checked_at);
assert(sqlite3_column_int(statement, 4) == ADDRESS_SOURCE_ETCP);
sqlite3_finalize(statement); sqlite3_finalize(statement);
} }

8
tests/test_sock_match.c

@ -13,7 +13,8 @@ int main(void) {
const uint32_t public_ip = htonl(UINT32_C(0xc633640b)); const uint32_t public_ip = htonl(UINT32_C(0xc633640b));
const uint32_t private_ip = htonl(UINT32_C(0x0a400102)); const uint32_t private_ip = htonl(UINT32_C(0x0a400102));
struct address_profile unknown = {0}; struct address_profile unknown = {0};
struct address_profile open = {.mapping = ADDRESS_MAP_EIM, .inbound = ADDRESS_IN_OPEN, .evidence_id = 1, .checked_at = now}; struct address_profile open = {.mapping = ADDRESS_MAP_EIM, .inbound = ADDRESS_IN_OPEN, .source = ADDRESS_SOURCE_ETCP,
.evidence_id = 1, .checked_at = now};
struct address_profile contact = open; contact.inbound = ADDRESS_IN_CONTACT; struct address_profile contact = open; contact.inbound = ADDRESS_IN_CONTACT;
struct address_profile dependent = open; dependent.mapping = ADDRESS_MAP_DEPENDENT; dependent.inbound = ADDRESS_IN_UNKNOWN; struct address_profile dependent = open; dependent.mapping = ADDRESS_MAP_DEPENDENT; dependent.inbound = ADDRESS_IN_UNKNOWN;
@ -39,6 +40,11 @@ int main(void) {
assert(!sock_match(&local, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &open, public_ip)); assert(!sock_match(&local, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &open, public_ip));
assert(sock_match(&local, TOPO_ADDR_INTERFACE, CFG_SERVER_TYPE_NAT, &dependent, private_ip)); assert(sock_match(&local, TOPO_ADDR_INTERFACE, CFG_SERVER_TYPE_NAT, &dependent, private_ip));
assert(!sock_match(&outgoing, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &dependent, public_ip)); assert(!sock_match(&outgoing, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &dependent, public_ip));
dependent.source = ADDRESS_SOURCE_STUN;
assert(sock_match(&outgoing, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &dependent, public_ip));
assert(address_profile_valid(&dependent));
dependent.source = ADDRESS_SOURCE_NONE;
assert(!address_profile_valid(&dependent));
outgoing.now_us = now + ADDRESS_PROFILE_TTL_US + 1; outgoing.now_us = now + ADDRESS_PROFILE_TTL_US + 1;
assert(sock_match(&outgoing, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &open, public_ip)); assert(sock_match(&outgoing, TOPO_ADDR_NAT, CFG_SERVER_TYPE_NAT, &open, public_ip));
/* Смена времени/давности снижает уверенность, сохраняя возможность реального handshake. */ /* Смена времени/давности снижает уверенность, сохраняя возможность реального handshake. */

Loading…
Cancel
Save