diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c index 988cdb087f3b..50c0b79660e2 100644 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -199,7 +199,7 @@ newreno_ack_received(struct cc_var *ccv, uint16_t type) 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 @@ newreno_after_idle(struct cc_var *ccv) * * 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)); } diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index c4a4746d4218..750046407fbd 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -371,31 +371,14 @@ cc_conn_init(struct tcpcb *tp) /* * 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 @@ tcp_compute_pipe(struct tcpcb *tp) 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); + } +} diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index d2db801b1f85..8201dc514bf0 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -1425,21 +1425,9 @@ rack_cc_after_idle(struct tcpcb *tp, int reduce_largest) if (tp->snd_cwnd == 1) i_cwnd = tp->t_maxseg; /* SYN(-ACK) lost */ - else if (V_tcp_initcwnd_segments) - i_cwnd = min((V_tcp_initcwnd_segments * tp->t_maxseg), - max(2 * tp->t_maxseg, V_tcp_initcwnd_segments * 1460)); - else if (V_tcp_do_rfc3390) - i_cwnd = min(4 * tp->t_maxseg, - max(2 * tp->t_maxseg, 4380)); - else { - /* Per RFC5681 Section 3.1 */ - if (tp->t_maxseg > 2190) - i_cwnd = 2 * tp->t_maxseg; - else if (tp->t_maxseg > 1095) - i_cwnd = 3 * tp->t_maxseg; - else - i_cwnd = 4 * tp->t_maxseg; - } + else + i_cwnd = tcp_compute_initwnd(tcp_maxseg(tp)); + if (reduce_largest) { /* * Do we reduce the largest cwnd to make diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 2fbe07ade5dc..09316343cb2a 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -942,6 +942,7 @@ void tcp_sack_partialack(struct tcpcb *, struct tcphdr *); 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,