If a TCP connection has been idle for one retransmit timeout or more
it must reset its congestion window back to the initial window. RFC3390 has increased the initial window from 1 segment to up to 4 segments. The initial window increase of RFC3390 wasn't reflected into the restart window which remained at its original defaults of 4 segments for local and 1 segment for all other connections. Both values are controllable through sysctl net.inet.tcp.local_slowstart_flightsize and net.inet.tcp.slowstart_flightsize. The increase helps TCP's slow start algorithm to open up the congestion window much faster. Reviewed by: lstewart MFC after: 1 week
This commit is contained in:
parent
3ed1008b89
commit
c3f0bdc66b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=211464
@ -140,7 +140,7 @@ tcp_output(struct tcpcb *tp)
|
||||
{
|
||||
struct socket *so = tp->t_inpcb->inp_socket;
|
||||
long len, recwin, sendwin;
|
||||
int off, flags, error;
|
||||
int off, flags, error, rw;
|
||||
struct mbuf *m;
|
||||
struct ip *ip = NULL;
|
||||
struct ipovly *ipov = NULL;
|
||||
@ -176,23 +176,34 @@ tcp_output(struct tcpcb *tp)
|
||||
idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una);
|
||||
if (idle && ticks - tp->t_rcvtime >= tp->t_rxtcur) {
|
||||
/*
|
||||
* We have been idle for "a while" and no acks are
|
||||
* expected to clock out any data we send --
|
||||
* slow start to get ack "clock" running again.
|
||||
* If we've been idle for more than one retransmit
|
||||
* timeout the old congestion window is no longer
|
||||
* current and we have to reduce it to the restart
|
||||
* window before we can transmit again.
|
||||
*
|
||||
* Set the slow-start flight size depending on whether
|
||||
* this is a local network or not.
|
||||
* The restart window is the initial window or the last
|
||||
* CWND, whichever is smaller.
|
||||
*
|
||||
* This is done to prevent us from flooding the path with
|
||||
* a full CWND at wirespeed, overloading router and switch
|
||||
* buffers along the way.
|
||||
*
|
||||
* See RFC5681 Section 4.1. "Restarting Idle Connections".
|
||||
*/
|
||||
int ss = V_ss_fltsz;
|
||||
if (V_tcp_do_rfc3390)
|
||||
rw = min(4 * tp->t_maxseg,
|
||||
max(2 * tp->t_maxseg, 4380));
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
if (in6_localaddr(&tp->t_inpcb->in6p_faddr))
|
||||
ss = V_ss_fltsz_local;
|
||||
} else
|
||||
#endif /* INET6 */
|
||||
if (in_localaddr(tp->t_inpcb->inp_faddr))
|
||||
ss = V_ss_fltsz_local;
|
||||
tp->snd_cwnd = tp->t_maxseg * ss;
|
||||
else if ((isipv6 ? in6_localaddr(&tp->t_inpcb->in6p_faddr) :
|
||||
in_localaddr(tp->t_inpcb->inp_faddr)))
|
||||
#else
|
||||
else if (in_localaddr(tp->t_inpcb->inp_faddr))
|
||||
#endif
|
||||
rw = V_ss_fltsz_local * tp->t_maxseg;
|
||||
else
|
||||
rw = V_ss_fltsz * tp->t_maxseg;
|
||||
|
||||
tp->snd_cwnd = min(rw, tp->snd_cwnd);
|
||||
}
|
||||
tp->t_flags &= ~TF_LASTIDLE;
|
||||
if (idle) {
|
||||
|
@ -565,6 +565,7 @@ extern int tcp_log_in_vain;
|
||||
VNET_DECLARE(int, tcp_mssdflt); /* XXX */
|
||||
VNET_DECLARE(int, tcp_minmss);
|
||||
VNET_DECLARE(int, tcp_delack_enabled);
|
||||
VNET_DECLARE(int, tcp_do_rfc3390);
|
||||
VNET_DECLARE(int, tcp_do_newreno);
|
||||
VNET_DECLARE(int, path_mtu_discovery);
|
||||
VNET_DECLARE(int, ss_fltsz);
|
||||
@ -575,6 +576,7 @@ VNET_DECLARE(int, ss_fltsz_local);
|
||||
#define V_tcp_mssdflt VNET(tcp_mssdflt)
|
||||
#define V_tcp_minmss VNET(tcp_minmss)
|
||||
#define V_tcp_delack_enabled VNET(tcp_delack_enabled)
|
||||
#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390)
|
||||
#define V_tcp_do_newreno VNET(tcp_do_newreno)
|
||||
#define V_path_mtu_discovery VNET(path_mtu_discovery)
|
||||
#define V_ss_fltsz VNET(ss_fltsz)
|
||||
|
Loading…
Reference in New Issue
Block a user