Author: tuexen Date: Wed Aug 9 13:26:12 2017 New Revision: 322315 URL: https://svnweb.freebsd.org/changeset/base/322315
Log: MFC r317208: 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 Differential Revision: https://reviews.freebsd.org/D10272 Modified: stable/10/sys/netinet/tcp_syncache.c stable/10/sys/netinet/tcp_syncache.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/netinet/tcp_syncache.c ============================================================================== --- stable/10/sys/netinet/tcp_syncache.c Wed Aug 9 13:25:27 2017 (r322314) +++ stable/10/sys/netinet/tcp_syncache.c Wed Aug 9 13:26:12 2017 (r322315) @@ -277,6 +277,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. */ @@ -357,6 +358,7 @@ syncache_insert(struct syncache *sc, struct syncache_h 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); } @@ -985,10 +987,13 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt /* * 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) { @@ -999,6 +1004,15 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt 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); @@ -1336,8 +1350,10 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *t * 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: stable/10/sys/netinet/tcp_syncache.h ============================================================================== --- stable/10/sys/netinet/tcp_syncache.h Wed Aug 9 13:25:27 2017 (r322314) +++ stable/10/sys/netinet/tcp_syncache.h Wed Aug 9 13:26:12 2017 (r322315) @@ -100,6 +100,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 _______________________________________________ svn-src-stable-10@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10 To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"