Apply Revision 220794 from FreeBSD to avoid dup ACKs:
When checking to see if a window update should be sent to the remote peer, don't force a window update if the window would not actually grow due to window scaling. Specifically, if the window scaling factor is larger than 2 * MSS, then after the local reader has drained 2 * MSS bytes from the socket, a window update can end up advertising the same window. If this happens, the supposed window update actually ends up being a duplicate ACK. This can result in an excessive number of duplicate ACKs when using a higher maximum socket buffer size. Pointed out by Ricky Charlet, in tech-net.
This commit is contained in:
parent
016c7d8298
commit
ffe2b84e28
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tcp_output.c,v 1.181 2015/04/27 02:59:44 ozaki-r Exp $ */
|
||||
/* $NetBSD: tcp_output.c,v 1.182 2015/04/27 16:50:17 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -135,7 +135,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.181 2015/04/27 02:59:44 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.182 2015/04/27 16:50:17 christos Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -1020,11 +1020,19 @@ again:
|
||||
long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) -
|
||||
(tp->rcv_adv - tp->rcv_nxt);
|
||||
|
||||
/*
|
||||
* If the new window size ends up being the same as the old
|
||||
* size when it is scaled, then don't force a window update.
|
||||
*/
|
||||
if ((tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale ==
|
||||
(adv + tp->rcv_adv - tp->rcv_nxt) >> tp->rcv_scale)
|
||||
goto dontupdate;
|
||||
if (adv >= (long) (2 * rxsegsize))
|
||||
goto send;
|
||||
if (2 * adv >= (long) so->so_rcv.sb_hiwat)
|
||||
goto send;
|
||||
}
|
||||
dontupdate:
|
||||
|
||||
/*
|
||||
* Send if we owe peer an ACK.
|
||||
|
Loading…
Reference in New Issue
Block a user