Give initial NAT measurements bounded priority without opening filters
This commit is contained in:
1 parent
585834ffbe
commit
9324b8af8c
2 files changed
+53
-2
No files matched your search
@@ -1153,6 +1153,54 @@ static uint64_t candidate_fingerprint(struct nat_socket *state, int ready) {
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ограниченное окно сохраняет свежие IP для первого ingress; изменение доступных endpoint обновляет резерв один раз. */
|
||||||
|
uint64_t nat_detection_probe_delay(struct NAT_DETECTION *detector) {
|
||||||
|
if (!detector || detector->stopping) return 0;
|
||||||
|
uint64_t now = get_time_tb(), delay = 0;
|
||||||
|
if (detector->reservation_dirty) {
|
||||||
|
detector->reservation_dirty = 0;
|
||||||
|
for (struct ETCP_SOCKET *socket = detector->instance->etcp_sockets; socket; socket = socket->next) {
|
||||||
|
if (socket->is_tcp || socket->probe_only || socket->socks_udp ||
|
||||||
|
socket->type == CFG_SERVER_TYPE_PRIVATE || socket->type == CFG_SERVER_TYPE_LOCAL) continue;
|
||||||
|
struct nat_socket *state = socket_state(detector, socket, 1);
|
||||||
|
if (!state) continue;
|
||||||
|
uint64_t fingerprint = candidate_fingerprint(state, 0);
|
||||||
|
if (fingerprint != state->reservation_fingerprint) {
|
||||||
|
state->reservation_fingerprint = fingerprint;
|
||||||
|
if (fingerprint) state->cold_until = now + NAT_ROUND_TB + 2500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (struct nat_socket *state = detector->sockets; state; state = state->next) {
|
||||||
|
if (state->socket->is_tcp || !state->reservation_fingerprint || state->cold_until <= now ||
|
||||||
|
(!detector->automatic && !state->phase && !state->forced) ||
|
||||||
|
(state->measured_profile.source == ADDRESS_SOURCE_ETCP && state->measured_profile.mapping && state->measured_profile.inbound))
|
||||||
|
continue;
|
||||||
|
if (state->cold_until - now > delay) delay = state->cold_until - now;
|
||||||
|
}
|
||||||
|
return delay > 10000 ? 10000 : delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nat_detection_observe_allowed(struct NAT_DETECTION *detector, struct ETCP_SOCKET *socket,
|
||||||
|
const uint8_t peer_key[32], const uint8_t *tag, size_t length) {
|
||||||
|
if (!detector || !socket || socket->probe_only || !tag || length != ROUTE_OBSERVE_TAG_SIZE || memcmp(tag, "NAT3UDP!", 8)) return 1;
|
||||||
|
nat_detection_probe_delay(detector);
|
||||||
|
struct nat_socket *state = socket_state(detector, socket, 0);
|
||||||
|
if (!state || !state->reservation_fingerprint || state->cold_until <= get_time_tb() ||
|
||||||
|
(!detector->automatic && !state->phase && !state->forced) ||
|
||||||
|
(state->measured_profile.source == ADDRESS_SOURCE_ETCP && state->measured_profile.mapping && state->measured_profile.inbound)) return 1;
|
||||||
|
uint64_t peer = sc_derive_node_id_from_pubkey(peer_key), group_id = read64(tag + 25), round = read64(tag + 17), owner = peer;
|
||||||
|
if (state->phase && state->group_id == group_id && state->round == round && (state->helper == peer || state->observer == peer)) return 1;
|
||||||
|
for (struct nat_binding *binding = detector->bindings; binding; binding = binding->next)
|
||||||
|
if (binding->group_id == group_id && binding->round == round && binding->helper == peer && binding->expires > get_time_tb()) {
|
||||||
|
owner = binding->owner; break;
|
||||||
|
}
|
||||||
|
if (owner <= detector->instance->node_id) return 1;
|
||||||
|
DEBUG_DEBUG(DEBUG_CATEGORY_NAT, "NAT observation deferred for cold owner priority socket=%s group=%016llx requester=%016llx owner=%016llx",
|
||||||
|
socket->name, (unsigned long long)group_id, (unsigned long long)peer, (unsigned long long)owner);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Изменения нескольких групп объединяются; известный полный ETCP-профиль не перепроверяется из-за нового соседа. */
|
/* Изменения нескольких групп объединяются; известный полный ETCP-профиль не перепроверяется из-за нового соседа. */
|
||||||
static void topology_wake(void *arg) {
|
static void topology_wake(void *arg) {
|
||||||
struct NAT_DETECTION *detector = arg; detector->topology_wake = NULL;
|
struct NAT_DETECTION *detector = arg; detector->topology_wake = NULL;
|
||||||
@@ -1276,7 +1324,7 @@ struct NAT_DETECTION *nat_detection_create(struct UTUN_INSTANCE *instance) {
|
|||||||
}
|
}
|
||||||
struct NAT_DETECTION *detector = u_calloc(1, sizeof(*detector));
|
struct NAT_DETECTION *detector = u_calloc(1, sizeof(*detector));
|
||||||
if (!detector) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "NAT detector allocation failed"); return NULL; }
|
if (!detector) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "NAT detector allocation failed"); return NULL; }
|
||||||
detector->instance = instance; detector->automatic = 1;
|
detector->instance = instance; detector->automatic = 1; detector->reservation_dirty = 1;
|
||||||
if (etcp_router_bind(instance, ETCP_RT_ID_NAT_DETECTION, receive_control)) { u_free(detector); return NULL; }
|
if (etcp_router_bind(instance, ETCP_RT_ID_NAT_DETECTION, receive_control)) { u_free(detector); return NULL; }
|
||||||
etcp_add_conn_status_cbk(instance, connection_status, detector);
|
etcp_add_conn_status_cbk(instance, connection_status, detector);
|
||||||
etcp_add_socket_cbk(instance, socket_changed, detector, ETCP_SOCKET_EVENT_ADDR_CHANGED);
|
etcp_add_socket_cbk(instance, socket_changed, detector, ETCP_SOCKET_EVENT_ADDR_CHANGED);
|
||||||
@@ -1345,6 +1393,7 @@ void nat_detection_set_allow_local(struct NAT_DETECTION *detector, int allow) {
|
|||||||
void nat_detection_set_automatic(struct NAT_DETECTION *detector, int automatic) {
|
void nat_detection_set_automatic(struct NAT_DETECTION *detector, int automatic) {
|
||||||
if (!detector) return;
|
if (!detector) return;
|
||||||
detector->automatic = !!automatic;
|
detector->automatic = !!automatic;
|
||||||
|
detector->reservation_dirty = 1;
|
||||||
DEBUG_INFO(DEBUG_CATEGORY_NAT, "NAT automatic endpoint measurements %s", automatic ? "enabled" : "disabled");
|
DEBUG_INFO(DEBUG_CATEGORY_NAT, "NAT automatic endpoint measurements %s", automatic ? "enabled" : "disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1796,8 +1796,10 @@ static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
|
|||||||
if ((flags & ETCP_PING_FLAG_OBSERVE) && (flags & ETCP_PING_FLAG_ADDRESS_CHECK)) {
|
if ((flags & ETCP_PING_FLAG_OBSERVE) && (flags & ETCP_PING_FLAG_ADDRESS_CHECK)) {
|
||||||
DEBUG_WARN(DEBUG_CATEGORY_NAT, "UDP probe has incompatible flags=%02x", flags); return 7;
|
DEBUG_WARN(DEBUG_CATEGORY_NAT, "UDP probe has incompatible flags=%02x", flags); return 7;
|
||||||
}
|
}
|
||||||
if ((flags & ETCP_PING_FLAG_OBSERVE) && e_sock->instance->nat_det)
|
if ((flags & ETCP_PING_FLAG_OBSERVE) && e_sock->instance->nat_det) {
|
||||||
|
if (!nat_detection_observe_allowed(e_sock->instance->nat_det, e_sock, decrypted_pubkey, udata, ulen)) return 0;
|
||||||
nat_detection_record_observation(e_sock->instance->nat_det, e_sock, decrypted_pubkey, addr, udata, ulen);
|
nat_detection_record_observation(e_sock->instance->nat_det, e_sock, decrypted_pubkey, addr, udata, ulen);
|
||||||
|
}
|
||||||
if ((flags & ETCP_PING_FLAG_ADDRESS_CHECK) && e_sock->instance->nat_det)
|
if ((flags & ETCP_PING_FLAG_ADDRESS_CHECK) && e_sock->instance->nat_det)
|
||||||
nat_detection_receive_ingress(e_sock->instance->nat_det, e_sock, decrypted_pubkey, addr, udata, ulen);
|
nat_detection_receive_ingress(e_sock->instance->nat_det, e_sock, decrypted_pubkey, addr, udata, ulen);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user