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:
Joel Cunningham
2017-06-01 12:31:17 -05:00
parent 0df2c4f2be
commit 3eaf976152
2 changed files with 13 additions and 13 deletions

View File

@@ -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));
}