mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-11 08:54:38 +08: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;
|
u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2;
|
||||||
/* RFC 3465, section 2.2 Slow Start */
|
/* RFC 3465, section 2.2 Slow Start */
|
||||||
increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss));
|
increase = LWIP_MIN(acked, (tcpwnd_size_t)(num_seg * pcb->mss));
|
||||||
if (pcb->cwnd + increase > pcb->cwnd) {
|
TCP_WND_INC(pcb->cwnd, increase);
|
||||||
pcb->cwnd += increase;
|
|
||||||
}
|
|
||||||
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
|
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
|
||||||
} else {
|
} else {
|
||||||
tcpwnd_size_t new_cwnd = pcb->cwnd;
|
|
||||||
/* RFC 3465, section 2.1 Congestion Avoidance */
|
/* RFC 3465, section 2.1 Congestion Avoidance */
|
||||||
if (pcb->bytes_acked + acked > pcb->bytes_acked) {
|
TCP_WND_INC(pcb->bytes_acked, acked);
|
||||||
pcb->bytes_acked += acked;
|
if (pcb->bytes_acked >= pcb->cwnd) {
|
||||||
if (pcb->bytes_acked >= pcb->cwnd) {
|
pcb->bytes_acked -= pcb->cwnd;
|
||||||
pcb->bytes_acked -= pcb->cwnd;
|
TCP_WND_INC(pcb->cwnd, pcb->mss);
|
||||||
new_cwnd = pcb->cwnd + pcb->mss;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (new_cwnd > pcb->cwnd) {
|
|
||||||
pcb->cwnd = new_cwnd;
|
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd));
|
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 TCPWND16(x) (x)
|
||||||
#define TCP_WND_MAX(pcb) TCP_WND
|
#define TCP_WND_MAX(pcb) TCP_WND
|
||||||
#endif
|
#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
|
#if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG || LWIP_TCP_TIMESTAMPS
|
||||||
typedef u16_t tcpflags_t;
|
typedef u16_t tcpflags_t;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user