aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/syncookies.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/syncookies.c')
-rw-r--r--net/ipv4/syncookies.c33
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);
253struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, 253struct 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