diff options
author | Yuchung Cheng <ycheng@google.com> | 2012-07-19 02:43:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-19 14:02:03 -0400 |
commit | 67da22d23fa6f3324e03bcd0580b914b2e4afbf3 (patch) | |
tree | e794826d1dd7e30cf0885cbe93f22bc050c62359 /net | |
parent | aab4874355679c70f93993cf3b3fd74643b9ac33 (diff) |
net-tcp: Fast Open client - cookie-less mode
In trusted networks, e.g., intranet, data-center, the client does not
need to use Fast Open cookie to mitigate DoS attacks. In cookie-less
mode, sendmsg() with MSG_FASTOPEN flag will send SYN-data regardless
of cookie availability.
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')
-rw-r--r-- | net/ipv4/tcp_input.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 6 |
2 files changed, 11 insertions, 3 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c49a4fc175b..e67d685a6c0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5650,7 +5650,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5650 | struct tcp_fastopen_cookie *cookie) | 5650 | struct tcp_fastopen_cookie *cookie) |
5651 | { | 5651 | { |
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 = tp->syn_data ? tcp_write_queue_head(sk) : NULL; |
5654 | u16 mss = tp->rx_opt.mss_clamp; | 5654 | u16 mss = tp->rx_opt.mss_clamp; |
5655 | bool syn_drop; | 5655 | bool syn_drop; |
5656 | 5656 | ||
@@ -5665,6 +5665,9 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5665 | mss = opt.mss_clamp; | 5665 | mss = opt.mss_clamp; |
5666 | } | 5666 | } |
5667 | 5667 | ||
5668 | if (!tp->syn_fastopen) /* Ignore an unsolicited cookie */ | ||
5669 | cookie->len = -1; | ||
5670 | |||
5668 | /* The SYN-ACK neither has cookie nor acknowledges the data. Presumably | 5671 | /* The SYN-ACK neither has cookie nor acknowledges the data. Presumably |
5669 | * the remote receives only the retransmitted (regular) SYNs: either | 5672 | * the remote receives only the retransmitted (regular) SYNs: either |
5670 | * the original SYN-data or the corresponding SYN-ACK is lost. | 5673 | * the original SYN-data or the corresponding SYN-ACK is lost. |
@@ -5816,7 +5819,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
5816 | 5819 | ||
5817 | tcp_finish_connect(sk, skb); | 5820 | tcp_finish_connect(sk, skb); |
5818 | 5821 | ||
5819 | if (tp->syn_fastopen && tcp_rcv_fastopen_synack(sk, skb, &foc)) | 5822 | if ((tp->syn_fastopen || tp->syn_data) && |
5823 | tcp_rcv_fastopen_synack(sk, skb, &foc)) | ||
5820 | return -1; | 5824 | return -1; |
5821 | 5825 | ||
5822 | if (sk->sk_write_pending || | 5826 | if (sk->sk_write_pending || |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c5cfd5ec318..27a32acfdb6 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2864,6 +2864,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
2864 | struct sk_buff *syn_data = NULL, *data; | 2864 | struct sk_buff *syn_data = NULL, *data; |
2865 | unsigned long last_syn_loss = 0; | 2865 | unsigned long last_syn_loss = 0; |
2866 | 2866 | ||
2867 | tp->rx_opt.mss_clamp = tp->advmss; /* If MSS is not cached */ | ||
2867 | tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie, | 2868 | tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie, |
2868 | &syn_loss, &last_syn_loss); | 2869 | &syn_loss, &last_syn_loss); |
2869 | /* Recurring FO SYN losses: revert to regular handshake temporarily */ | 2870 | /* Recurring FO SYN losses: revert to regular handshake temporarily */ |
@@ -2873,7 +2874,9 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
2873 | goto fallback; | 2874 | goto fallback; |
2874 | } | 2875 | } |
2875 | 2876 | ||
2876 | if (fo->cookie.len <= 0) | 2877 | if (sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) |
2878 | fo->cookie.len = -1; | ||
2879 | else if (fo->cookie.len <= 0) | ||
2877 | goto fallback; | 2880 | goto fallback; |
2878 | 2881 | ||
2879 | /* MSS for SYN-data is based on cached MSS and bounded by PMTU and | 2882 | /* MSS for SYN-data is based on cached MSS and bounded by PMTU and |
@@ -2916,6 +2919,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
2916 | fo->copied = data->len; | 2919 | fo->copied = data->len; |
2917 | 2920 | ||
2918 | if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) { | 2921 | if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) { |
2922 | tp->syn_data = (fo->copied > 0); | ||
2919 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE); | 2923 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE); |
2920 | goto done; | 2924 | goto done; |
2921 | } | 2925 | } |