diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-06-25 06:32:01 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-06-25 06:32:01 -0400 |
| commit | da7878d75b8520c9ae00d27dfbbce546a7bfdfbb (patch) | |
| tree | 547fd497a80818a60ac36831377d5df97868173c /net/ipv4/tcp_input.c | |
| parent | 0e50a4c6ab94ffe7e5515b86b5df9e5abc8c6b13 (diff) | |
| parent | 543cf4cb3fe6f6cae3651ba918b9c56200b257d0 (diff) | |
Merge branch 'linus' into x86/pebs
Diffstat (limited to 'net/ipv4/tcp_input.c')
| -rw-r--r-- | net/ipv4/tcp_input.c | 80 |
1 files changed, 22 insertions, 58 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b54d9d37b636..cad73b7dfef0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -1392,9 +1392,9 @@ static struct sk_buff *tcp_maybe_skipping_dsack(struct sk_buff *skb, | |||
| 1392 | 1392 | ||
| 1393 | if (before(next_dup->start_seq, skip_to_seq)) { | 1393 | if (before(next_dup->start_seq, skip_to_seq)) { |
| 1394 | skb = tcp_sacktag_skip(skb, sk, next_dup->start_seq, fack_count); | 1394 | skb = tcp_sacktag_skip(skb, sk, next_dup->start_seq, fack_count); |
| 1395 | tcp_sacktag_walk(skb, sk, NULL, | 1395 | skb = tcp_sacktag_walk(skb, sk, NULL, |
| 1396 | next_dup->start_seq, next_dup->end_seq, | 1396 | next_dup->start_seq, next_dup->end_seq, |
| 1397 | 1, fack_count, reord, flag); | 1397 | 1, fack_count, reord, flag); |
| 1398 | } | 1398 | } |
| 1399 | 1399 | ||
| 1400 | return skb; | 1400 | return skb; |
| @@ -2483,6 +2483,20 @@ static inline void tcp_complete_cwr(struct sock *sk) | |||
| 2483 | tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); | 2483 | tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); |
| 2484 | } | 2484 | } |
| 2485 | 2485 | ||
| 2486 | static void tcp_try_keep_open(struct sock *sk) | ||
| 2487 | { | ||
| 2488 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 2489 | int state = TCP_CA_Open; | ||
| 2490 | |||
| 2491 | if (tcp_left_out(tp) || tp->retrans_out || tp->undo_marker) | ||
| 2492 | state = TCP_CA_Disorder; | ||
| 2493 | |||
| 2494 | if (inet_csk(sk)->icsk_ca_state != state) { | ||
| 2495 | tcp_set_ca_state(sk, state); | ||
| 2496 | tp->high_seq = tp->snd_nxt; | ||
| 2497 | } | ||
| 2498 | } | ||
| 2499 | |||
| 2486 | static void tcp_try_to_open(struct sock *sk, int flag) | 2500 | static void tcp_try_to_open(struct sock *sk, int flag) |
| 2487 | { | 2501 | { |
| 2488 | struct tcp_sock *tp = tcp_sk(sk); | 2502 | struct tcp_sock *tp = tcp_sk(sk); |
| @@ -2496,15 +2510,7 @@ static void tcp_try_to_open(struct sock *sk, int flag) | |||
| 2496 | tcp_enter_cwr(sk, 1); | 2510 | tcp_enter_cwr(sk, 1); |
| 2497 | 2511 | ||
| 2498 | if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) { | 2512 | if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) { |
| 2499 | int state = TCP_CA_Open; | 2513 | tcp_try_keep_open(sk); |
| 2500 | |||
| 2501 | if (tcp_left_out(tp) || tp->retrans_out || tp->undo_marker) | ||
| 2502 | state = TCP_CA_Disorder; | ||
| 2503 | |||
| 2504 | if (inet_csk(sk)->icsk_ca_state != state) { | ||
| 2505 | tcp_set_ca_state(sk, state); | ||
| 2506 | tp->high_seq = tp->snd_nxt; | ||
| 2507 | } | ||
| 2508 | tcp_moderate_cwnd(tp); | 2514 | tcp_moderate_cwnd(tp); |
| 2509 | } else { | 2515 | } else { |
| 2510 | tcp_cwnd_down(sk, flag); | 2516 | tcp_cwnd_down(sk, flag); |
| @@ -3310,8 +3316,11 @@ no_queue: | |||
| 3310 | return 1; | 3316 | return 1; |
| 3311 | 3317 | ||
| 3312 | old_ack: | 3318 | old_ack: |
| 3313 | if (TCP_SKB_CB(skb)->sacked) | 3319 | if (TCP_SKB_CB(skb)->sacked) { |
| 3314 | tcp_sacktag_write_queue(sk, skb, prior_snd_una); | 3320 | tcp_sacktag_write_queue(sk, skb, prior_snd_una); |
| 3321 | if (icsk->icsk_ca_state == TCP_CA_Open) | ||
| 3322 | tcp_try_keep_open(sk); | ||
| 3323 | } | ||
| 3315 | 3324 | ||
| 3316 | uninteresting_ack: | 3325 | uninteresting_ack: |
| 3317 | SOCK_DEBUG(sk, "Ack %u out of %u:%u\n", ack, tp->snd_una, tp->snd_nxt); | 3326 | SOCK_DEBUG(sk, "Ack %u out of %u:%u\n", ack, tp->snd_una, tp->snd_nxt); |
| @@ -4532,49 +4541,6 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th) | |||
| 4532 | } | 4541 | } |
| 4533 | } | 4542 | } |
| 4534 | 4543 | ||
| 4535 | static int tcp_defer_accept_check(struct sock *sk) | ||
| 4536 | { | ||
| 4537 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 4538 | |||
| 4539 | if (tp->defer_tcp_accept.request) { | ||
| 4540 | int queued_data = tp->rcv_nxt - tp->copied_seq; | ||
| 4541 | int hasfin = !skb_queue_empty(&sk->sk_receive_queue) ? | ||
| 4542 | tcp_hdr((struct sk_buff *) | ||
| 4543 | sk->sk_receive_queue.prev)->fin : 0; | ||
| 4544 | |||
| 4545 | if (queued_data && hasfin) | ||
| 4546 | queued_data--; | ||
| 4547 | |||
| 4548 | if (queued_data && | ||
| 4549 | tp->defer_tcp_accept.listen_sk->sk_state == TCP_LISTEN) { | ||
| 4550 | if (sock_flag(sk, SOCK_KEEPOPEN)) { | ||
| 4551 | inet_csk_reset_keepalive_timer(sk, | ||
| 4552 | keepalive_time_when(tp)); | ||
| 4553 | } else { | ||
| 4554 | inet_csk_delete_keepalive_timer(sk); | ||
| 4555 | } | ||
| 4556 | |||
| 4557 | inet_csk_reqsk_queue_add( | ||
| 4558 | tp->defer_tcp_accept.listen_sk, | ||
| 4559 | tp->defer_tcp_accept.request, | ||
| 4560 | sk); | ||
| 4561 | |||
| 4562 | tp->defer_tcp_accept.listen_sk->sk_data_ready( | ||
| 4563 | tp->defer_tcp_accept.listen_sk, 0); | ||
| 4564 | |||
| 4565 | sock_put(tp->defer_tcp_accept.listen_sk); | ||
| 4566 | sock_put(sk); | ||
| 4567 | tp->defer_tcp_accept.listen_sk = NULL; | ||
| 4568 | tp->defer_tcp_accept.request = NULL; | ||
| 4569 | } else if (hasfin || | ||
| 4570 | tp->defer_tcp_accept.listen_sk->sk_state != TCP_LISTEN) { | ||
| 4571 | tcp_reset(sk); | ||
| 4572 | return -1; | ||
| 4573 | } | ||
| 4574 | } | ||
| 4575 | return 0; | ||
| 4576 | } | ||
| 4577 | |||
| 4578 | static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) | 4544 | static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) |
| 4579 | { | 4545 | { |
| 4580 | struct tcp_sock *tp = tcp_sk(sk); | 4546 | struct tcp_sock *tp = tcp_sk(sk); |
| @@ -4935,8 +4901,6 @@ step5: | |||
| 4935 | 4901 | ||
| 4936 | tcp_data_snd_check(sk); | 4902 | tcp_data_snd_check(sk); |
| 4937 | tcp_ack_snd_check(sk); | 4903 | tcp_ack_snd_check(sk); |
| 4938 | |||
| 4939 | tcp_defer_accept_check(sk); | ||
| 4940 | return 0; | 4904 | return 0; |
| 4941 | 4905 | ||
| 4942 | csum_error: | 4906 | csum_error: |
