Defer reachability probes while the first NAT ingress is protected
This commit is contained in:
1 parent
9324b8af8c
commit
9bd113054c
2 files changed
+39
No files matched your search
@@ -19,6 +19,7 @@
|
||||
#include "route_connectivity.h"
|
||||
#include "topo_node_sqlite.h"
|
||||
#include "sock_match.h"
|
||||
#include "nat_detection.h"
|
||||
#ifdef UTUN_HAVE_STANDBY
|
||||
#include "standby.h"
|
||||
#endif
|
||||
@@ -253,6 +254,24 @@ static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) {
|
||||
|
||||
// ---- public API ----
|
||||
|
||||
struct route_nat_defer {
|
||||
struct UTUN_INSTANCE *instance;
|
||||
struct TOPO_GROUP *group;
|
||||
struct TOPO_GROUP_NODE *node;
|
||||
void *timer;
|
||||
};
|
||||
|
||||
/* После NAT-окна запускает обычную проверку; удаление узла отменяет таймер и освобождает контекст. */
|
||||
static void route_nat_deferred_cb(void *arg) {
|
||||
struct route_nat_defer *deferred = arg;
|
||||
struct UTUN_INSTANCE *instance = deferred->instance;
|
||||
struct TOPO_GROUP *group = deferred->group;
|
||||
struct TOPO_GROUP_NODE *node = deferred->node;
|
||||
node->connectivity.nat_probe_wait = NULL; node->connectivity.probe_status = PROBE_STATUS_NONE;
|
||||
u_free(deferred);
|
||||
route_connectivity_probe_node(instance, group, node);
|
||||
}
|
||||
|
||||
#ifdef UTUN_HAVE_STANDBY
|
||||
/* Контекст пробы, отложенной до следующего активного интервала (standby_wait). */
|
||||
struct route_probe_defer {
|
||||
@@ -277,6 +296,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
|
||||
struct TOPO_NODE* ni = topo_node_registry_find(instance->topo_groups, nq->node_id);
|
||||
if (!ni) return;
|
||||
if (nq->node_id == instance->node_id) return; // не пингуем себя
|
||||
if (nq->connectivity.nat_probe_wait) return;
|
||||
/* Пир в SLEEP-фазе: прямое соединение живо, probe будит пира — пропускаем. */
|
||||
{
|
||||
struct ETCP_CONN* c = instance_find_conn(instance, nq->node_id);
|
||||
@@ -303,6 +323,19 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t nat_delay = nat_detection_probe_delay(instance->nat_det);
|
||||
if (nat_delay) {
|
||||
struct route_nat_defer *deferred = u_calloc(1, sizeof(*deferred));
|
||||
if (!deferred) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NAT probe defer allocation failed"); return; }
|
||||
deferred->instance = instance; deferred->group = group; deferred->node = nq;
|
||||
deferred->timer = uasync_set_timeout(instance->ua, nat_delay, deferred, route_nat_deferred_cb, "route_nat_defer");
|
||||
if (!deferred->timer) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NAT probe defer scheduling failed"); u_free(deferred); return; }
|
||||
nq->connectivity.nat_probe_wait = deferred; nq->connectivity.probe_status = PROBE_STATUS_DEFERRED;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "connectivity probe waits for initial NAT measurement node=%016llx delay_tb=%llu",
|
||||
(unsigned long long)nq->node_id, (unsigned long long)nat_delay);
|
||||
return;
|
||||
}
|
||||
|
||||
nq->connectivity.probe_status = PROBE_STATUS_IN_PROGRESS;
|
||||
nq->connectivity.probe_start_time = get_time_tb();
|
||||
nq->connectivity.interface_status = PROBE_RESULT_UNKNOWN;
|
||||
@@ -422,6 +455,11 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
|
||||
* хендла — они отсоединяются и освобождаются своим штатным ping_timeout/PONG. */
|
||||
static void conn_probe_cancel_nq(struct TOPO_GROUP_NODE* nq) {
|
||||
if (!nq) return;
|
||||
struct route_nat_defer *deferred = nq->connectivity.nat_probe_wait;
|
||||
if (deferred) {
|
||||
uasync_cancel_timeout(deferred->instance->ua, deferred->timer);
|
||||
nq->connectivity.nat_probe_wait = NULL; u_free(deferred);
|
||||
}
|
||||
#ifdef UTUN_HAVE_STANDBY
|
||||
{ struct route_probe_defer* d = (struct route_probe_defer*)nq->connectivity.probe_deferred_wait;
|
||||
if (d) {
|
||||
|
||||
@@ -100,6 +100,7 @@ struct TOPO_CONNECTIVITY {
|
||||
uint64_t last_ping_time;
|
||||
void* probe_list; // принадлежащие узлу контексты текущих проб
|
||||
void* probe_deferred_wait; /* контекст отложенной пробы (standby_wait, Android) */
|
||||
void* nat_probe_wait; /* контекст таймера: NAT сохраняет холодный ingress перед фоновыми ping */
|
||||
};
|
||||
|
||||
#define PING_TTL_TB (86400ULL * 10000ULL)
|
||||
|
||||
Reference in new issue
Block a user