diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 57ae96a04220..28e029632493 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2717,6 +2717,35 @@ static void tcp_try_undo_dsack(struct sock *sk) | |||
2717 | } | 2717 | } |
2718 | } | 2718 | } |
2719 | 2719 | ||
2720 | /* We can clear retrans_stamp when there are no retransmissions in the | ||
2721 | * window. It would seem that it is trivially available for us in | ||
2722 | * tp->retrans_out, however, that kind of assumptions doesn't consider | ||
2723 | * what will happen if errors occur when sending retransmission for the | ||
2724 | * second time. ...It could the that such segment has only | ||
2725 | * TCPCB_EVER_RETRANS set at the present time. It seems that checking | ||
2726 | * the head skb is enough except for some reneging corner cases that | ||
2727 | * are not worth the effort. | ||
2728 | * | ||
2729 | * Main reason for all this complexity is the fact that connection dying | ||
2730 | * time now depends on the validity of the retrans_stamp, in particular, | ||
2731 | * that successive retransmissions of a segment must not advance | ||
2732 | * retrans_stamp under any conditions. | ||
2733 | */ | ||
2734 | static int tcp_any_retrans_done(struct sock *sk) | ||
2735 | { | ||
2736 | struct tcp_sock *tp = tcp_sk(sk); | ||
2737 | struct sk_buff *skb; | ||
2738 | |||
2739 | if (tp->retrans_out) | ||
2740 | return 1; | ||
2741 | |||
2742 | skb = tcp_write_queue_head(sk); | ||
2743 | if (unlikely(skb && TCP_SKB_CB(skb)->sacked & TCPCB_EVER_RETRANS)) | ||
2744 | return 1; | ||
2745 | |||
2746 | return 0; | ||
2747 | } | ||
2748 | |||
2720 | /* Undo during fast recovery after partial ACK. */ | 2749 | /* Undo during fast recovery after partial ACK. */ |
2721 | 2750 | ||
2722 | static int tcp_try_undo_partial(struct sock *sk, int acked) | 2751 | static int tcp_try_undo_partial(struct sock *sk, int acked) |
@@ -2729,7 +2758,7 @@ static int tcp_try_undo_partial(struct sock *sk, int acked) | |||
2729 | /* Plain luck! Hole if filled with delayed | 2758 | /* Plain luck! Hole if filled with delayed |
2730 | * packet, rather than with a retransmit. | 2759 | * packet, rather than with a retransmit. |
2731 | */ | 2760 | */ |
2732 | if (tp->retrans_out == 0) | 2761 | if (!tcp_any_retrans_done(sk)) |
2733 | tp->retrans_stamp = 0; | 2762 | tp->retrans_stamp = 0; |
2734 | 2763 | ||
2735 | tcp_update_reordering(sk, tcp_fackets_out(tp) + acked, 1); | 2764 | tcp_update_reordering(sk, tcp_fackets_out(tp) + acked, 1); |
@@ -2788,7 +2817,7 @@ static void tcp_try_keep_open(struct sock *sk) | |||
2788 | struct tcp_sock *tp = tcp_sk(sk); | 2817 | struct tcp_sock *tp = tcp_sk(sk); |
2789 | int state = TCP_CA_Open; | 2818 | int state = TCP_CA_Open; |
2790 | 2819 | ||
2791 | if (tcp_left_out(tp) || tp->retrans_out || tp->undo_marker) | 2820 | if (tcp_left_out(tp) || tcp_any_retrans_done(sk) || tp->undo_marker) |
2792 | state = TCP_CA_Disorder; | 2821 | state = TCP_CA_Disorder; |
2793 | 2822 | ||
2794 | if (inet_csk(sk)->icsk_ca_state != state) { | 2823 | if (inet_csk(sk)->icsk_ca_state != state) { |
@@ -2803,7 +2832,7 @@ static void tcp_try_to_open(struct sock *sk, int flag) | |||
2803 | 2832 | ||
2804 | tcp_verify_left_out(tp); | 2833 | tcp_verify_left_out(tp); |
2805 | 2834 | ||
2806 | if (!tp->frto_counter && tp->retrans_out == 0) | 2835 | if (!tp->frto_counter && !tcp_any_retrans_done(sk)) |
2807 | tp->retrans_stamp = 0; | 2836 | tp->retrans_stamp = 0; |
2808 | 2837 | ||
2809 | if (flag & FLAG_ECE) | 2838 | if (flag & FLAG_ECE) |
@@ -3698,7 +3727,7 @@ old_ack: | |||
3698 | * the fast version below fails. | 3727 | * the fast version below fails. |
3699 | */ | 3728 | */ |
3700 | void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | 3729 | void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, |
3701 | u8 **hvpp, int estab, struct dst_entry *dst) | 3730 | u8 **hvpp, int estab) |
3702 | { | 3731 | { |
3703 | unsigned char *ptr; | 3732 | unsigned char *ptr; |
3704 | struct tcphdr *th = tcp_hdr(skb); | 3733 | struct tcphdr *th = tcp_hdr(skb); |
@@ -3737,8 +3766,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | |||
3737 | break; | 3766 | break; |
3738 | case TCPOPT_WINDOW: | 3767 | case TCPOPT_WINDOW: |
3739 | if (opsize == TCPOLEN_WINDOW && th->syn && | 3768 | if (opsize == TCPOLEN_WINDOW && th->syn && |
3740 | !estab && sysctl_tcp_window_scaling && | 3769 | !estab && sysctl_tcp_window_scaling) { |
3741 | !dst_feature(dst, RTAX_FEATURE_NO_WSCALE)) { | ||
3742 | __u8 snd_wscale = *(__u8 *)ptr; | 3770 | __u8 snd_wscale = *(__u8 *)ptr; |
3743 | opt_rx->wscale_ok = 1; | 3771 | opt_rx->wscale_ok = 1; |
3744 | if (snd_wscale > 14) { | 3772 | if (snd_wscale > 14) { |
@@ -3754,8 +3782,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | |||
3754 | case TCPOPT_TIMESTAMP: | 3782 | case TCPOPT_TIMESTAMP: |
3755 | if ((opsize == TCPOLEN_TIMESTAMP) && | 3783 | if ((opsize == TCPOLEN_TIMESTAMP) && |
3756 | ((estab && opt_rx->tstamp_ok) || | 3784 | ((estab && opt_rx->tstamp_ok) || |
3757 | (!estab && sysctl_tcp_timestamps && | 3785 | (!estab && sysctl_tcp_timestamps))) { |
3758 | !dst_feature(dst, RTAX_FEATURE_NO_TSTAMP)))) { | ||
3759 | opt_rx->saw_tstamp = 1; | 3786 | opt_rx->saw_tstamp = 1; |
3760 | opt_rx->rcv_tsval = get_unaligned_be32(ptr); | 3787 | opt_rx->rcv_tsval = get_unaligned_be32(ptr); |
3761 | opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4); | 3788 | opt_rx->rcv_tsecr = get_unaligned_be32(ptr + 4); |
@@ -3763,8 +3790,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | |||
3763 | break; | 3790 | break; |
3764 | case TCPOPT_SACK_PERM: | 3791 | case TCPOPT_SACK_PERM: |
3765 | if (opsize == TCPOLEN_SACK_PERM && th->syn && | 3792 | if (opsize == TCPOLEN_SACK_PERM && th->syn && |
3766 | !estab && sysctl_tcp_sack && | 3793 | !estab && sysctl_tcp_sack) { |
3767 | !dst_feature(dst, RTAX_FEATURE_NO_SACK)) { | ||
3768 | opt_rx->sack_ok = 1; | 3794 | opt_rx->sack_ok = 1; |
3769 | tcp_sack_reset(opt_rx); | 3795 | tcp_sack_reset(opt_rx); |
3770 | } | 3796 | } |
@@ -3849,7 +3875,7 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, | |||
3849 | if (tcp_parse_aligned_timestamp(tp, th)) | 3875 | if (tcp_parse_aligned_timestamp(tp, th)) |
3850 | return 1; | 3876 | return 1; |
3851 | } | 3877 | } |
3852 | tcp_parse_options(skb, &tp->rx_opt, hvpp, 1, NULL); | 3878 | tcp_parse_options(skb, &tp->rx_opt, hvpp, 1); |
3853 | return 1; | 3879 | return 1; |
3854 | } | 3880 | } |
3855 | 3881 | ||
@@ -4104,10 +4130,8 @@ static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, | |||
4104 | static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq) | 4130 | static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq) |
4105 | { | 4131 | { |
4106 | struct tcp_sock *tp = tcp_sk(sk); | 4132 | struct tcp_sock *tp = tcp_sk(sk); |
4107 | struct dst_entry *dst = __sk_dst_get(sk); | ||
4108 | 4133 | ||
4109 | if (tcp_is_sack(tp) && sysctl_tcp_dsack && | 4134 | if (tcp_is_sack(tp) && sysctl_tcp_dsack) { |
4110 | !dst_feature(dst, RTAX_FEATURE_NO_DSACK)) { | ||
4111 | int mib_idx; | 4135 | int mib_idx; |
4112 | 4136 | ||
4113 | if (before(seq, tp->rcv_nxt)) | 4137 | if (before(seq, tp->rcv_nxt)) |
@@ -4136,15 +4160,13 @@ static void tcp_dsack_extend(struct sock *sk, u32 seq, u32 end_seq) | |||
4136 | static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb) | 4160 | static void tcp_send_dupack(struct sock *sk, struct sk_buff *skb) |
4137 | { | 4161 | { |
4138 | struct tcp_sock *tp = tcp_sk(sk); | 4162 | struct tcp_sock *tp = tcp_sk(sk); |
4139 | struct dst_entry *dst = __sk_dst_get(sk); | ||
4140 | 4163 | ||
4141 | if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && | 4164 | if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && |
4142 | before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { | 4165 | before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { |
4143 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); | 4166 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); |
4144 | tcp_enter_quickack_mode(sk); | 4167 | tcp_enter_quickack_mode(sk); |
4145 | 4168 | ||
4146 | if (tcp_is_sack(tp) && sysctl_tcp_dsack && | 4169 | if (tcp_is_sack(tp) && sysctl_tcp_dsack) { |
4147 | !dst_feature(dst, RTAX_FEATURE_NO_DSACK)) { | ||
4148 | u32 end_seq = TCP_SKB_CB(skb)->end_seq; | 4170 | u32 end_seq = TCP_SKB_CB(skb)->end_seq; |
4149 | 4171 | ||
4150 | if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) | 4172 | if (after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) |
@@ -5399,11 +5421,10 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
5399 | u8 *hash_location; | 5421 | u8 *hash_location; |
5400 | struct inet_connection_sock *icsk = inet_csk(sk); | 5422 | struct inet_connection_sock *icsk = inet_csk(sk); |
5401 | struct tcp_sock *tp = tcp_sk(sk); | 5423 | struct tcp_sock *tp = tcp_sk(sk); |
5402 | struct dst_entry *dst = __sk_dst_get(sk); | ||
5403 | struct tcp_cookie_values *cvp = tp->cookie_values; | 5424 | struct tcp_cookie_values *cvp = tp->cookie_values; |
5404 | int saved_clamp = tp->rx_opt.mss_clamp; | 5425 | int saved_clamp = tp->rx_opt.mss_clamp; |
5405 | 5426 | ||
5406 | tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, dst); | 5427 | tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0); |
5407 | 5428 | ||
5408 | if (th->ack) { | 5429 | if (th->ack) { |
5409 | /* rfc793: | 5430 | /* rfc793: |