|
45 | 45 | /* People can turn this off for buggy TCP's found in printers etc. */ |
46 | 46 | int sysctl_tcp_retrans_collapse = 1; |
47 | 47 |
|
| 48 | +/* People can turn this on to work with those rare, broken TCPs that |
| 49 | + * interpret the window field as a signed quantity. |
| 50 | + */ |
| 51 | +int sysctl_tcp_workaround_signed_windows = 0; |
| 52 | + |
48 | 53 | /* This limits the percentage of the congestion window which we |
49 | 54 | * will allow a single TSO frame to consume. Building TSO frames |
50 | 55 | * which are too large can cause TCP streams to be bursty. |
@@ -177,12 +182,18 @@ void tcp_select_initial_window(int __space, __u32 mss, |
177 | 182 | space = (space / mss) * mss; |
178 | 183 |
|
179 | 184 | /* NOTE: offering an initial window larger than 32767 |
180 | | - * will break some buggy TCP stacks. We try to be nice. |
181 | | - * If we are not window scaling, then this truncates |
182 | | - * our initial window offering to 32k. There should also |
183 | | - * be a sysctl option to stop being nice. |
| 185 | + * will break some buggy TCP stacks. If the admin tells us |
| 186 | + * it is likely we could be speaking with such a buggy stack |
| 187 | + * we will truncate our initial window offering to 32K-1 |
| 188 | + * unless the remote has sent us a window scaling option, |
| 189 | + * which we interpret as a sign the remote TCP is not |
| 190 | + * misinterpreting the window field as a signed quantity. |
184 | 191 | */ |
185 | | - (*rcv_wnd) = min(space, MAX_TCP_WINDOW); |
| 192 | + if (sysctl_tcp_workaround_signed_windows) |
| 193 | + (*rcv_wnd) = min(space, MAX_TCP_WINDOW); |
| 194 | + else |
| 195 | + (*rcv_wnd) = space; |
| 196 | + |
186 | 197 | (*rcv_wscale) = 0; |
187 | 198 | if (wscale_ok) { |
188 | 199 | /* Set window scaling on max possible window |
@@ -241,7 +252,7 @@ static u16 tcp_select_window(struct sock *sk) |
241 | 252 | /* Make sure we do not exceed the maximum possible |
242 | 253 | * scaled window. |
243 | 254 | */ |
244 | | - if (!tp->rx_opt.rcv_wscale) |
| 255 | + if (!tp->rx_opt.rcv_wscale && sysctl_tcp_workaround_signed_windows) |
245 | 256 | new_win = min(new_win, MAX_TCP_WINDOW); |
246 | 257 | else |
247 | 258 | new_win = min(new_win, (65535U << tp->rx_opt.rcv_wscale)); |
|
0 commit comments