|
|
|
|
@ -325,11 +325,35 @@ static void test_groups(void) {
|
|
|
|
|
assert(!stun_nat_get_socket_result(&f.inst, &duplicate, &second)); |
|
|
|
|
assert(second.mapping_reason == STUN_REASON_ROUTE); |
|
|
|
|
} else DEBUG_WARN(DEBUG_CATEGORY_NAT, "STUN routing conflict subtest unavailable: bind-to-device denied"); |
|
|
|
|
socket_close_wrapper(duplicate.fd); duplicate = extra_socket(&f, "another-ip", "127.0.0.5"); |
|
|
|
|
test_clock_run_for(f.ua, 30001); end = get_time_tb() + 3000000; |
|
|
|
|
do { assert(!stun_nat_get_socket_result(&f.inst, &duplicate, &second)); |
|
|
|
|
if (second.status != STUN_NAT_PENDING) break; test_clock_poll(f.ua, 10000); |
|
|
|
|
} while (get_time_tb() < end); |
|
|
|
|
assert(!stun_nat_get_socket_result(&f.inst, &f.source, &first)); |
|
|
|
|
assert(second.key.address[3] == 5 && first.key.address[3] == 1 && second.evidence_id != first.evidence_id); |
|
|
|
|
socket_close_wrapper(duplicate.fd); f.source.next = NULL; f.original = f.source; |
|
|
|
|
fixture_destroy(&f); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS STUN groups: duplicate ports, representative removal, separate netif, policy conflict"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Штатный refresh сохраняет прежний результат до TTL, не продлевая его возраст. */ |
|
|
|
|
static void test_cache(void) { |
|
|
|
|
struct fixture f = {.rfc = 1, .mapping = STUN_MAP_EIM, .filtering = STUN_FILTER_EIF, |
|
|
|
|
.multiple_clients = 1}; fixture_init(&f); fixture_start(&f, 0, 0, 0); |
|
|
|
|
struct stun_nat_result first = wait_result(&f), current; |
|
|
|
|
assert(first.status == STUN_NAT_COMPLETE); |
|
|
|
|
f.drop_primary = 1; |
|
|
|
|
test_clock_run_for(f.ua, 1830000); |
|
|
|
|
assert(!stun_nat_get_socket_result(&f.inst, &f.source, ¤t)); |
|
|
|
|
assert(current.evidence_id == first.evidence_id && current.measured_at_us == first.measured_at_us && current.refreshing); |
|
|
|
|
test_clock_run_for(f.ua, 1300000); |
|
|
|
|
assert(!stun_nat_get_socket_result(&f.inst, &f.source, ¤t)); |
|
|
|
|
assert(current.evidence_id != first.evidence_id && current.mapping == STUN_MAP_UNKNOWN && current.filtering == STUN_FILTER_UNKNOWN); |
|
|
|
|
fixture_destroy(&f); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS STUN cache: automatic refresh, preserved age, failed refresh and expiry"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void wait_source(struct nat_fixture* nf, struct ETCP_SOCKET* socket, uint8_t source) { |
|
|
|
|
uint64_t end = get_time_tb() + 3000000; |
|
|
|
|
while (get_time_tb() < end) { |
|
|
|
|
@ -382,6 +406,11 @@ static void test_fallback(void) {
|
|
|
|
|
while (get_time_tb() < end && next.status == STUN_NAT_PENDING); |
|
|
|
|
assert(next.mapping == STUN_MAP_EIM && next.evidence_id != prior.evidence_id); |
|
|
|
|
assert(socket->address_profile.source == ADDRESS_SOURCE_ETCP && socket->address_profile.evidence_id == evidence); |
|
|
|
|
nat_detection_request_check_all(owner->nat_det); end = get_time_tb() + 300000; |
|
|
|
|
do { test_clock_poll(nf.ua, 10000); } |
|
|
|
|
while (get_time_tb() < end && socket->address_profile.evidence_id == evidence); |
|
|
|
|
assert(socket->address_profile.source == ADDRESS_SOURCE_ETCP && socket->address_profile.evidence_id != evidence); |
|
|
|
|
assert(socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED && socket->address_profile.inbound == ADDRESS_IN_UNKNOWN); |
|
|
|
|
for (unsigned i = 0; i < 6; i++) { |
|
|
|
|
assert(!uasync_remove_socket_t(nf.ua, server.endpoints[i].fd)); socket_close_wrapper(server.endpoints[i].fd); |
|
|
|
|
} |
|
|
|
|
@ -397,6 +426,7 @@ int main(void) {
|
|
|
|
|
test_clock_init(10000); |
|
|
|
|
test_config(); |
|
|
|
|
test_groups(); |
|
|
|
|
test_cache(); |
|
|
|
|
struct fixture ordinary = { .mapping = STUN_MAP_EIM }; |
|
|
|
|
run_case("ordinary equal", &ordinary, STUN_MAP_MATCH, STUN_FILTER_UNKNOWN); |
|
|
|
|
struct fixture dependent = { .mapping = STUN_MAP_ADM }; |
|
|
|
|
|