mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-16 23:15:37 +00:00
tcp: fix cwnd rollover introduced by ABC
Changes for TCP Appropriate Byte Counting introduce a potential cwnd rollover by not taking into account integer promotion on tcpwnd_size_t during inequality comparisions This fixes the issue by introducing a macro TCP_WND_INC which detects the rollover correctly and now holds the tcpwnd_size_t at the maximum value rather than not incrementing the window. This provides a slight performance improvement by allowing full use of the tcpwnd_size_t number space for the congestion window
This commit is contained in:
parent
0df2c4f2be
commit
3eaf976152
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user