aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_minisocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r--net/ipv4/tcp_minisocks.c76
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 29int 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
35int sysctl_tcp_syncookies __read_mostly = SYNC_INIT;
36EXPORT_SYMBOL(sysctl_tcp_syncookies); 30EXPORT_SYMBOL(sysctl_tcp_syncookies);
37 31
38int sysctl_tcp_abort_on_overflow __read_mostly; 32int sysctl_tcp_abort_on_overflow __read_mostly;
@@ -96,13 +90,14 @@ enum tcp_tw_status
96tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, 90tcp_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