Message ID | 1383066545-27348-1-git-send-email-ycheng@google.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Yuchung Cheng <ycheng@google.com> Date: Tue, 29 Oct 2013 10:09:05 -0700 > Fast Open currently has a fall back feature to address SYN-data > being dropped by but it requires the middle-box to pass on regular > SYN retry after SYN-data. This is implemented in commit aab487435 > ("net-tcp: Fast Open client - detecting SYN-data drops") > > However some NAT boxes will drop all subsequent packets after first > SYN-data and blackholes the entire connections. An example is incommit > 356d7d8 "netfilter: nf_conntrack: fix tcp_in_window for Fast Open". > > The sender should note such incidents and falls back to use regular > TCP handshake on subsequent attempt temporarily as well: after the > second SYN timeouts the original Fast Open SYN is most likely lost. > When such an event recurs Fast Open is disabled based on the number > of recurrences exponentially. > > Signed-off-by: Yuchung Cheng <ycheng@google.com> > Signed-off-by: Neal Cardwell <ncardwell@google.com> > Signed-off-by: Eric Dumazet <edumazet@google.com> Applied, thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 4a2a841..2ab09cb 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -671,8 +671,9 @@ void tcp_fastopen_cache_set(struct sock *sk, u16 mss, struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen; write_seqlock_bh(&fastopen_seqlock); - tfom->mss = mss; - if (cookie->len > 0) + if (mss) + tfom->mss = mss; + if (cookie && cookie->len > 0) tfom->cookie = *cookie; if (syn_lost) { ++tfom->syn_loss; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index af07b5b..64f0354 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -156,12 +156,16 @@ static bool retransmits_timed_out(struct sock *sk, static int tcp_write_timeout(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); + struct tcp_sock *tp = tcp_sk(sk); int retry_until; bool do_reset, syn_set = false; if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { - if (icsk->icsk_retransmits) + if (icsk->icsk_retransmits) { dst_negative_advice(sk); + if (tp->syn_fastopen || tp->syn_data) + tcp_fastopen_cache_set(sk, 0, NULL, true); + } retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; syn_set = true; } else {