From a09c647dfd283a190f53317d4ec92784ab8519b6 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Fri, 5 Jun 2026 18:15:43 +0300 Subject: [PATCH] =?UTF-8?q?lwip=5Ftcp:=20=D0=B4=D0=B5=D1=82=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=20=D0=B8=20=D0=B7=D0=B0=D1=89=D0=B8=D1=82=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=82=20self-loop=20(pcb->next=3D=3Dpcb)=20=D0=B2=20tw=5Fpcbs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tcp_slowtmr: после tcp_free проверка pcb==pcb2 → ctx->tw_pcbs=NULL, break tcp_kill_timewait: проверка inactive->next==inactive → ctx->tw_pcbs=NULL, tcp_free lwip_tcp_input: проверка pcb->next==pcb перед tcp_timewait_input → tcp_abort все 3 лога выводят next_owner для диагностики источника self-ссылки --- src/lwip_tcp/lwip_tcp.c | 19 ++++++++++++++++++- src/lwip_tcp/lwip_tcp_in.c | 8 +++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/lwip_tcp/lwip_tcp.c b/src/lwip_tcp/lwip_tcp.c index 8f9bbca0..7e99488c 100644 --- a/src/lwip_tcp/lwip_tcp.c +++ b/src/lwip_tcp/lwip_tcp.c @@ -812,7 +812,15 @@ void tcp_slowtmr(struct lwip_tcp_ctx *ctx) } pcb2 = pcb; pcb = pcb->next; + int self_loop = (pcb == pcb2); + uint8_t sl_owner = pcb2->next_owner; tcp_free(pcb2); + if (self_loop) { + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS SELF-LOOP in tcp_slowtmr: freed pcb=%p state=TIME_WAIT port=%u next_owner=%d, clearing tw_pcbs", + (void*)pcb2, pcb2->local_port, sl_owner); + ctx->tw_pcbs = NULL; + break; + } } else { prev = pcb; pcb = pcb->next; @@ -1036,7 +1044,16 @@ static void tcp_kill_timewait(struct lwip_tcp_ctx *ctx) inactive = pcb; } } - if (inactive != NULL) tcp_abort(inactive); + if (inactive != NULL) { + if (inactive->next == inactive) { + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS SELF-LOOP in tcp_kill_timewait: aborting pcb=%p next_owner=%d, clearing tw_pcbs", + (void*)inactive, inactive->next_owner); + ctx->tw_pcbs = NULL; + tcp_free(inactive); + } else { + tcp_abort(inactive); + } + } } static void tcp_handle_closepend(struct lwip_tcp_ctx *ctx) diff --git a/src/lwip_tcp/lwip_tcp_in.c b/src/lwip_tcp/lwip_tcp_in.c index 044254b9..80b104df 100644 --- a/src/lwip_tcp/lwip_tcp_in.c +++ b/src/lwip_tcp/lwip_tcp_in.c @@ -221,7 +221,13 @@ void lwip_tcp_input(struct lwip_tcp_ctx *ctx, struct pbuf *p, pcb->local_port == dport && pcb->remote_ip == src_ip && pcb->local_ip == dst_ip) { - tcp_timewait_input(pcb); + if (pcb->next == pcb) { + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS SELF-LOOP in lwip_tcp_input: pcb=%p sport=%u dport=%u next_owner=%d, aborting", + (void*)pcb, sport, dport, pcb->next_owner); + tcp_abort(pcb); + } else { + tcp_timewait_input(pcb); + } pbuf_free(p); return; }