Browse Source

bugfixes

tmo
Evgeny 4 months ago
parent
commit
cff81a70da
  1. 17
      src/lwip_tcp/lwip_tcp.c
  2. 13
      src/lwip_tcp/lwip_tcp.h
  3. 8
      src/lwip_tcp/lwip_tcp_in.c
  4. 7
      src/lwip_tcp/lwip_tcp_opts.h
  5. 4
      src/lwip_tcp/lwip_tcp_priv.h

17
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);

13
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;
};

8
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);

7
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)

4
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)

Loading…
Cancel
Save