diff --git a/CHANGELOG b/CHANGELOG index de4000f8..371a97b7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -249,6 +249,11 @@ HISTORY ++ Bugfixes: + 2015-08-28: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #44023: TCP ssthresh value is unclear: ssthresh + is set to the full send window for active open, too, and is updated once + after SYN to ensure the correct send window is used + 2015-08-28: Simon Goldschmidt * tcp: fixed bug #45559: Window scaling casts u32_t to u16_t without checks diff --git a/src/core/tcp.c b/src/core/tcp.c index eff39917..6edab081 100644 --- a/src/core/tcp.c +++ b/src/core/tcp.c @@ -834,7 +834,7 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, PCB_ISIPV6(pcb)); #endif /* TCP_CALCULATE_EFF_SEND_MSS */ pcb->cwnd = 1; - pcb->ssthresh = pcb->mss * 10; + pcb->ssthresh = TCP_WND; #if LWIP_CALLBACK_API pcb->connected = connected; #else /* LWIP_CALLBACK_API */ diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c index 19671281..49615515 100644 --- a/src/core/tcp_in.c +++ b/src/core/tcp_in.c @@ -61,7 +61,10 @@ #include "lwip/nd6.h" #endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ +/** Initial CWND calculation as defined RFC 2581 */ #define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)); +/** Initial slow start threshold value: we use the full window */ +#define LWIP_TCP_INITIAL_SSTHRESH(pcb) ((pcb)->snd_wnd) /* These variables are global to all functions involved in the input processing of TCP segments. They are set by the tcp_input() @@ -592,7 +595,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) tcp_parseopt(npcb); npcb->snd_wnd = SND_WND_SCALE(npcb, tcphdr->wnd); npcb->snd_wnd_max = npcb->snd_wnd; - npcb->ssthresh = npcb->snd_wnd; + npcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(npcb); #if TCP_CALCULATE_EFF_SEND_MSS npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, @@ -741,9 +744,8 @@ tcp_process(struct tcp_pcb *pcb) PCB_ISIPV6(pcb)); #endif /* TCP_CALCULATE_EFF_SEND_MSS */ - /* Set ssthresh again after changing pcb->mss (already set in tcp_connect - * but for the default value of pcb->mss) */ - pcb->ssthresh = pcb->mss * 10; + /* Set ssthresh again after changing 'mss' and 'snd_wnd' */ + pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb); pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F @@ -804,6 +806,11 @@ tcp_process(struct tcp_pcb *pcb) * we'd better pass it on to the application as well. */ tcp_receive(pcb); + /* passive open: update initial ssthresh now that the correct window is + known: if the remote side supports window scaling, the window sent + with the initial SYN can be smaller than the one used later */ + pcb->ssthresh = LWIP_TCP_INITIAL_SSTHRESH(pcb); + /* Prevent ACK for SYN to generate a sent event */ if (pcb->acked != 0) { pcb->acked--;