diff --git a/src/route_bgp.c b/src/route_bgp.c index 57847900..31eae0b2 100644 --- a/src/route_bgp.c +++ b/src/route_bgp.c @@ -383,6 +383,16 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: peer=%016llx", (unsigned long long)conn->peer_node_id); + // Cancel pending NAT checks for this connection's links + route_ping_cancel_for_conn(bgp, conn); + struct ETCP_LINK* lnk = conn->links; + while (lnk) { + if (lnk->nat_check_status == NAT_CHECK_IN_PROGRESS) { + lnk->nat_check_status = NAT_CHECK_NONE; + } + lnk = lnk->next; + } + struct ROUTE_TABLE* rt = conn->instance->rt; // Remove this connection from all nodes' path lists @@ -547,12 +557,6 @@ int nodeinfo_dyn_size(struct NODEINFO* node) { } // NAT check context -struct nat_check_arg { - struct ETCP_LINK* link; - uint32_t nat_ip; - uint16_t nat_port; -}; - static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent, uint8_t count_ok, void* arg) { (void)avg_rtt; (void)count_sent; (void)count_ok; diff --git a/src/route_bgp.h b/src/route_bgp.h index 1a10b058..ecd205fe 100644 --- a/src/route_bgp.h +++ b/src/route_bgp.h @@ -200,4 +200,11 @@ void route_bgp_set_nat_check_local(struct ROUTE_BGP* bgp, int allow); */ void route_bgp_request_nat_check_all(struct ROUTE_BGP* bgp); +/* Аргумент callback NAT check */ +struct nat_check_arg { + struct ETCP_LINK* link; + uint32_t nat_ip; + uint16_t nat_port; +}; + #endif // ROUTE_BGP_H diff --git a/src/route_ping.c b/src/route_ping.c index ec5b1f3f..0bf8319e 100644 --- a/src/route_ping.c +++ b/src/route_ping.c @@ -17,6 +17,7 @@ #include "route_node.h" #include "route_bgp.h" #include "route_ping.h" +#include "../lib/u_async.h" struct route_ping_series_ctx { struct ETCP_CONN* reply_conn; @@ -100,6 +101,33 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, (unsigned long long)resp->request_id); } +void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { + if (!bgp || !conn) return; + struct route_ping_pending** cur = &bgp->ping_pending; + int cancelled = 0; + while (*cur) { + struct route_ping_pending* p = *cur; + struct nat_check_arg* na = (struct nat_check_arg*)p->arg; + if (na && na->link && na->link->conn == conn) { + *cur = p->next; + if (p->timeout_timer) { + uasync_cancel_timeout(bgp->instance->ua, p->timeout_timer); + p->timeout_timer = NULL; + } + p->cancelled = 1; + na->link = NULL; + u_free(p); + cancelled++; + } else { + cur = &(*cur)->next; + } + } + if (cancelled > 0) { + DEBUG_INFO(DEBUG_CATEGORY_BGP, "Cancelled %d pending NAT checks for conn %s", + cancelled, conn->log_name); + } +} + // ======================================================================== int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, diff --git a/src/route_ping.h b/src/route_ping.h index 380e9ccb..758ad886 100644 --- a/src/route_ping.h +++ b/src/route_ping.h @@ -44,6 +44,9 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, // Очистить список ожидающих запросов (при уничтожении BGP) void route_ping_destroy_pending(struct ROUTE_BGP* bgp); +// Отменить pending запросы для указанного соединения (при удалении conn) +void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); + // Обработчики, вызываемые из route_bgp_receive_cbk void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);