Browse Source

Try controlled ingress before asking the broker for helper mapping

master
evgeny 6 days ago
parent
commit
9a24ac6bdf
  1. 23
      src/routing_layer/nat_detection.c

23
src/routing_layer/nat_detection.c

@ -679,7 +679,8 @@ void nat_detection_receive_ingress(struct NAT_DETECTION *detector, struct ETCP_S
DEBUG_DEBUG(DEBUG_CATEGORY_NAT, "NAT ingress ignored without pending endpoint/valid tag length=%zu", length); return;
}
uint8_t expected[ROUTE_OBSERVE_TAG_SIZE]; route_ping_make_tag(expected, socket, state->group_id, state->round);
uint8_t step = state->phase == NAT_PRE ? NAT_STEP_PRE : state->phase == NAT_POST ? NAT_STEP_POST : 0;
uint8_t step = state->phase == NAT_PREPARE_C ? NAT_STEP_PREPARE : state->phase == NAT_PRE ? NAT_STEP_PRE :
state->phase == NAT_POST ? NAT_STEP_POST : 0;
if (!step || memcmp(tag, expected, sizeof(expected)) || tag[ROUTE_OBSERVE_TAG_SIZE] != step ||
read64(tag + ROUTE_OBSERVE_TAG_SIZE + 1) != state->token ||
sc_derive_node_id_from_pubkey(peer_key) != state->helper || memcmp(peer_key, state->helper_key, 32) ||
@ -689,7 +690,7 @@ void nat_detection_receive_ingress(struct NAT_DETECTION *detector, struct ETCP_S
DEBUG_WARN(DEBUG_CATEGORY_NAT, "NAT ingress correlation/source mismatch socket=%s phase=%u round=%016llx source=%s",
socket->name, state->phase, (unsigned long long)state->round, sockaddr_storage_to_str(source).str); return;
}
if (step == NAT_STEP_PRE) {
if (step == NAT_STEP_PRE || step == NAT_STEP_PREPARE) {
if (!state->pre_received) { state->filter_clean = !contacted(state, source); state->helper_address = *source; }
state->pre_received = 1;
}
@ -756,7 +757,7 @@ static void helper_ping_cb(int success, uint16_t rtt, void *arg, uint64_t nonce,
if (probe->cancelled) return;
probe->active = 0; probe->tcp = NULL;
uint8_t step = probe->message.step;
if (step == NAT_STEP_PREPARE || step == NAT_STEP_ALT) {
if (step == NAT_STEP_ALT || (step == NAT_STEP_PREPARE && probe->alternate_fallback)) {
struct ETCP_SOCKET *socket = find_socket(probe->detector, probe->io_socket, probe->io_generation);
struct sockaddr_storage mapped;
if (success && socket && !route_ping_observation(data, length, socket, probe->group_id,
@ -791,6 +792,12 @@ static void helper_ping_cb(int success, uint16_t rtt, void *arg, uint64_t nonce,
helper_finish(probe, NAT_REASON_INVALID_OBSERVATION); return;
}
probe->message.received++;
if (step == NAT_STEP_PREPARE) { helper_finish(probe, NAT_REASON_NONE); return; }
}
if (step == NAT_STEP_PREPARE && probe->message.sent >= NAT_PROBE_COUNT) {
probe->alternate_fallback = 1; probe->message.sent = 0;
DEBUG_DEBUG(DEBUG_CATEGORY_NAT, "NAT first ingress blocked; discover helper mapping through broker group=%016llx owner=%016llx",
(unsigned long long)probe->group_id, (unsigned long long)read64(probe->message.owner));
}
if (probe->message.sent >= NAT_PROBE_COUNT) { helper_finish(probe, NAT_REASON_NONE); return; }
}
@ -811,7 +818,7 @@ static int helper_send(struct nat_probe *probe) {
if (parameters) { topo_node_reality_config(&reality, parameters); camouflage = &reality; }
result = etcp_send_tcp_ping(detector->instance, probe->owner_key, &target, timeout,
helper_ping_cb, probe, &probe->tcp, camouflage);
} else if (probe->message.step == NAT_STEP_PREPARE || probe->message.step == NAT_STEP_ALT) {
} else if (probe->message.step == NAT_STEP_ALT || (probe->message.step == NAT_STEP_PREPARE && probe->alternate_fallback)) {
struct ETCP_SOCKET *source = find_socket(detector, probe->source_socket, probe->source_generation);
if (!source) { DEBUG_WARN(DEBUG_CATEGORY_NAT, "NAT helper source generation disappeared"); return -1; }
struct ETCP_SOCKET *socket = helper_socket(detector, source, probe->message.step == NAT_STEP_ALT);
@ -954,7 +961,8 @@ static void handle_result(struct nat_socket *state, const struct nat_wire *messa
struct sockaddr_storage primary;
if (route_ping_addr_decode(message->primary, &primary) || primary.ss_family != state->local.ss_family ||
!public_address(state->detector, &primary)) { owner_finish(state, NAT_REASON_INVALID_OBSERVATION); return; }
int same_ip = route_ping_addr_equal(&state->observer_address, &primary, 0), old_contact = contacted(state, &primary);
int same_ip = route_ping_addr_equal(&state->observer_address, &primary, 0);
int old_contact = state->pre_received ? !state->filter_clean : contacted(state, &primary);
if (same_ip || (old_contact && !state->using_fallback)) {
if (!same_ip && !state->fallback.group) state->fallback = (struct nat_pair){state->group_id, state->observer, state->helper};
DEBUG_INFO(DEBUG_CATEGORY_NAT, "NAT try another pair socket=%s group=%016llx helper=%016llx endpoint=%s reason=%s",
@ -963,6 +971,11 @@ static void handle_result(struct nat_socket *state, const struct nat_wire *messa
owner_finish(state, same_ip ? NAT_REASON_NO_HELPER : NAT_REASON_CONTACT_HISTORY); return;
}
state->helper_address = primary; state->filter_clean = !old_contact;
if (state->pre_received) {
state->phase = NAT_OBSERVE_C;
if (owner_observe(state)) owner_finish(state, NAT_REASON_SEND_ERROR);
return;
}
if (owner_run(state, NAT_STEP_PRE)) owner_finish(state, NAT_REASON_CONTROL_LOST);
return;
}

Loading…
Cancel
Save