test(nat): reserve fresh helper before publishing it during recheck
This commit is contained in:
1 parent
edc78cbf4a
commit
1d1f5d081f
1 file changed
+17
-8
@@ -14,7 +14,7 @@ static struct {
|
|||||||
struct UTUN_INSTANCE *owner, *observer, *helper, *alias;
|
struct UTUN_INSTANCE *owner, *observer, *helper, *alias;
|
||||||
struct ETCP_SOCKET *socket, *alias_source;
|
struct ETCP_SOCKET *socket, *alias_source;
|
||||||
enum fault_mode mode;
|
enum fault_mode mode;
|
||||||
unsigned dropped, altered, direct_received, observations;
|
unsigned dropped, altered, direct_received, observations, preserved;
|
||||||
int contacted, injected;
|
int contacted, injected;
|
||||||
socket_t delayed_fd;
|
socket_t delayed_fd;
|
||||||
uint8_t delayed[1600];
|
uint8_t delayed[1600];
|
||||||
@@ -160,6 +160,9 @@ void __wrap_nat_detection_record_observation(struct NAT_DETECTION *detector, str
|
|||||||
/* Подлинная проба приходит с локального IP, несмотря на пригодный предварительный адрес помощника. */
|
/* Подлинная проба приходит с локального IP, несмотря на пригодный предварительный адрес помощника. */
|
||||||
void __wrap_nat_detection_receive_ingress(struct NAT_DETECTION *detector, struct ETCP_SOCKET *socket,
|
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) {
|
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 &&
|
if (fault.fixture && fault.mode == FAULT_LOCAL_INGRESS && detector == fault.owner->nat_det &&
|
||||||
!memcmp(key, fault.alias->my_keys.public_key, 32)) {
|
!memcmp(key, fault.alias->my_keys.public_key, 32)) {
|
||||||
struct nat_check_status before, after;
|
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); }
|
do { assert(sc_generate_keypair(&next) == SC_OK); }
|
||||||
while (sc_derive_node_id_from_pubkey(next.public_key) <= alias->node_id);
|
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);
|
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;
|
fault.helper = fresh; rounds = status.rounds;
|
||||||
assert(!nat_detection_request_check_socket(owner->nat_det, socket, observer->node_id));
|
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 {
|
do {
|
||||||
test_clock_poll(fixture.ua, 1000); assert(!nat_detection_get_status(owner->nat_det, socket, &status));
|
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));
|
} 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);
|
assert(socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED && socket->address_profile.inbound == ADDRESS_IN_OPEN);
|
||||||
}
|
}
|
||||||
fault.fixture = NULL; nat_fixture_cleanup(&fixture);
|
fault.fixture = NULL; nat_fixture_cleanup(&fixture);
|
||||||
@@ -402,6 +405,9 @@ static void run_budget_resume(void) {
|
|||||||
nat_fixture_connect(&fixture, owner, "udp", observer);
|
nat_fixture_connect(&fixture, owner, "udp", observer);
|
||||||
memset(&fault, 0, sizeof(fault)); fault.fixture = &fixture; fault.owner = owner; fault.observer = 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;
|
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));
|
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;
|
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)); }
|
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);
|
assert(fault.socket->address_profile.inbound == ADDRESS_IN_UNKNOWN);
|
||||||
fault.mode = FAULT_NONE; fault.delayed_length = 0; end = get_time_tb() + 700000;
|
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)); }
|
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);
|
while (get_time_tb() < end && status.cycling);
|
||||||
assert(!status.phase && !status.cycling && status.round != paused_round && status.helper == paused_helper);
|
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 &&
|
assert(status.helper_reselections == completed_pairs + 1 && fault.socket->address_profile.mapping == ADDRESS_MAP_UNCHANGED &&
|
||||||
fault.socket->address_profile.inbound == ADDRESS_IN_OPEN);
|
fault.socket->address_profile.inbound == ADDRESS_IN_UNKNOWN && status.reason == NAT_REASON_CONTACT_HISTORY);
|
||||||
fault.fixture = NULL; nat_fixture_cleanup(&fixture);
|
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");
|
DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS NAT budget pause retains mapping, rejects late ingress and retries the unfinished pair");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user