Browse Source

NAT: полное решение для отмены pending при падении conn

1. Добавлен via_conn в struct route_ping_pending - отслеживает через
   какое соединение (third_conn) отправлен запрос на ping
2. route_ping_cancel_for_conn теперь отменяет pending при падении ЛЮБОГО
   из двух conn: владельца линка (link->etcp) ИЛИ third_conn (via_conn)
3. nat_link_check_cb проверяет link->nat_check_status == IN_PROGRESS
   перед обработкой - защита от race condition когда conn упал раньше
   чем пришел ответ
4. Убраны избыточные DEBUG-логи, оставлены только информативные
congestion
Evgeny 5 months ago
parent
commit
04f02ffead
  1. 4
      src/etcp.c
  2. 19
      src/route_bgp.c
  3. 16
      src/route_ping.c

4
src/etcp.c

@ -216,14 +216,10 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
}
// Clear links list safely
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "connection_close: %s links=%p clearing_links",
etcp->log_name, (void*)etcp->links);
if (etcp->links) {
struct ETCP_LINK* link = etcp->links;
while (link) {
struct ETCP_LINK* next = link->next;
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "connection_close: closing link=%p nat_status=%d",
(void*)link, link->nat_check_status);
etcp_link_close(link);
link = next;
}

19
src/route_bgp.c

@ -384,19 +384,8 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
(unsigned long long)conn->peer_node_id);
// Cancel pending NAT checks for this connection's links
int link_count = 0;
struct ETCP_LINK* lnk = conn->links;
while (lnk) {
link_count++;
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "remove_conn: link=%p nat_status=%d",
(void*)lnk, lnk->nat_check_status);
lnk = lnk->next;
}
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "remove_conn: total links=%d for %s", link_count, conn->log_name);
route_ping_cancel_for_conn(bgp, conn);
lnk = conn->links;
struct ETCP_LINK* lnk = conn->links;
while (lnk) {
if (lnk->nat_check_status == NAT_CHECK_IN_PROGRESS) {
lnk->nat_check_status = NAT_CHECK_NONE;
@ -574,6 +563,12 @@ static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent,
struct nat_check_arg* na = (struct nat_check_arg*)arg;
if (!na || !na->link) { u_free(na); return; }
struct ETCP_LINK* link = na->link;
// Защита: если conn упал, статус уже сброшен в NONE
if (link->nat_check_status != NAT_CHECK_IN_PROGRESS) {
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "nat check cb: link status=%d, skip (conn down?)", link->nat_check_status);
u_free(na);
return;
}
uint8_t nat_type = success ? NAT_TYPE_OPEN : NAT_TYPE_RESTRICTED;
link->nat_type = nat_type;
link->nat_check_status = success ? NAT_CHECK_OPEN : NAT_CHECK_RESTRICTED;

16
src/route_ping.c

@ -42,6 +42,7 @@ struct route_ping_pending {
void* arg;
void* timeout_timer;
uint8_t cancelled;
struct ETCP_CONN* via_conn; // через кого отправили запрос (third_conn)
};
// если удаленный узел долго не отвечает - вызываем коллбэк по таймауту
@ -117,12 +118,12 @@ void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) {
struct route_ping_pending* p = *cur;
struct nat_check_arg* na = (struct nat_check_arg*)p->arg;
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, " checking pending req_id=%016llx arg=%p na=%p link=%p link->etcp=%s",
(unsigned long long)p->request_id, p->arg, na,
na ? na->link : NULL,
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, " checking pending req_id=%016llx via=%s link->etcp=%s",
(unsigned long long)p->request_id,
p->via_conn ? p->via_conn->log_name : "NULL",
(na && na->link && na->link->etcp) ? na->link->etcp->log_name : "NULL");
if (na && na->link && na->link->etcp == conn) {
if ((na && na->link && na->link->etcp == conn) || p->via_conn == conn) {
*cur = p->next;
if (p->timeout_timer) {
uasync_cancel_timeout(bgp->instance->ua, p->timeout_timer);
@ -200,15 +201,10 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn,
pending->request_id = req_pkt->request_id;
pending->callback = cb;
pending->arg = arg;
pending->via_conn = to_conn;
pending->next = bgp->ping_pending;
bgp->ping_pending = pending;
struct nat_check_arg* na_dbg = (struct nat_check_arg*)arg;
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "pending created req_id=%016llx arg=%p link=%p link->etcp=%s",
(unsigned long long)pending->request_id, pending->arg,
na_dbg ? na_dbg->link : NULL,
(na_dbg && na_dbg->link && na_dbg->link->etcp) ? na_dbg->link->etcp->log_name : "NULL");
pending->timeout_timer = uasync_set_timeout(bgp->instance->ua, wait_timeout_ms * 10, pending, route_ping_pending_timeout, "route_ping");
DEBUG_INFO(DEBUG_CATEGORY_BGP, "request_id=%016llx ip=%s port=%u pubkey=%s",

Loading…
Cancel
Save