aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_output.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2011-04-18 17:43:16 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2011-04-18 17:43:16 +0000
commitda84b2e6c534703fd8df9be7af9ae8790f3c76ee (patch)
tree4161dc82bb293978239c557a1667246cc6cebe77 /sys/netinet/tcp_output.c
parent5d253e418f9bfd54bfa6b36f431b95fe81df3f3b (diff)
downloadsrc-da84b2e6c534703fd8df9be7af9ae8790f3c76ee.tar.gz
src-da84b2e6c534703fd8df9be7af9ae8790f3c76ee.zip
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
Notes
Notes: svn path=/head/; revision=220794
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 55d3c8e7b968..dc2e5ca23f07 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