diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 3c94763a..2305a3cb 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -1200,22 +1200,14 @@ tcp_receive(struct tcp_pcb *pcb) u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2; /* RFC 3465, section 2.2 Slow Start */ increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss)); - if (pcb->cwnd + increase > pcb->cwnd) { - pcb->cwnd += increase; - } + TCP_WND_INC(pcb->cwnd, increase); LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); } else { - tcpwnd_size_t new_cwnd = pcb->cwnd; /* RFC 3465, section 2.1 Congestion Avoidance */ - if (pcb->bytes_acked + acked > pcb->bytes_acked) { - pcb->bytes_acked += acked; - if (pcb->bytes_acked >= pcb->cwnd) { - pcb->bytes_acked -= pcb->cwnd; - new_cwnd = pcb->cwnd + pcb->mss; - } - } - if (new_cwnd > pcb->cwnd) { - pcb->cwnd = new_cwnd; + TCP_WND_INC(pcb->bytes_acked, acked); + if (pcb->bytes_acked >= pcb->cwnd) { + pcb->bytes_acked -= pcb->cwnd; + TCP_WND_INC(pcb->cwnd, pcb->mss); } LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); } diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index ad192390..e5e05693 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -143,6 +143,14 @@ typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); #define TCPWND16(x) (x) #define TCP_WND_MAX(pcb) TCP_WND #endif +/* Increments a tcpwnd_size_t and holds at max value rather than rollover */ +#define TCP_WND_INC(wnd, inc) do { \ + if ((tcpwnd_size_t)(wnd + inc) >= wnd) { \ + wnd += inc; \ + } else { \ + wnd = (tcpwnd_size_t)-1; \ + } \ + } while(0) #if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG || LWIP_TCP_TIMESTAMPS typedef u16_t tcpflags_t;