From a44e2190d60d177fd5626cebcdebd5a9e3e1c35d Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Fri, 7 Feb 2014 11:32:02 +0100 Subject: [PATCH] TCP window scaling: change tcp_pcb::acked to u32_t when window scaling is enabled to prevent an overflow when more than 64 Kbytes are ACKed --- src/core/tcp_in.c | 24 +++++++++++++++++++----- src/include/lwip/tcp.h | 2 +- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 07d881a1..115cfb00 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -345,9 +345,22 @@ tcp_input(struct pbuf *p, struct netif *inp) called when new send buffer space is available, we call it now. */ if (pcb->acked > 0) { - TCP_EVENT_SENT(pcb, pcb->acked, err); - if (err == ERR_ABRT) { - goto aborted; + u16_t acked; +#if LWIP_WND_SCALE + /* pcb->acked is u32_t but the sent callback only takes a u16_t, + so we might have to call it multiple timess. */ + u32_t pcb_acked = pcb->acked; + while(pcb_acked > 0) { + acked = (u16_t)LWIP_MIN(pcb_acked, 0xffffu); + pcb_acked -= acked; +#else + { + acked = pcb->acked; +#endif + TCP_EVENT_SENT(pcb, (u16_t)acked, err); + if (err == ERR_ABRT) { + goto aborted; + } } } @@ -991,8 +1004,9 @@ tcp_receive(struct tcp_pcb *pcb) /* Reset the retransmission time-out. */ pcb->rto = (pcb->sa >> 3) + pcb->sv; - /* Update the send buffer space. Diff between the two can never exceed 64K? */ - pcb->acked = (u16_t)(ackno - pcb->lastack); + /* Update the send buffer space. Diff between the two can never exceed 64K + unless window scaling is used. */ + pcb->acked = (tcpwnd_size_t)(ackno - pcb->lastack); pcb->snd_buf += pcb->acked; diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index 4b1237eb..c2c0f111 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -244,7 +244,7 @@ struct tcp_pcb { tcpwnd_size_t snd_wnd; /* sender window */ tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ - u16_t acked; + tcpwnd_size_t acked; tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)