diff options
author | Florian Westphal <fw@strlen.de> | 2010-06-21 07:48:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-27 01:00:03 -0400 |
commit | 734f614bc1e7c6bf075d201f6bd9a555b8b4a984 (patch) | |
tree | f5602e98d4088b1b667e286a1ead644122cd77e8 /net/ipv4 | |
parent | 9587c6ddd452314e8ed5707ad832a507a030ef57 (diff) |
syncookies: do not store rcv_wscale in tcp timestamp
As pointed out by Fernando Gont there is no need to encode rcv_wscale
into the cookie.
We did not use the restored rcv_wscale anyway; it is recomputed
via tcp_select_initial_window().
Thus we can save 4 bits in the ts option space by removing rcv_wscale.
In case window scaling was not supported, we set the (invalid) wscale
value 0xf.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/syncookies.c | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 51b5662545d6..8896329aebd0 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -18,8 +18,8 @@ | |||
18 | #include <net/tcp.h> | 18 | #include <net/tcp.h> |
19 | #include <net/route.h> | 19 | #include <net/route.h> |
20 | 20 | ||
21 | /* Timestamps: lowest 9 bits store TCP options */ | 21 | /* Timestamps: lowest bits store TCP options */ |
22 | #define TSBITS 9 | 22 | #define TSBITS 5 |
23 | #define TSMASK (((__u32)1 << TSBITS) - 1) | 23 | #define TSMASK (((__u32)1 << TSBITS) - 1) |
24 | 24 | ||
25 | extern int sysctl_tcp_syncookies; | 25 | extern int sysctl_tcp_syncookies; |
@@ -58,7 +58,7 @@ static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, | |||
58 | 58 | ||
59 | /* | 59 | /* |
60 | * when syncookies are in effect and tcp timestamps are enabled we encode | 60 | * when syncookies are in effect and tcp timestamps are enabled we encode |
61 | * tcp options in the lowest 9 bits of the timestamp value that will be | 61 | * tcp options in the lower bits of the timestamp value that will be |
62 | * sent in the syn-ack. | 62 | * sent in the syn-ack. |
63 | * Since subsequent timestamps use the normal tcp_time_stamp value, we | 63 | * Since subsequent timestamps use the normal tcp_time_stamp value, we |
64 | * must make sure that the resulting initial timestamp is <= tcp_time_stamp. | 64 | * must make sure that the resulting initial timestamp is <= tcp_time_stamp. |
@@ -70,11 +70,9 @@ __u32 cookie_init_timestamp(struct request_sock *req) | |||
70 | u32 options = 0; | 70 | u32 options = 0; |
71 | 71 | ||
72 | ireq = inet_rsk(req); | 72 | ireq = inet_rsk(req); |
73 | if (ireq->wscale_ok) { | 73 | |
74 | options = ireq->snd_wscale; | 74 | options = ireq->wscale_ok ? ireq->snd_wscale : 0xf; |
75 | options |= ireq->rcv_wscale << 4; | 75 | options |= ireq->sack_ok << 4; |
76 | } | ||
77 | options |= ireq->sack_ok << 8; | ||
78 | 76 | ||
79 | ts = ts_now & ~TSMASK; | 77 | ts = ts_now & ~TSMASK; |
80 | ts |= options; | 78 | ts |= options; |
@@ -227,15 +225,14 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, | |||
227 | * additional tcp options in the timestamp. | 225 | * additional tcp options in the timestamp. |
228 | * This extracts these options from the timestamp echo. | 226 | * This extracts these options from the timestamp echo. |
229 | * | 227 | * |
230 | * The lowest 4 bits are for snd_wscale | 228 | * The lowest 4 bits store snd_wscale. |
231 | * The next 4 lsb are for rcv_wscale | ||
232 | * The next lsb is for sack_ok | 229 | * The next lsb is for sack_ok |
233 | * | 230 | * |
234 | * return false if we decode an option that should not be. | 231 | * return false if we decode an option that should not be. |
235 | */ | 232 | */ |
236 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt) | 233 | bool cookie_check_timestamp(struct tcp_options_received *tcp_opt) |
237 | { | 234 | { |
238 | /* echoed timestamp, 9 lowest bits contain options */ | 235 | /* echoed timestamp, lowest bits contain options */ |
239 | u32 options = tcp_opt->rcv_tsecr & TSMASK; | 236 | u32 options = tcp_opt->rcv_tsecr & TSMASK; |
240 | 237 | ||
241 | if (!tcp_opt->saw_tstamp) { | 238 | if (!tcp_opt->saw_tstamp) { |
@@ -246,20 +243,17 @@ bool cookie_check_timestamp(struct tcp_options_received *tcp_opt) | |||
246 | if (!sysctl_tcp_timestamps) | 243 | if (!sysctl_tcp_timestamps) |
247 | return false; | 244 | return false; |
248 | 245 | ||
249 | tcp_opt->snd_wscale = options & 0xf; | ||
250 | options >>= 4; | ||
251 | tcp_opt->rcv_wscale = options & 0xf; | ||
252 | |||
253 | tcp_opt->sack_ok = (options >> 4) & 0x1; | 246 | tcp_opt->sack_ok = (options >> 4) & 0x1; |
254 | 247 | ||
255 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) | 248 | if (tcp_opt->sack_ok && !sysctl_tcp_sack) |
256 | return false; | 249 | return false; |
257 | 250 | ||
258 | if (tcp_opt->snd_wscale || tcp_opt->rcv_wscale) { | 251 | if ((options & 0xf) == 0xf) |
259 | tcp_opt->wscale_ok = 1; | 252 | return true; /* no window scaling */ |
260 | return sysctl_tcp_window_scaling != 0; | 253 | |
261 | } | 254 | tcp_opt->wscale_ok = 1; |
262 | return true; | 255 | tcp_opt->snd_wscale = options & 0xf; |
256 | return sysctl_tcp_window_scaling != 0; | ||
263 | } | 257 | } |
264 | EXPORT_SYMBOL(cookie_check_timestamp); | 258 | EXPORT_SYMBOL(cookie_check_timestamp); |
265 | 259 | ||
@@ -313,7 +307,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
313 | ireq->rmt_addr = ip_hdr(skb)->saddr; | 307 | ireq->rmt_addr = ip_hdr(skb)->saddr; |
314 | ireq->ecn_ok = 0; | 308 | ireq->ecn_ok = 0; |
315 | ireq->snd_wscale = tcp_opt.snd_wscale; | 309 | ireq->snd_wscale = tcp_opt.snd_wscale; |
316 | ireq->rcv_wscale = tcp_opt.rcv_wscale; | ||
317 | ireq->sack_ok = tcp_opt.sack_ok; | 310 | ireq->sack_ok = tcp_opt.sack_ok; |
318 | ireq->wscale_ok = tcp_opt.wscale_ok; | 311 | ireq->wscale_ok = tcp_opt.wscale_ok; |
319 | ireq->tstamp_ok = tcp_opt.saw_tstamp; | 312 | ireq->tstamp_ok = tcp_opt.saw_tstamp; |