aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-04-24 11:26:50 -0400
committerSteve French <sfrench@us.ibm.com>2008-04-24 11:26:50 -0400
commit36d99df2fb474222ab47fbe8ae7385661033223b (patch)
tree962e068491b752a944f61c454fad3f8619a1ea3f /net/ipv4/tcp_input.c
parent076d8423a98659a92837b07aa494cb74bfefe77c (diff)
parent3dc5063786b273f1aee545844f6bd4e9651ebffe (diff)
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c78
1 files changed, 69 insertions, 9 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index bbb7d88a16b4..ac9b8482f702 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2298,7 +2298,7 @@ static inline int tcp_packet_delayed(struct tcp_sock *tp)
2298{ 2298{
2299 return !tp->retrans_stamp || 2299 return !tp->retrans_stamp ||
2300 (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr && 2300 (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
2301 (__s32)(tp->rx_opt.rcv_tsecr - tp->retrans_stamp) < 0); 2301 before(tp->rx_opt.rcv_tsecr, tp->retrans_stamp));
2302} 2302}
2303 2303
2304/* Undo procedures. */ 2304/* Undo procedures. */
@@ -2309,12 +2309,25 @@ static void DBGUNDO(struct sock *sk, const char *msg)
2309 struct tcp_sock *tp = tcp_sk(sk); 2309 struct tcp_sock *tp = tcp_sk(sk);
2310 struct inet_sock *inet = inet_sk(sk); 2310 struct inet_sock *inet = inet_sk(sk);
2311 2311
2312 printk(KERN_DEBUG "Undo %s %u.%u.%u.%u/%u c%u l%u ss%u/%u p%u\n", 2312 if (sk->sk_family == AF_INET) {
2313 msg, 2313 printk(KERN_DEBUG "Undo %s " NIPQUAD_FMT "/%u c%u l%u ss%u/%u p%u\n",
2314 NIPQUAD(inet->daddr), ntohs(inet->dport), 2314 msg,
2315 tp->snd_cwnd, tcp_left_out(tp), 2315 NIPQUAD(inet->daddr), ntohs(inet->dport),
2316 tp->snd_ssthresh, tp->prior_ssthresh, 2316 tp->snd_cwnd, tcp_left_out(tp),
2317 tp->packets_out); 2317 tp->snd_ssthresh, tp->prior_ssthresh,
2318 tp->packets_out);
2319 }
2320#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
2321 else if (sk->sk_family == AF_INET6) {
2322 struct ipv6_pinfo *np = inet6_sk(sk);
2323 printk(KERN_DEBUG "Undo %s " NIP6_FMT "/%u c%u l%u ss%u/%u p%u\n",
2324 msg,
2325 NIP6(np->daddr), ntohs(inet->dport),
2326 tp->snd_cwnd, tcp_left_out(tp),
2327 tp->snd_ssthresh, tp->prior_ssthresh,
2328 tp->packets_out);
2329 }
2330#endif
2318} 2331}
2319#else 2332#else
2320#define DBGUNDO(x...) do { } while (0) 2333#define DBGUNDO(x...) do { } while (0)
@@ -3592,7 +3605,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
3592 * cases we should never reach this piece of code. 3605 * cases we should never reach this piece of code.
3593 */ 3606 */
3594 printk(KERN_ERR "%s: Impossible, sk->sk_state=%d\n", 3607 printk(KERN_ERR "%s: Impossible, sk->sk_state=%d\n",
3595 __FUNCTION__, sk->sk_state); 3608 __func__, sk->sk_state);
3596 break; 3609 break;
3597 } 3610 }
3598 3611
@@ -4012,7 +4025,7 @@ drop:
4012 u32 end_seq = TCP_SKB_CB(skb)->end_seq; 4025 u32 end_seq = TCP_SKB_CB(skb)->end_seq;
4013 4026
4014 if (seq == TCP_SKB_CB(skb1)->end_seq) { 4027 if (seq == TCP_SKB_CB(skb1)->end_seq) {
4015 __skb_append(skb1, skb, &tp->out_of_order_queue); 4028 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4016 4029
4017 if (!tp->rx_opt.num_sacks || 4030 if (!tp->rx_opt.num_sacks ||
4018 tp->selective_acks[0].end_seq != seq) 4031 tp->selective_acks[0].end_seq != seq)
@@ -4508,6 +4521,49 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th)
4508 } 4521 }
4509} 4522}
4510 4523
4524static int tcp_defer_accept_check(struct sock *sk)
4525{
4526 struct tcp_sock *tp = tcp_sk(sk);
4527
4528 if (tp->defer_tcp_accept.request) {
4529 int queued_data = tp->rcv_nxt - tp->copied_seq;
4530 int hasfin = !skb_queue_empty(&sk->sk_receive_queue) ?
4531 tcp_hdr((struct sk_buff *)
4532 sk->sk_receive_queue.prev)->fin : 0;
4533
4534 if (queued_data && hasfin)
4535 queued_data--;
4536
4537 if (queued_data &&
4538 tp->defer_tcp_accept.listen_sk->sk_state == TCP_LISTEN) {
4539 if (sock_flag(sk, SOCK_KEEPOPEN)) {
4540 inet_csk_reset_keepalive_timer(sk,
4541 keepalive_time_when(tp));
4542 } else {
4543 inet_csk_delete_keepalive_timer(sk);
4544 }
4545
4546 inet_csk_reqsk_queue_add(
4547 tp->defer_tcp_accept.listen_sk,
4548 tp->defer_tcp_accept.request,
4549 sk);
4550
4551 tp->defer_tcp_accept.listen_sk->sk_data_ready(
4552 tp->defer_tcp_accept.listen_sk, 0);
4553
4554 sock_put(tp->defer_tcp_accept.listen_sk);
4555 sock_put(sk);
4556 tp->defer_tcp_accept.listen_sk = NULL;
4557 tp->defer_tcp_accept.request = NULL;
4558 } else if (hasfin ||
4559 tp->defer_tcp_accept.listen_sk->sk_state != TCP_LISTEN) {
4560 tcp_reset(sk);
4561 return -1;
4562 }
4563 }
4564 return 0;
4565}
4566
4511static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) 4567static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
4512{ 4568{
4513 struct tcp_sock *tp = tcp_sk(sk); 4569 struct tcp_sock *tp = tcp_sk(sk);
@@ -4868,6 +4924,9 @@ step5:
4868 4924
4869 tcp_data_snd_check(sk); 4925 tcp_data_snd_check(sk);
4870 tcp_ack_snd_check(sk); 4926 tcp_ack_snd_check(sk);
4927
4928 if (tcp_defer_accept_check(sk))
4929 return -1;
4871 return 0; 4930 return 0;
4872 4931
4873csum_error: 4932csum_error:
@@ -5387,6 +5446,7 @@ discard:
5387 5446
5388EXPORT_SYMBOL(sysctl_tcp_ecn); 5447EXPORT_SYMBOL(sysctl_tcp_ecn);
5389EXPORT_SYMBOL(sysctl_tcp_reordering); 5448EXPORT_SYMBOL(sysctl_tcp_reordering);
5449EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
5390EXPORT_SYMBOL(tcp_parse_options); 5450EXPORT_SYMBOL(tcp_parse_options);
5391EXPORT_SYMBOL(tcp_rcv_established); 5451EXPORT_SYMBOL(tcp_rcv_established);
5392EXPORT_SYMBOL(tcp_rcv_state_process); 5452EXPORT_SYMBOL(tcp_rcv_state_process);