Date: Thu, 20 Apr 2017 19:19:34 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317208 - head/sys/netinet Message-ID: <201704201919.v3KJJYko052651@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Thu Apr 20 19:19:33 2017 New Revision: 317208 URL: https://svnweb.freebsd.org/changeset/base/317208 Log: Syncoockies can be used in combination with the syncache. If the cache overflows, syncookies are used. This patch restricts the usage of syncookies in this case: accept syncookies only if there was an overflow of the syncache recently. This mitigates a problem reported in PR217637, where is syncookie was accepted without any recent drops. Thanks to glebius@ for suggesting an improvement. PR: 217637 Reviewed by: gnn, glebius MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D10272 Modified: head/sys/netinet/tcp_syncache.c head/sys/netinet/tcp_syncache.h Modified: head/sys/netinet/tcp_syncache.c ============================================================================== --- head/sys/netinet/tcp_syncache.c Thu Apr 20 19:14:52 2017 (r317207) +++ head/sys/netinet/tcp_syncache.c Thu Apr 20 19:19:33 2017 (r317208) @@ -260,6 +260,7 @@ syncache_init(void) &V_tcp_syncache.hashbase[i].sch_mtx, 0); V_tcp_syncache.hashbase[i].sch_length = 0; V_tcp_syncache.hashbase[i].sch_sc = &V_tcp_syncache; + V_tcp_syncache.hashbase[i].sch_last_overflow = INT64_MIN; } /* Create the syncache entry zone. */ @@ -335,6 +336,7 @@ syncache_insert(struct syncache *sc, str KASSERT(!TAILQ_EMPTY(&sch->sch_bucket), ("sch->sch_length incorrect")); sc2 = TAILQ_LAST(&sch->sch_bucket, sch_head); + sch->sch_last_overflow = time_uptime; syncache_drop(sc2, sch); TCPSTAT_INC(tcps_sc_bucketoverflow); } @@ -974,10 +976,13 @@ syncache_expand(struct in_conninfo *inc, /* * There is no syncache entry, so see if this ACK is * a returning syncookie. To do this, first: - * A. See if this socket has had a syncache entry dropped in - * the past. We don't want to accept a bogus syncookie - * if we've never received a SYN. - * B. check that the syncookie is valid. If it is, then + * A. Check if syncookies are used in case of syncache + * overflows + * B. See if this socket has had a syncache entry dropped in + * the recent past. We don't want to accept a bogus + * syncookie if we've never received a SYN or accept it + * twice. + * C. check that the syncookie is valid. If it is, then * cobble up a fake syncache entry, and return. */ if (!V_tcp_syncookies) { @@ -988,6 +993,15 @@ syncache_expand(struct in_conninfo *inc, s, __func__); goto failed; } + if (!V_tcp_syncookiesonly && + sch->sch_last_overflow < time_uptime - SYNCOOKIE_LIFETIME) { + SCH_UNLOCK(sch); + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) + log(LOG_DEBUG, "%s; %s: Spurious ACK, " + "segment rejected (no syncache entry)\n", + s, __func__); + goto failed; + } bzero(&scs, sizeof(scs)); sc = syncookie_lookup(inc, sch, &scs, th, to, *lsop); SCH_UNLOCK(sch); @@ -1411,8 +1425,10 @@ syncache_add(struct in_conninfo *inc, st * entry and insert the new one. */ TCPSTAT_INC(tcps_sc_zonefail); - if ((sc = TAILQ_LAST(&sch->sch_bucket, sch_head)) != NULL) + if ((sc = TAILQ_LAST(&sch->sch_bucket, sch_head)) != NULL) { + sch->sch_last_overflow = time_uptime; syncache_drop(sc, sch); + } sc = uma_zalloc(V_tcp_syncache.zone, M_NOWAIT | M_ZERO); if (sc == NULL) { if (V_tcp_syncookies) { Modified: head/sys/netinet/tcp_syncache.h ============================================================================== --- head/sys/netinet/tcp_syncache.h Thu Apr 20 19:14:52 2017 (r317207) +++ head/sys/netinet/tcp_syncache.h Thu Apr 20 19:19:33 2017 (r317208) @@ -99,6 +99,7 @@ struct syncache_head { int sch_nextc; u_int sch_length; struct tcp_syncache *sch_sc; + time_t sch_last_overflow; }; #define SYNCOOKIE_SECRET_SIZE 16
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704201919.v3KJJYko052651>