aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2015-05-14 17:26:56 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-14 22:32:17 -0400
commit264ea103a7473f51aced838e68ed384ea2c759f5 (patch)
tree0f8366835d004fb0ee387d876f6c4b301a0ff89e /include/net/tcp.h
parentc24a59649f3c8f4f78adc2d0e31423fa883b012b (diff)
tcp: syncookies: extend validity range
Now we allow storing more request socks per listener, we might hit syncookie mode less often and hit following bug in our stack : When we send a burst of syncookies, then exit this mode, tcp_synq_no_recent_overflow() can return false if the ACK packets coming from clients are coming three seconds after the end of syncookie episode. This is a way too strong requirement and conflicts with rest of syncookie code which allows ACK to be aged up to 2 minutes. Perfectly valid ACK packets are dropped just because clients might be in a crowded wifi environment or on another planet. So let's fix this, and also change tcp_synq_overflow() to not dirty a cache line for every syncookie we send, as we are under attack. Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Florian Westphal <fw@strlen.de> Acked-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h38
1 files changed, 24 insertions, 14 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index b8ea12880fd9..7ace6acbf5fd 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -326,18 +326,6 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
326 326
327bool tcp_check_oom(struct sock *sk, int shift); 327bool tcp_check_oom(struct sock *sk, int shift);
328 328
329/* syncookies: remember time of last synqueue overflow */
330static inline void tcp_synq_overflow(struct sock *sk)
331{
332 tcp_sk(sk)->rx_opt.ts_recent_stamp = jiffies;
333}
334
335/* syncookies: no recent synqueue overflow on this listening socket? */
336static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
337{
338 unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
339 return time_after(jiffies, last_overflow + TCP_TIMEOUT_FALLBACK);
340}
341 329
342extern struct proto tcp_prot; 330extern struct proto tcp_prot;
343 331
@@ -483,13 +471,35 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb);
483 * i.e. a sent cookie is valid only at most for 2*60 seconds (or less if 471 * i.e. a sent cookie is valid only at most for 2*60 seconds (or less if
484 * the counter advances immediately after a cookie is generated). 472 * the counter advances immediately after a cookie is generated).
485 */ 473 */
486#define MAX_SYNCOOKIE_AGE 2 474#define MAX_SYNCOOKIE_AGE 2
475#define TCP_SYNCOOKIE_PERIOD (60 * HZ)
476#define TCP_SYNCOOKIE_VALID (MAX_SYNCOOKIE_AGE * TCP_SYNCOOKIE_PERIOD)
477
478/* syncookies: remember time of last synqueue overflow
479 * But do not dirty this field too often (once per second is enough)
480 */
481static inline void tcp_synq_overflow(struct sock *sk)
482{
483 unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
484 unsigned long now = jiffies;
485
486 if (time_after(now, last_overflow + HZ))
487 tcp_sk(sk)->rx_opt.ts_recent_stamp = now;
488}
489
490/* syncookies: no recent synqueue overflow on this listening socket? */
491static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
492{
493 unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
494
495 return time_after(jiffies, last_overflow + TCP_SYNCOOKIE_VALID);
496}
487 497
488static inline u32 tcp_cookie_time(void) 498static inline u32 tcp_cookie_time(void)
489{ 499{
490 u64 val = get_jiffies_64(); 500 u64 val = get_jiffies_64();
491 501
492 do_div(val, 60 * HZ); 502 do_div(val, TCP_SYNCOOKIE_PERIOD);
493 return val; 503 return val;
494} 504}
495 505