aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2012-07-19 02:43:10 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-19 14:02:03 -0400
commitaab4874355679c70f93993cf3b3fd74643b9ac33 (patch)
tree677d3faf161e39f9de18b5956e24cd746e73d996 /net/ipv4/tcp_output.c
parentcf60af03ca4e71134206809ea892e49b92a88896 (diff)
net-tcp: Fast Open client - detecting SYN-data drops
On paths with firewalls dropping SYN with data or experimental TCP options, Fast Open connections will have experience SYN timeout and bad performance. The solution is to track such incidents in the cookie cache and disables Fast Open temporarily. Since only the original SYN includes data and/or Fast Open option, the SYN-ACK has some tell-tale sign (tcp_rcv_fastopen_synack()) to detect such drops. If a path has recurring Fast Open SYN drops, Fast Open is disabled for 2^(recurring_losses) minutes starting from four minutes up to roughly one and half day. sendmsg with MSG_FASTOPEN flag will succeed but it behaves as connect() then write(). Signed-off-by: Yuchung Cheng <ycheng@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 88693281da4c..c5cfd5ec3184 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2860,10 +2860,19 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
2860{ 2860{
2861 struct tcp_sock *tp = tcp_sk(sk); 2861 struct tcp_sock *tp = tcp_sk(sk);
2862 struct tcp_fastopen_request *fo = tp->fastopen_req; 2862 struct tcp_fastopen_request *fo = tp->fastopen_req;
2863 int space, i, err = 0, iovlen = fo->data->msg_iovlen; 2863 int syn_loss = 0, space, i, err = 0, iovlen = fo->data->msg_iovlen;
2864 struct sk_buff *syn_data = NULL, *data; 2864 struct sk_buff *syn_data = NULL, *data;
2865 unsigned long last_syn_loss = 0;
2866
2867 tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie,
2868 &syn_loss, &last_syn_loss);
2869 /* Recurring FO SYN losses: revert to regular handshake temporarily */
2870 if (syn_loss > 1 &&
2871 time_before(jiffies, last_syn_loss + (60*HZ << syn_loss))) {
2872 fo->cookie.len = -1;
2873 goto fallback;
2874 }
2865 2875
2866 tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie);
2867 if (fo->cookie.len <= 0) 2876 if (fo->cookie.len <= 0)
2868 goto fallback; 2877 goto fallback;
2869 2878