Browse Source

test(nat): reserve fresh helper before publishing it during recheck

stream-multiview
evgeny 1 week ago
parent
commit
1d1f5d081f
  1. 25
      tests/test_nat_detection_faults.c

25
tests/test_nat_detection_faults.c

@ -14,7 +14,7 @@ static struct {
struct UTUN_INSTANCE *owner, *observer, *helper, *alias;
struct ETCP_SOCKET *socket, *alias_source;
enum fault_mode mode;
unsigned dropped, altered, direct_received, observations;
unsigned dropped, altered, direct_received, observations, preserved;
int contacted, injected;
socket_t delayed_fd;
uint8_t delayed[1600];
@ -160,6 +160,9 @@ void __wrap_nat_detection_record_observation(struct NAT_DETECTION *detector, str
/* Подлинная проба приходит с локального IP, несмотря на пригодный предварительный адрес помощника. */
void __wrap_nat_detection_receive_ingress(struct NAT_DETECTION *detector, struct ETCP_SOCKET *socket,
const uint8_t *key, const struct sockaddr_storage *source, const uint8_t *tag, size_t length) {
if (fault.fixture && fault.mode == FAULT_KNOWN_ALIAS && detector == fault.owner->nat_det &&
!memcmp(key, fault.alias->my_keys.public_key, 32) && socket->address_profile.inbound == ADDRESS_IN_OPEN)
fault.preserved++;
if (fault.fixture && fault.mode == FAULT_LOCAL_INGRESS && detector == fault.owner->nat_det &&
!memcmp(key, fault.alias->my_keys.public_key, 32)) {
struct nat_check_status before, after;
@ -275,16 +278,16 @@ static void run_alias(const char *alias_ip, enum fault_mode mode) {
do { assert(sc_generate_keypair(&next) == SC_OK); }
while (sc_derive_node_id_from_pubkey(next.public_key) <= alias->node_id);
struct UTUN_INSTANCE *fresh = nat_fixture_node(&fixture, "127.0.0.6", &next, NULL);
nat_detection_set_automatic(fresh->nat_det, 0); nat_fixture_connect(&fixture, observer, "udp", fresh);
nat_detection_set_automatic(fresh->nat_det, 0);
fault.helper = fresh; rounds = status.rounds;
assert(!nat_detection_request_check_socket(owner->nat_det, socket, observer->node_id));
int preserved_seen = 0; end = get_time_tb() + 400000;
/* Резерв нового измерения включён до появления нового IP в топологии. */
nat_fixture_connect(&fixture, observer, "udp", fresh);
end = get_time_tb() + 400000;
do {
test_clock_poll(fixture.ua, 1000); assert(!nat_detection_get_status(owner->nat_det, socket, &status));
if (status.helper == alias->node_id && status.reason == NAT_REASON_CONTACT_HISTORY && status.cycling &&
socket->address_profile.inbound == ADDRESS_IN_OPEN) preserved_seen = 1;
} while (get_time_tb() < end && (status.rounds == rounds || status.phase || status.cycling));
assert(preserved_seen && !status.phase && !status.cycling && status.helper == fresh->node_id);
assert(fault.preserved && !status.phase && !status.cycling && status.helper == fresh->node_id && !status.reason);
assert(socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED && socket->address_profile.inbound == ADDRESS_IN_OPEN);
}
fault.fixture = NULL; nat_fixture_cleanup(&fixture);
@ -402,6 +405,9 @@ static void run_budget_resume(void) {
nat_fixture_connect(&fixture, owner, "udp", observer);
memset(&fault, 0, sizeof(fault)); fault.fixture = &fixture; fault.owner = owner; fault.observer = observer;
fault.socket = test_etcp_bound_socket(owner, "udp"); fault.mode = FAULT_BUDGET;
for (unsigned i = 2; i < fixture.node_count; i++)
assert(!etcp_send_ping_to_socket(owner, fault.socket, fixture.nodes[i]->my_keys.public_key,
&test_etcp_bound_socket(fixture.nodes[i], "udp")->local_addr, 500, ignored_ping, NULL, NULL, 0, 0));
assert(!nat_detection_request_check_socket(owner->nat_det, fault.socket, observer->node_id));
struct nat_check_status status = {0}; uint64_t end = get_time_tb() + 500000;
do { test_clock_poll(fixture.ua, 1000); assert(!nat_detection_get_status(owner->nat_det, fault.socket, &status)); }
@ -421,10 +427,13 @@ static void run_budget_resume(void) {
assert(fault.socket->address_profile.inbound == ADDRESS_IN_UNKNOWN);
fault.mode = FAULT_NONE; fault.delayed_length = 0; end = get_time_tb() + 700000;
do { test_clock_poll(fixture.ua, 1000); assert(!nat_detection_get_status(owner->nat_det, fault.socket, &status)); }
while (get_time_tb() < end && status.round == paused_round);
assert(status.round != paused_round && status.helper == paused_helper && status.helper_reselections == completed_pairs);
do { test_clock_poll(fixture.ua, 1000); assert(!nat_detection_get_status(owner->nat_det, fault.socket, &status)); }
while (get_time_tb() < end && status.cycling);
assert(!status.phase && !status.cycling && status.round != paused_round && status.helper == paused_helper);
assert(status.helper_reselections == completed_pairs && fault.socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED &&
fault.socket->address_profile.inbound == ADDRESS_IN_OPEN);
assert(status.helper_reselections == completed_pairs + 1 && fault.socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED &&
fault.socket->address_profile.inbound == ADDRESS_IN_UNKNOWN && status.reason == NAT_REASON_CONTACT_HISTORY);
fault.fixture = NULL; nat_fixture_cleanup(&fixture);
DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS NAT budget pause retains mapping, rejects late ingress and retries the unfinished pair");
}

Loading…
Cancel
Save