aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.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_input.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_input.c')
-rw-r--r--net/ipv4/tcp_input.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 38b6a811edfc..c49a4fc175bd 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5652,6 +5652,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
5652 struct tcp_sock *tp = tcp_sk(sk); 5652 struct tcp_sock *tp = tcp_sk(sk);
5653 struct sk_buff *data = tcp_write_queue_head(sk); 5653 struct sk_buff *data = tcp_write_queue_head(sk);
5654 u16 mss = tp->rx_opt.mss_clamp; 5654 u16 mss = tp->rx_opt.mss_clamp;
5655 bool syn_drop;
5655 5656
5656 if (mss == tp->rx_opt.user_mss) { 5657 if (mss == tp->rx_opt.user_mss) {
5657 struct tcp_options_received opt; 5658 struct tcp_options_received opt;
@@ -5664,7 +5665,14 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
5664 mss = opt.mss_clamp; 5665 mss = opt.mss_clamp;
5665 } 5666 }
5666 5667
5667 tcp_fastopen_cache_set(sk, mss, cookie); 5668 /* The SYN-ACK neither has cookie nor acknowledges the data. Presumably
5669 * the remote receives only the retransmitted (regular) SYNs: either
5670 * the original SYN-data or the corresponding SYN-ACK is lost.
5671 */
5672 syn_drop = (cookie->len <= 0 && data &&
5673 inet_csk(sk)->icsk_retransmits);
5674
5675 tcp_fastopen_cache_set(sk, mss, cookie, syn_drop);
5668 5676
5669 if (data) { /* Retransmit unacked data in SYN */ 5677 if (data) { /* Retransmit unacked data in SYN */
5670 tcp_retransmit_skb(sk, data); 5678 tcp_retransmit_skb(sk, data);