aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2015-02-09 15:35:23 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-09 17:26:55 -0500
commit531c94a9681b8c253fd0490a4ca8bbe01a38c78b (patch)
treef15abdcc7f4af03a3cd80e234e68acc0601a7c5d /net/ipv4
parent223ab8ffeb0c7883304d66e5891004643b0e1c0b (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.c13
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}