Index: sys/netinet/cc/cc_newreno.c =================================================================== --- sys/netinet/cc/cc_newreno.c +++ sys/netinet/cc/cc_newreno.c @@ -199,7 +199,7 @@ static void newreno_after_idle(struct cc_var *ccv) { - int rw; + uint32_t rw; /* * If we've been idle for more than one retransmit timeout the old @@ -214,11 +214,7 @@ * * See RFC5681 Section 4.1. "Restarting Idle Connections". */ - if (V_tcp_do_rfc3390) - rw = min(4 * CCV(ccv, t_maxseg), - max(2 * CCV(ccv, t_maxseg), 4380)); - else - rw = CCV(ccv, t_maxseg) * 2; + rw = tcp_compute_initwnd(tcp_maxseg(ccv->ccvc.tcp)); CCV(ccv, snd_cwnd) = min(rw, CCV(ccv, snd_cwnd)); } Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -371,31 +371,14 @@ /* * Set the initial slow-start flight size. * - * RFC5681 Section 3.1 specifies the default conservative values. - * RFC3390 specifies slightly more aggressive values. - * RFC6928 increases it to ten segments. - * Support for user specified value for initial flight size. - * * If a SYN or SYN/ACK was lost and retransmitted, we have to * reduce the initial CWND to one segment as congestion is likely * requiring us to be cautious. */ if (tp->snd_cwnd == 1) tp->snd_cwnd = maxseg; /* SYN(-ACK) lost */ - else if (V_tcp_initcwnd_segments) - tp->snd_cwnd = min(V_tcp_initcwnd_segments * maxseg, - max(2 * maxseg, V_tcp_initcwnd_segments * 1460)); - else if (V_tcp_do_rfc3390) - tp->snd_cwnd = min(4 * maxseg, max(2 * maxseg, 4380)); - else { - /* Per RFC5681 Section 3.1 */ - if (maxseg > 2190) - tp->snd_cwnd = 2 * maxseg; - else if (maxseg > 1095) - tp->snd_cwnd = 3 * maxseg; - else - tp->snd_cwnd = 4 * maxseg; - } + else + tp->snd_cwnd = tcp_compute_initwnd(maxseg); if (CC_ALGO(tp)->conn_init != NULL) CC_ALGO(tp)->conn_init(tp->ccv); @@ -3818,3 +3801,30 @@ tp->sackhint.sack_bytes_rexmit - tp->sackhint.sacked_bytes); } + +uint32_t +tcp_compute_initwnd(uint32_t maxseg) +{ + /* + * Calculate the Initial Window, also used as Restart Window + * + * RFC5681 Section 3.1 specifies the default conservative values. + * RFC3390 specifies slightly more aggressive values. + * RFC6928 increases it to ten segments. + * Support for user specified value for initial flight size. + */ + if (V_tcp_initcwnd_segments) + return min(V_tcp_initcwnd_segments * maxseg, + max(2 * maxseg, V_tcp_initcwnd_segments * 1460)); + else if (V_tcp_do_rfc3390) + return min(4 * maxseg, max(2 * maxseg, 4380)); + else { + /* Per RFC5681 Section 3.1 */ + if (maxseg > 2190) + return (2 * maxseg); + else if (maxseg > 1095) + return (3 * maxseg); + else + return (4 * maxseg); + } +} Index: sys/netinet/tcp_var.h =================================================================== --- sys/netinet/tcp_var.h +++ sys/netinet/tcp_var.h @@ -942,6 +942,7 @@ void tcp_free_sackholes(struct tcpcb *tp); int tcp_newreno(struct tcpcb *, struct tcphdr *); int tcp_compute_pipe(struct tcpcb *); +uint32_t tcp_compute_initwnd(uint32_t); void tcp_sndbuf_autoscale(struct tcpcb *, struct socket *, uint32_t); struct mbuf * tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen,