Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Jun 2017 08:32:35 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r319400 - stable/11/sys/netinet
Message-ID:  <201706010832.v518WZjC026636@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Thu Jun  1 08:32:35 2017
New Revision: 319400
URL: https://svnweb.freebsd.org/changeset/base/319400

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/11/sys/netinet/tcp_syncache.c
  stable/11/sys/netinet/tcp_syncache.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/tcp_syncache.c
==============================================================================
--- stable/11/sys/netinet/tcp_syncache.c	Thu Jun  1 08:29:08 2017	(r319399)
+++ stable/11/sys/netinet/tcp_syncache.c	Thu Jun  1 08:32:35 2017	(r319400)
@@ -252,6 +252,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. */
@@ -327,6 +328,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);
 	}
@@ -966,10 +968,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) {
@@ -980,6 +985,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);
@@ -1399,8 +1413,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/11/sys/netinet/tcp_syncache.h
==============================================================================
--- stable/11/sys/netinet/tcp_syncache.h	Thu Jun  1 08:29:08 2017	(r319399)
+++ stable/11/sys/netinet/tcp_syncache.h	Thu Jun  1 08:32:35 2017	(r319400)
@@ -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?201706010832.v518WZjC026636>