aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn Heffner <jheffner@psc.edu>2004-07-07 01:22:10 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-07-07 01:22:10 -0700
commit5e6ae6a49621072af626fad4c5d87b5946dc318f (patch)
treef27a82ec72606608d7b8520986efb6fcfc9c4632 /net
parente5cd84c9fc5304737559cec7f09612b7dd79eae5 (diff)
downloadhistory-5e6ae6a49621072af626fad4c5d87b5946dc318f.tar.gz
[TCP]: Do not round window to MSS if window scaling.
Signed-off-by: John Heffner <jheffner@psc.edu> Signed-off-by: David S. Miller <davem@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/tcp_output.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 1fbe1edbba7b96..98212fab242ef5 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -682,17 +682,32 @@ u32 __tcp_select_window(struct sock *sk)
if (free_space > tp->rcv_ssthresh)
free_space = tp->rcv_ssthresh;
- /* Get the largest window that is a nice multiple of mss.
- * Window clamp already applied above.
- * If our current window offering is within 1 mss of the
- * free space we just keep it. This prevents the divide
- * and multiply from happening most of the time.
- * We also don't do any window rounding when the free space
- * is too small.
+ /* Don't do rounding if we are using window scaling, since the
+ * scaled window will not line up with the MSS boundary anyway.
*/
window = tp->rcv_wnd;
- if (window <= free_space - mss || window > free_space)
- window = (free_space/mss)*mss;
+ if (tp->rcv_wscale) {
+ window = free_space;
+
+ /* Advertise enough space so that it won't get scaled away.
+ * Import case: prevent zero window announcement if
+ * 1<<rcv_wscale > mss.
+ */
+ if (((window >> tp->rcv_wscale) << tp->rcv_wscale) != window)
+ window = (((window >> tp->rcv_wscale) + 1)
+ << tp->rcv_wscale);
+ } else {
+ /* Get the largest window that is a nice multiple of mss.
+ * Window clamp already applied above.
+ * If our current window offering is within 1 mss of the
+ * free space we just keep it. This prevents the divide
+ * and multiply from happening most of the time.
+ * We also don't do any window rounding when the free space
+ * is too small.
+ */
+ if (window <= free_space - mss || window > free_space)
+ window = (free_space/mss)*mss;
+ }
return window;
}