diff options
author | Yuchung Cheng <ycheng@google.com> | 2015-02-09 15:35:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-09 17:26:55 -0500 |
commit | 531c94a9681b8c253fd0490a4ca8bbe01a38c78b (patch) | |
tree | f15abdcc7f4af03a3cd80e234e68acc0601a7c5d /net/ipv4 | |
parent | 223ab8ffeb0c7883304d66e5891004643b0e1c0b (diff) |
tcp: don't include Fast Open option in SYN-ACK on pure SYN-data
If a server has enabled Fast Open and it receives a pure SYN-data
packet (without a Fast Open option), it won't accept the data but it
incorrectly returns a SYN-ACK with a Fast Open cookie and also
increments the SNMP stat LINUX_MIB_TCPFASTOPENPASSIVEFAIL.
This patch makes the server include a Fast Open cookie in SYN-ACK
only if the SYN has some Fast Open option (i.e., when client
requests or presents a cookie).
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/tcp_fastopen.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 815c85e3b1e0..53db2c309572 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c | |||
@@ -255,6 +255,9 @@ bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, | |||
255 | struct tcp_fastopen_cookie valid_foc = { .len = -1 }; | 255 | struct tcp_fastopen_cookie valid_foc = { .len = -1 }; |
256 | bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1; | 256 | bool syn_data = TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1; |
257 | 257 | ||
258 | if (foc->len == 0) /* Client requests a cookie */ | ||
259 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENCOOKIEREQD); | ||
260 | |||
258 | if (!((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) && | 261 | if (!((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) && |
259 | (syn_data || foc->len >= 0) && | 262 | (syn_data || foc->len >= 0) && |
260 | tcp_fastopen_queue_check(sk))) { | 263 | tcp_fastopen_queue_check(sk))) { |
@@ -265,7 +268,8 @@ bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, | |||
265 | if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD)) | 268 | if (syn_data && (sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD)) |
266 | goto fastopen; | 269 | goto fastopen; |
267 | 270 | ||
268 | if (tcp_fastopen_cookie_gen(req, skb, &valid_foc) && | 271 | if (foc->len >= 0 && /* Client presents or requests a cookie */ |
272 | tcp_fastopen_cookie_gen(req, skb, &valid_foc) && | ||
269 | foc->len == TCP_FASTOPEN_COOKIE_SIZE && | 273 | foc->len == TCP_FASTOPEN_COOKIE_SIZE && |
270 | foc->len == valid_foc.len && | 274 | foc->len == valid_foc.len && |
271 | !memcmp(foc->val, valid_foc.val, foc->len)) { | 275 | !memcmp(foc->val, valid_foc.val, foc->len)) { |
@@ -284,11 +288,10 @@ fastopen: | |||
284 | LINUX_MIB_TCPFASTOPENPASSIVE); | 288 | LINUX_MIB_TCPFASTOPENPASSIVE); |
285 | return true; | 289 | return true; |
286 | } | 290 | } |
287 | } | 291 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVEFAIL); |
292 | } else if (foc->len > 0) /* Client presents an invalid cookie */ | ||
293 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVEFAIL); | ||
288 | 294 | ||
289 | NET_INC_STATS_BH(sock_net(sk), foc->len ? | ||
290 | LINUX_MIB_TCPFASTOPENPASSIVEFAIL : | ||
291 | LINUX_MIB_TCPFASTOPENCOOKIEREQD); | ||
292 | *foc = valid_foc; | 295 | *foc = valid_foc; |
293 | return false; | 296 | return false; |
294 | } | 297 | } |