From cff81a70daa9ddec6517e4dd41e85d1ea842476b Mon Sep 17 00:00:00 2001 From: Evgeny Date: Tue, 9 Jun 2026 01:54:06 +0300 Subject: [PATCH] bugfixes --- src/lwip_tcp/lwip_tcp.c | 17 +++++++---------- src/lwip_tcp/lwip_tcp.h | 13 ------------- src/lwip_tcp/lwip_tcp_in.c | 8 ++------ src/lwip_tcp/lwip_tcp_opts.h | 7 ++++--- src/lwip_tcp/lwip_tcp_priv.h | 4 +--- 5 files changed, 14 insertions(+), 35 deletions(-) diff --git a/src/lwip_tcp/lwip_tcp.c b/src/lwip_tcp/lwip_tcp.c index 8d28a8c6..723a56c5 100644 --- a/src/lwip_tcp/lwip_tcp.c +++ b/src/lwip_tcp/lwip_tcp.c @@ -103,7 +103,7 @@ struct lwip_tcp_ctx *lwip_tcp_init(struct UASYNC *ua, tcp_output_fn output, void return NULL; } ctx->iss_seed = (uint16_t)(get_time_tb() & 0xFFFF); - ctx->tmr_interval_ms = TCP_TMR_INTERVAL; + ctx->tmr_interval_ms = TCP_TMR_INTERVAL / 4; ctx->rto_min_ms = 3000; ctx->rto_max_ms = 0; ctx->timer = uasync_set_timeout(ua, ctx->tmr_interval_ms * 10, ctx, tcp_tmr_cb, "lwip_tcp_tmr"); @@ -749,7 +749,6 @@ void tcp_slowtmr(struct lwip_tcp_ctx *ctx) tcp_pcb_purge(pcb); if (prev != NULL) { prev->next = pcb->next; - prev->next_owner = PCB_NEXT_SLOWTMR; } else { ctx->active_pcbs = pcb->next; } @@ -808,18 +807,16 @@ void tcp_slowtmr(struct lwip_tcp_ctx *ctx) tcp_pcb_purge(pcb); if (prev != NULL) { prev->next = pcb->next; - prev->next_owner = PCB_NEXT_SLOWTMR; } else { ctx->tw_pcbs = pcb->next; } 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); + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS SELF-LOOP in tcp_slowtmr: freed pcb=%p state=TIME_WAIT port=%u, clearing tw_pcbs", + (void*)pcb2, pcb2->local_port); ctx->tw_pcbs = NULL; break; } @@ -1050,8 +1047,8 @@ static void tcp_kill_timewait(struct lwip_tcp_ctx *ctx) } 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); + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS SELF-LOOP in tcp_kill_timewait: aborting pcb=%p, clearing tw_pcbs", + (void*)inactive); ctx->tw_pcbs = NULL; tcp_free(inactive); } else { @@ -1115,8 +1112,8 @@ struct tcp_pcb *tcp_alloc(struct lwip_tcp_ctx *ctx, uint8_t prio) pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND16(TCP_WND); pcb->ttl = 64; pcb->mss = INITIAL_MSS; - pcb->rto = (int16_t)(ctx->rto_min_ms / TCP_SLOW_INTERVAL); - pcb->sv = (int16_t)(ctx->rto_min_ms / TCP_SLOW_INTERVAL); + pcb->rto = (int16_t)(TCP_RTO_MIN_MS / TCP_SLOW_INTERVAL); + pcb->sv = (int16_t)(TCP_RTO_MIN_MS / TCP_SLOW_INTERVAL); pcb->rtime = -1; pcb->cwnd = 1; DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "tcp_alloc: cwnd=%u snd_buf=%u mss=%u snd_wnd=%u", pcb->cwnd, pcb->snd_buf, pcb->mss, pcb->snd_wnd); diff --git a/src/lwip_tcp/lwip_tcp.h b/src/lwip_tcp/lwip_tcp.h index 0fa4ccae..d3058d77 100644 --- a/src/lwip_tcp/lwip_tcp.h +++ b/src/lwip_tcp/lwip_tcp.h @@ -67,15 +67,6 @@ enum tcp_err_enum { LERR_CLSD = -15, LERR_ARG = -16 }; - -// кто последним записал pcb->next (диагностика зацикливания tw_pcbs) -enum pcb_next_owner { - PCB_NEXT_NONE = 0, - PCB_NEXT_REG = 1, - PCB_NEXT_RMV = 2, - PCB_NEXT_SLOWTMR = 3, - PCB_NEXT_INPUT = 4, -}; typedef int err_t; // Forward declaration for callbacks @@ -175,9 +166,6 @@ struct tcp_pcb { tcp_connected_fn connected; tcp_poll_fn poll; tcp_err_fn errf; - - uint8_t next_owner; // who last wrote pcb->next (enum pcb_next_owner) - uint32_t keep_idle; uint8_t persist_cnt; uint8_t persist_backoff; @@ -193,7 +181,6 @@ struct tcp_pcb_listen { uint8_t prio; uint16_t local_port; uint32_t local_ip; - uint8_t next_owner; tcp_accept_fn accept; }; diff --git a/src/lwip_tcp/lwip_tcp_in.c b/src/lwip_tcp/lwip_tcp_in.c index 9b1cbdf9..d7d214f5 100644 --- a/src/lwip_tcp/lwip_tcp_in.c +++ b/src/lwip_tcp/lwip_tcp_in.c @@ -198,9 +198,7 @@ void lwip_tcp_input(struct lwip_tcp_ctx *ctx, struct pbuf *p, pcb->local_ip == dst_ip) { if (prev != NULL) { prev->next = pcb->next; - prev->next_owner = PCB_NEXT_INPUT; pcb->next = ctx->active_pcbs; - pcb->next_owner = PCB_NEXT_INPUT; ctx->active_pcbs = pcb; } break; @@ -225,8 +223,8 @@ void lwip_tcp_input(struct lwip_tcp_ctx *ctx, struct pbuf *p, pcb->remote_ip == src_ip && pcb->local_ip == dst_ip) { 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); + DEBUG_ERROR(DEBUG_CATEGORY_ALL, "TW_PCBS SELF-LOOP in lwip_tcp_input: pcb=%p sport=%u dport=%u, aborting", + (void*)pcb, sport, dport); tcp_abort(pcb); } else { tcp_timewait_input(pcb); @@ -249,9 +247,7 @@ void lwip_tcp_input(struct lwip_tcp_ctx *ctx, struct pbuf *p, if (lpcb != NULL) { if (prev != NULL) { ((struct tcp_pcb_listen *)prev)->next = lpcb->next; - ((struct tcp_pcb_listen *)prev)->next_owner = PCB_NEXT_INPUT; lpcb->next = ctx->listen_pcbs; - lpcb->next_owner = PCB_NEXT_INPUT; ctx->listen_pcbs = (struct tcp_pcb *)lpcb; } tcp_listen_input(lpcb); diff --git a/src/lwip_tcp/lwip_tcp_opts.h b/src/lwip_tcp/lwip_tcp_opts.h index 28cfbf11..4c5f5b59 100644 --- a/src/lwip_tcp/lwip_tcp_opts.h +++ b/src/lwip_tcp/lwip_tcp_opts.h @@ -14,9 +14,10 @@ #define TCP_FAST_INTERVAL TCP_TMR_INTERVAL #define TCP_SLOW_INTERVAL (2 * TCP_TMR_INTERVAL) -#define TCP_FIN_WAIT_TIMEOUT 6000 // ms -#define TCP_SYN_RCVD_TIMEOUT 6000 // ms -#define TCP_MSL 25000 // ms (2*MSL = 50s) +#define TCP_RTO_MIN_MS 3000 // ms, initial RTO +#define TCP_FIN_WAIT_TIMEOUT 20000 // ms +#define TCP_SYN_RCVD_TIMEOUT 20000 // ms +#define TCP_MSL 60000 // ms (2*MSL = 120s) #define TCP_OOSEQ_TIMEOUT 6 // x RTO #define TCP_KEEPIDLE_DEFAULT 7200000 // ms (unused, no keepalive) diff --git a/src/lwip_tcp/lwip_tcp_priv.h b/src/lwip_tcp/lwip_tcp_priv.h index 882a030f..6a12f045 100644 --- a/src/lwip_tcp/lwip_tcp_priv.h +++ b/src/lwip_tcp/lwip_tcp_priv.h @@ -236,15 +236,13 @@ void lwip_tcp_stats_clear(struct lwip_tcp_ctx *ctx); // PCB list management #define TCP_REG(pcbs, npcb) do { \ - (npcb)->next_owner = PCB_NEXT_REG; \ (npcb)->next = *(pcbs); *(pcbs) = (npcb); \ } while(0) #define TCP_RMV(pcbs, npcb) do { \ if(*(pcbs) == (npcb)) { *(pcbs) = (*pcbs)->next; } \ - else { struct tcp_pcb *_tmp; for(_tmp = *(pcbs); _tmp != NULL; _tmp = _tmp->next) { if(_tmp->next == (npcb)) { _tmp->next_owner = PCB_NEXT_SLOWTMR; _tmp->next = (npcb)->next; break; } } } \ + else { struct tcp_pcb *_tmp; for(_tmp = *(pcbs); _tmp != NULL; _tmp = _tmp->next) { if(_tmp->next == (npcb)) { _tmp->next = (npcb)->next; break; } } } \ (npcb)->next = NULL; \ - (npcb)->next_owner = PCB_NEXT_RMV; \ } while(0) #define TCP_REG_ACTIVE(ctx, npcb) TCP_REG(&(ctx)->active_pcbs, npcb)