diff options
Diffstat (limited to 'net/ipv4/syncookies.c')
-rw-r--r-- | net/ipv4/syncookies.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index a6e0e077ac33..26399ad2a289 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -253,6 +253,8 @@ EXPORT_SYMBOL(cookie_check_timestamp); | |||
253 | struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | 253 | struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, |
254 | struct ip_options *opt) | 254 | struct ip_options *opt) |
255 | { | 255 | { |
256 | struct tcp_options_received tcp_opt; | ||
257 | u8 *hash_location; | ||
256 | struct inet_request_sock *ireq; | 258 | struct inet_request_sock *ireq; |
257 | struct tcp_request_sock *treq; | 259 | struct tcp_request_sock *treq; |
258 | struct tcp_sock *tp = tcp_sk(sk); | 260 | struct tcp_sock *tp = tcp_sk(sk); |
@@ -263,7 +265,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
263 | int mss; | 265 | int mss; |
264 | struct rtable *rt; | 266 | struct rtable *rt; |
265 | __u8 rcv_wscale; | 267 | __u8 rcv_wscale; |
266 | struct tcp_options_received tcp_opt; | ||
267 | 268 | ||
268 | if (!sysctl_tcp_syncookies || !th->ack) | 269 | if (!sysctl_tcp_syncookies || !th->ack) |
269 | goto out; | 270 | goto out; |
@@ -276,13 +277,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
276 | 277 | ||
277 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV); | 278 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV); |
278 | 279 | ||
279 | /* check for timestamp cookie support */ | ||
280 | memset(&tcp_opt, 0, sizeof(tcp_opt)); | ||
281 | tcp_parse_options(skb, &tcp_opt, 0); | ||
282 | |||
283 | if (tcp_opt.saw_tstamp) | ||
284 | cookie_check_timestamp(&tcp_opt); | ||
285 | |||
286 | ret = NULL; | 280 | ret = NULL; |
287 | req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */ | 281 | req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */ |
288 | if (!req) | 282 | if (!req) |
@@ -298,12 +292,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
298 | ireq->loc_addr = ip_hdr(skb)->daddr; | 292 | ireq->loc_addr = ip_hdr(skb)->daddr; |
299 | ireq->rmt_addr = ip_hdr(skb)->saddr; | 293 | ireq->rmt_addr = ip_hdr(skb)->saddr; |
300 | ireq->ecn_ok = 0; | 294 | ireq->ecn_ok = 0; |
301 | ireq->snd_wscale = tcp_opt.snd_wscale; | ||
302 | ireq->rcv_wscale = tcp_opt.rcv_wscale; | ||
303 | ireq->sack_ok = tcp_opt.sack_ok; | ||
304 | ireq->wscale_ok = tcp_opt.wscale_ok; | ||
305 | ireq->tstamp_ok = tcp_opt.saw_tstamp; | ||
306 | req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; | ||
307 | 295 | ||
308 | /* We throwed the options of the initial SYN away, so we hope | 296 | /* We throwed the options of the initial SYN away, so we hope |
309 | * the ACK carries the same options again (see RFC1122 4.2.3.8) | 297 | * the ACK carries the same options again (see RFC1122 4.2.3.8) |
@@ -333,7 +321,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
333 | * no easy way to do this. | 321 | * no easy way to do this. |
334 | */ | 322 | */ |
335 | { | 323 | { |
336 | struct flowi fl = { .nl_u = { .ip4_u = | 324 | struct flowi fl = { .mark = sk->sk_mark, |
325 | .nl_u = { .ip4_u = | ||
337 | { .daddr = ((opt && opt->srr) ? | 326 | { .daddr = ((opt && opt->srr) ? |
338 | opt->faddr : | 327 | opt->faddr : |
339 | ireq->rmt_addr), | 328 | ireq->rmt_addr), |
@@ -351,6 +340,20 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
351 | } | 340 | } |
352 | } | 341 | } |
353 | 342 | ||
343 | /* check for timestamp cookie support */ | ||
344 | memset(&tcp_opt, 0, sizeof(tcp_opt)); | ||
345 | tcp_parse_options(skb, &tcp_opt, &hash_location, 0, &rt->u.dst); | ||
346 | |||
347 | if (tcp_opt.saw_tstamp) | ||
348 | cookie_check_timestamp(&tcp_opt); | ||
349 | |||
350 | ireq->snd_wscale = tcp_opt.snd_wscale; | ||
351 | ireq->rcv_wscale = tcp_opt.rcv_wscale; | ||
352 | ireq->sack_ok = tcp_opt.sack_ok; | ||
353 | ireq->wscale_ok = tcp_opt.wscale_ok; | ||
354 | ireq->tstamp_ok = tcp_opt.saw_tstamp; | ||
355 | req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; | ||
356 | |||
354 | /* Try to redo what tcp_v4_send_synack did. */ | 357 | /* Try to redo what tcp_v4_send_synack did. */ |
355 | req->window_clamp = tp->window_clamp ? :dst_metric(&rt->u.dst, RTAX_WINDOW); | 358 | req->window_clamp = tp->window_clamp ? :dst_metric(&rt->u.dst, RTAX_WINDOW); |
356 | 359 | ||