summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_output.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2011-04-18 17:43:16 +0000
committerjhb <jhb@FreeBSD.org>2011-04-18 17:43:16 +0000
commit5684b4d8327671c9516c3d6ac17deba6a8ba4aad (patch)
tree4161dc82bb293978239c557a1667246cc6cebe77 /sys/netinet/tcp_output.c
parent45c5f278635fd5c0303b813939271191a964eb85 (diff)
downloadFreeBSD-src-5684b4d8327671c9516c3d6ac17deba6a8ba4aad.zip
FreeBSD-src-5684b4d8327671c9516c3d6ac17deba6a8ba4aad.tar.gz
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. Reviewed by: bz MFC after: 1 month
Diffstat (limited to 'sys/netinet/tcp_output.c')
-rw-r--r--sys/netinet/tcp_output.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 55d3c8e..dc2e5ca 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -564,11 +564,19 @@ after_sack_rexmit:
long adv = min(recwin, (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 * tp->t_maxseg))
goto send;
if (2 * adv >= (long) so->so_rcv.sb_hiwat)
goto send;
}
+dontupdate:
/*
* Send if we owe the peer an ACK, RST, SYN, or urgent data. ACKNOW
OpenPOWER on IntegriCloud