diff options
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index d3f6bbfc76f0..96852af43ca7 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -383,14 +383,43 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 383 | const struct inet_request_sock *ireq = inet_rsk(req); | 383 | const struct inet_request_sock *ireq = inet_rsk(req); |
| 384 | struct tcp_request_sock *treq = tcp_rsk(req); | 384 | struct tcp_request_sock *treq = tcp_rsk(req); |
| 385 | struct inet_connection_sock *newicsk = inet_csk(newsk); | 385 | struct inet_connection_sock *newicsk = inet_csk(newsk); |
| 386 | struct tcp_sock *newtp; | 386 | struct tcp_sock *newtp = tcp_sk(newsk); |
| 387 | struct tcp_sock *oldtp = tcp_sk(sk); | ||
| 388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; | ||
| 389 | |||
| 390 | /* TCP Cookie Transactions require space for the cookie pair, | ||
| 391 | * as it differs for each connection. There is no need to | ||
| 392 | * copy any s_data_payload stored at the original socket. | ||
| 393 | * Failure will prevent resuming the connection. | ||
| 394 | * | ||
| 395 | * Presumed copied, in order of appearance: | ||
| 396 | * cookie_in_always, cookie_out_never | ||
| 397 | */ | ||
| 398 | if (oldcvp != NULL) { | ||
| 399 | struct tcp_cookie_values *newcvp = | ||
| 400 | kzalloc(sizeof(*newtp->cookie_values), | ||
| 401 | GFP_ATOMIC); | ||
| 402 | |||
| 403 | if (newcvp != NULL) { | ||
| 404 | kref_init(&newcvp->kref); | ||
| 405 | newcvp->cookie_desired = | ||
| 406 | oldcvp->cookie_desired; | ||
| 407 | newtp->cookie_values = newcvp; | ||
| 408 | } else { | ||
| 409 | /* Not Yet Implemented */ | ||
| 410 | newtp->cookie_values = NULL; | ||
| 411 | } | ||
| 412 | } | ||
| 387 | 413 | ||
| 388 | /* Now setup tcp_sock */ | 414 | /* Now setup tcp_sock */ |
| 389 | newtp = tcp_sk(newsk); | ||
| 390 | newtp->pred_flags = 0; | 415 | newtp->pred_flags = 0; |
| 391 | newtp->rcv_wup = newtp->copied_seq = newtp->rcv_nxt = treq->rcv_isn + 1; | 416 | |
| 392 | newtp->snd_sml = newtp->snd_una = newtp->snd_nxt = treq->snt_isn + 1; | 417 | newtp->rcv_wup = newtp->copied_seq = |
| 393 | newtp->snd_up = treq->snt_isn + 1; | 418 | newtp->rcv_nxt = treq->rcv_isn + 1; |
| 419 | |||
| 420 | newtp->snd_sml = newtp->snd_una = | ||
| 421 | newtp->snd_nxt = newtp->snd_up = | ||
| 422 | treq->snt_isn + 1 + tcp_s_data_size(oldtp); | ||
| 394 | 423 | ||
| 395 | tcp_prequeue_init(newtp); | 424 | tcp_prequeue_init(newtp); |
| 396 | 425 | ||
| @@ -423,8 +452,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 423 | tcp_set_ca_state(newsk, TCP_CA_Open); | 452 | tcp_set_ca_state(newsk, TCP_CA_Open); |
| 424 | tcp_init_xmit_timers(newsk); | 453 | tcp_init_xmit_timers(newsk); |
| 425 | skb_queue_head_init(&newtp->out_of_order_queue); | 454 | skb_queue_head_init(&newtp->out_of_order_queue); |
| 426 | newtp->write_seq = treq->snt_isn + 1; | 455 | newtp->write_seq = newtp->pushed_seq = |
| 427 | newtp->pushed_seq = newtp->write_seq; | 456 | treq->snt_isn + 1 + tcp_s_data_size(oldtp); |
| 428 | 457 | ||
| 429 | newtp->rx_opt.saw_tstamp = 0; | 458 | newtp->rx_opt.saw_tstamp = 0; |
| 430 | 459 | ||
| @@ -590,7 +619,8 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, | |||
| 590 | * Invalid ACK: reset will be sent by listening socket | 619 | * Invalid ACK: reset will be sent by listening socket |
| 591 | */ | 620 | */ |
| 592 | if ((flg & TCP_FLAG_ACK) && | 621 | if ((flg & TCP_FLAG_ACK) && |
| 593 | (TCP_SKB_CB(skb)->ack_seq != tcp_rsk(req)->snt_isn + 1)) | 622 | (TCP_SKB_CB(skb)->ack_seq != |
| 623 | tcp_rsk(req)->snt_isn + 1 + tcp_s_data_size(tcp_sk(sk)))) | ||
| 594 | return sk; | 624 | return sk; |
| 595 | 625 | ||
| 596 | /* Also, it would be not so bad idea to check rcv_tsecr, which | 626 | /* Also, it would be not so bad idea to check rcv_tsecr, which |
