diff options
author | John Heffner <jheffner@psc.edu> | 2004-07-07 01:22:10 -0700 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2004-07-07 01:22:10 -0700 |
commit | 5e6ae6a49621072af626fad4c5d87b5946dc318f (patch) | |
tree | f27a82ec72606608d7b8520986efb6fcfc9c4632 /net | |
parent | e5cd84c9fc5304737559cec7f09612b7dd79eae5 (diff) | |
download | history-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.c | 33 |
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; } |