|
|
|
|
@ -6,7 +6,7 @@
|
|
|
|
|
static void wait_profile(struct nat_fixture *fixture, struct ETCP_SOCKET *socket, uint8_t mapping, uint8_t inbound) { |
|
|
|
|
uint64_t end = get_time_tb() + 180000; |
|
|
|
|
while (get_time_tb() < end) { |
|
|
|
|
if (socket->address_profile.evidence_id && socket->address_profile.mapping == mapping && |
|
|
|
|
if (socket->address_profile.source && socket->address_profile.mapping == mapping && |
|
|
|
|
socket->address_profile.inbound == inbound) return; |
|
|
|
|
uasync_poll(fixture->ua, 10); |
|
|
|
|
} |
|
|
|
|
@ -23,13 +23,11 @@ static void check_snapshot(struct UTUN_INSTANCE *owner, struct ETCP_SOCKET *sock
|
|
|
|
|
assert(node && topo_node_verify(node) == 0); |
|
|
|
|
struct TOPO_SOCKMETA4 *meta = node->v4_sock_meta; |
|
|
|
|
while (meta && meta->id != socket->sock_id) meta = meta->next; |
|
|
|
|
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.mapping == socket->address_profile.mapping && |
|
|
|
|
assert(meta && meta->address_profile.mapping == socket->address_profile.mapping && |
|
|
|
|
meta->address_profile.inbound == socket->address_profile.inbound && |
|
|
|
|
meta->address_profile.source == ADDRESS_SOURCE_ETCP); |
|
|
|
|
struct address_profile saved = meta->address_profile; |
|
|
|
|
meta->address_profile.checked_at++; |
|
|
|
|
meta->address_profile.mapping = ADDRESS_MAP_DEPENDENT; |
|
|
|
|
assert(topo_node_verify(node) < 0); |
|
|
|
|
meta->address_profile = saved; |
|
|
|
|
meta->address_profile.source = ADDRESS_SOURCE_STUN; |
|
|
|
|
@ -41,14 +39,12 @@ static void check_snapshot(struct UTUN_INSTANCE *owner, struct ETCP_SOCKET *sock
|
|
|
|
|
|
|
|
|
|
sqlite3_stmt *statement = NULL; |
|
|
|
|
assert(sqlite3_prepare_v2(owner->topo_sqlite_db, |
|
|
|
|
"SELECT nat_mapping,nat_inbound,nat_evidence,nat_checked,nat_source FROM node_addresses WHERE node_id=? AND socket_id=?", |
|
|
|
|
"SELECT nat_mapping,nat_inbound,nat_source FROM node_addresses WHERE node_id=? AND socket_id=?", |
|
|
|
|
-1, &statement, NULL) == SQLITE_OK); |
|
|
|
|
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_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, 3) == saved.checked_at); |
|
|
|
|
assert(sqlite3_column_int(statement, 4) == ADDRESS_SOURCE_ETCP); |
|
|
|
|
assert(sqlite3_column_int(statement, 2) == ADDRESS_SOURCE_ETCP); |
|
|
|
|
sqlite3_finalize(statement); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -90,7 +86,9 @@ int main(void) {
|
|
|
|
|
struct nat_check_status status; |
|
|
|
|
assert(nat_detection_get_status(owner->nat_det, socket, &status) == 0); |
|
|
|
|
assert(status.helper_reselections > 0 && status.helper == helper->node_id && status.observer == observer->node_id); |
|
|
|
|
assert(socket->address_profile.evidence_id != second_socket->address_profile.evidence_id); |
|
|
|
|
struct nat_check_status second_status; |
|
|
|
|
assert(nat_detection_get_status(owner->nat_det, second_socket, &second_status) == 0); |
|
|
|
|
assert(status.round != second_status.round); |
|
|
|
|
check_snapshot(owner, socket); |
|
|
|
|
check_snapshot(owner, second_socket); |
|
|
|
|
check_snapshot(owner, tcp); |
|
|
|
|
@ -99,13 +97,17 @@ int main(void) {
|
|
|
|
|
assert(!route_ping_addr_equal(&socket->local_addr, &observer_socket->local_addr, 1)); |
|
|
|
|
assert(!route_ping_addr_equal(&socket->local_addr, &test_etcp_bound_socket(helper, "udp")->local_addr, 1)); |
|
|
|
|
|
|
|
|
|
/* Повторная проверка не объявляет старый контакт независимым. */ |
|
|
|
|
uint64_t old_evidence = socket->address_profile.evidence_id; |
|
|
|
|
/* Неполный повторный ingress сохраняет успех и не изменяет подписанный NODEINFO. */ |
|
|
|
|
uint64_t old_round = status.round; |
|
|
|
|
struct TOPO_NODE *snapshot = topo_node_registry_find(owner->topo_groups, owner->node_id); |
|
|
|
|
uint64_t old_timestamp = snapshot->timestamp; |
|
|
|
|
nat_detection_request_check_all(owner->nat_det); |
|
|
|
|
uint64_t end = get_time_tb() + 180000; |
|
|
|
|
while (get_time_tb() < end && socket->address_profile.evidence_id == old_evidence) uasync_poll(fixture.ua, 10); |
|
|
|
|
assert(socket->address_profile.evidence_id != old_evidence); |
|
|
|
|
assert(socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED && socket->address_profile.inbound == ADDRESS_IN_UNKNOWN); |
|
|
|
|
do { uasync_poll(fixture.ua, 10); assert(!nat_detection_get_status(owner->nat_det, socket, &status)); } |
|
|
|
|
while (get_time_tb() < end && (status.round == old_round || status.phase)); |
|
|
|
|
assert(status.round != old_round && !status.phase && status.reason == NAT_REASON_CONTACT_HISTORY); |
|
|
|
|
assert(socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED && socket->address_profile.inbound == ADDRESS_IN_OPEN); |
|
|
|
|
assert(snapshot->timestamp == old_timestamp && topo_node_verify(snapshot) == 0); |
|
|
|
|
|
|
|
|
|
/* Закрытие endpoint посреди запроса и переиспользование ID/порта: старые ответы не применяются. */ |
|
|
|
|
nat_detection_request_check_all(owner->nat_det); |
|
|
|
|
|