diff options
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 4c03598ed924..87accec8d097 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -26,13 +26,7 @@ | |||
26 | #include <net/inet_common.h> | 26 | #include <net/inet_common.h> |
27 | #include <net/xfrm.h> | 27 | #include <net/xfrm.h> |
28 | 28 | ||
29 | #ifdef CONFIG_SYSCTL | 29 | int sysctl_tcp_syncookies __read_mostly = 1; |
30 | #define SYNC_INIT 0 /* let the user enable it */ | ||
31 | #else | ||
32 | #define SYNC_INIT 1 | ||
33 | #endif | ||
34 | |||
35 | int sysctl_tcp_syncookies __read_mostly = SYNC_INIT; | ||
36 | EXPORT_SYMBOL(sysctl_tcp_syncookies); | 30 | EXPORT_SYMBOL(sysctl_tcp_syncookies); |
37 | 31 | ||
38 | int sysctl_tcp_abort_on_overflow __read_mostly; | 32 | int sysctl_tcp_abort_on_overflow __read_mostly; |
@@ -96,13 +90,14 @@ enum tcp_tw_status | |||
96 | tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, | 90 | tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, |
97 | const struct tcphdr *th) | 91 | const struct tcphdr *th) |
98 | { | 92 | { |
99 | struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); | ||
100 | struct tcp_options_received tmp_opt; | 93 | struct tcp_options_received tmp_opt; |
94 | u8 *hash_location; | ||
95 | struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); | ||
101 | int paws_reject = 0; | 96 | int paws_reject = 0; |
102 | 97 | ||
103 | tmp_opt.saw_tstamp = 0; | ||
104 | if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { | 98 | if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { |
105 | tcp_parse_options(skb, &tmp_opt, 0); | 99 | tmp_opt.tstamp_ok = 1; |
100 | tcp_parse_options(skb, &tmp_opt, &hash_location, 1, NULL); | ||
106 | 101 | ||
107 | if (tmp_opt.saw_tstamp) { | 102 | if (tmp_opt.saw_tstamp) { |
108 | tmp_opt.ts_recent = tcptw->tw_ts_recent; | 103 | tmp_opt.ts_recent = tcptw->tw_ts_recent; |
@@ -389,14 +384,43 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
389 | const struct inet_request_sock *ireq = inet_rsk(req); | 384 | const struct inet_request_sock *ireq = inet_rsk(req); |
390 | struct tcp_request_sock *treq = tcp_rsk(req); | 385 | struct tcp_request_sock *treq = tcp_rsk(req); |
391 | struct inet_connection_sock *newicsk = inet_csk(newsk); | 386 | struct inet_connection_sock *newicsk = inet_csk(newsk); |
392 | struct tcp_sock *newtp; | 387 | struct tcp_sock *newtp = tcp_sk(newsk); |
388 | struct tcp_sock *oldtp = tcp_sk(sk); | ||
389 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; | ||
390 | |||
391 | /* TCP Cookie Transactions require space for the cookie pair, | ||
392 | * as it differs for each connection. There is no need to | ||
393 | * copy any s_data_payload stored at the original socket. | ||
394 | * Failure will prevent resuming the connection. | ||
395 | * | ||
396 | * Presumed copied, in order of appearance: | ||
397 | * cookie_in_always, cookie_out_never | ||
398 | */ | ||
399 | if (oldcvp != NULL) { | ||
400 | struct tcp_cookie_values *newcvp = | ||
401 | kzalloc(sizeof(*newtp->cookie_values), | ||
402 | GFP_ATOMIC); | ||
403 | |||
404 | if (newcvp != NULL) { | ||
405 | kref_init(&newcvp->kref); | ||
406 | newcvp->cookie_desired = | ||
407 | oldcvp->cookie_desired; | ||
408 | newtp->cookie_values = newcvp; | ||
409 | } else { | ||
410 | /* Not Yet Implemented */ | ||
411 | newtp->cookie_values = NULL; | ||
412 | } | ||
413 | } | ||
393 | 414 | ||
394 | /* Now setup tcp_sock */ | 415 | /* Now setup tcp_sock */ |
395 | newtp = tcp_sk(newsk); | ||
396 | newtp->pred_flags = 0; | 416 | newtp->pred_flags = 0; |
397 | newtp->rcv_wup = newtp->copied_seq = newtp->rcv_nxt = treq->rcv_isn + 1; | 417 | |
398 | newtp->snd_sml = newtp->snd_una = newtp->snd_nxt = treq->snt_isn + 1; | 418 | newtp->rcv_wup = newtp->copied_seq = |
399 | newtp->snd_up = treq->snt_isn + 1; | 419 | newtp->rcv_nxt = treq->rcv_isn + 1; |
420 | |||
421 | newtp->snd_sml = newtp->snd_una = | ||
422 | newtp->snd_nxt = newtp->snd_up = | ||
423 | treq->snt_isn + 1 + tcp_s_data_size(oldtp); | ||
400 | 424 | ||
401 | tcp_prequeue_init(newtp); | 425 | tcp_prequeue_init(newtp); |
402 | 426 | ||
@@ -429,8 +453,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
429 | tcp_set_ca_state(newsk, TCP_CA_Open); | 453 | tcp_set_ca_state(newsk, TCP_CA_Open); |
430 | tcp_init_xmit_timers(newsk); | 454 | tcp_init_xmit_timers(newsk); |
431 | skb_queue_head_init(&newtp->out_of_order_queue); | 455 | skb_queue_head_init(&newtp->out_of_order_queue); |
432 | newtp->write_seq = treq->snt_isn + 1; | 456 | newtp->write_seq = newtp->pushed_seq = |
433 | newtp->pushed_seq = newtp->write_seq; | 457 | treq->snt_isn + 1 + tcp_s_data_size(oldtp); |
434 | 458 | ||
435 | newtp->rx_opt.saw_tstamp = 0; | 459 | newtp->rx_opt.saw_tstamp = 0; |
436 | 460 | ||
@@ -476,7 +500,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
476 | if (newtp->af_specific->md5_lookup(sk, newsk)) | 500 | if (newtp->af_specific->md5_lookup(sk, newsk)) |
477 | newtp->tcp_header_len += TCPOLEN_MD5SIG_ALIGNED; | 501 | newtp->tcp_header_len += TCPOLEN_MD5SIG_ALIGNED; |
478 | #endif | 502 | #endif |
479 | if (skb->len >= TCP_MIN_RCVMSS+newtp->tcp_header_len) | 503 | if (skb->len >= TCP_MSS_DEFAULT + newtp->tcp_header_len) |
480 | newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len; | 504 | newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len; |
481 | newtp->rx_opt.mss_clamp = req->mss; | 505 | newtp->rx_opt.mss_clamp = req->mss; |
482 | TCP_ECN_openreq_child(newtp, req); | 506 | TCP_ECN_openreq_child(newtp, req); |
@@ -495,15 +519,16 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
495 | struct request_sock *req, | 519 | struct request_sock *req, |
496 | struct request_sock **prev) | 520 | struct request_sock **prev) |
497 | { | 521 | { |
522 | struct tcp_options_received tmp_opt; | ||
523 | u8 *hash_location; | ||
524 | struct sock *child; | ||
498 | const struct tcphdr *th = tcp_hdr(skb); | 525 | const struct tcphdr *th = tcp_hdr(skb); |
499 | __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); | 526 | __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); |
500 | int paws_reject = 0; | 527 | int paws_reject = 0; |
501 | struct tcp_options_received tmp_opt; | ||
502 | struct sock *child; | ||
503 | 528 | ||
504 | tmp_opt.saw_tstamp = 0; | 529 | if ((th->doff > (sizeof(*th) >> 2)) && (req->ts_recent)) { |
505 | if (th->doff > (sizeof(struct tcphdr)>>2)) { | 530 | tmp_opt.tstamp_ok = 1; |
506 | tcp_parse_options(skb, &tmp_opt, 0); | 531 | tcp_parse_options(skb, &tmp_opt, &hash_location, 1, NULL); |
507 | 532 | ||
508 | if (tmp_opt.saw_tstamp) { | 533 | if (tmp_opt.saw_tstamp) { |
509 | tmp_opt.ts_recent = req->ts_recent; | 534 | tmp_opt.ts_recent = req->ts_recent; |
@@ -537,7 +562,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
537 | * Enforce "SYN-ACK" according to figure 8, figure 6 | 562 | * Enforce "SYN-ACK" according to figure 8, figure 6 |
538 | * of RFC793, fixed by RFC1122. | 563 | * of RFC793, fixed by RFC1122. |
539 | */ | 564 | */ |
540 | req->rsk_ops->rtx_syn_ack(sk, req); | 565 | req->rsk_ops->rtx_syn_ack(sk, req, NULL); |
541 | return NULL; | 566 | return NULL; |
542 | } | 567 | } |
543 | 568 | ||
@@ -596,7 +621,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
596 | * Invalid ACK: reset will be sent by listening socket | 621 | * Invalid ACK: reset will be sent by listening socket |
597 | */ | 622 | */ |
598 | if ((flg & TCP_FLAG_ACK) && | 623 | if ((flg & TCP_FLAG_ACK) && |
599 | (TCP_SKB_CB(skb)->ack_seq != tcp_rsk(req)->snt_isn + 1)) | 624 | (TCP_SKB_CB(skb)->ack_seq != |
625 | tcp_rsk(req)->snt_isn + 1 + tcp_s_data_size(tcp_sk(sk)))) | ||
600 | return sk; | 626 | return sk; |
601 | 627 | ||
602 | /* Also, it would be not so bad idea to check rcv_tsecr, which | 628 | /* Also, it would be not so bad idea to check rcv_tsecr, which |