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.cWed Aug 9 13:25:27 2017
(r322314)
+++ stable/10/sys/netinet/tcp_syncache.cWed Aug 9 13:26:12 2017
(r322315)
@@ -277,6 +277,7 @@ syncache_init(void)
_tcp_syncache.hashbase[i].sch_mtx, 0);
V_tcp_syncache.hashbase[i].sch_length = 0;
V_tcp_syncache.hashbase[i].sch_sc = _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_bucket),
("sch->sch_length incorrect"));
sc2 = TAILQ_LAST(>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(, sizeof(scs));
sc = syncookie_lookup(inc, sch, , 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_bucket, sch_head)) != NULL)
+ if ((sc = TAILQ_LAST(>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.hWed Aug 9 13:25:27 2017
(r322314)
+++ stable/10/sys/netinet/tcp_syncache.hWed 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;
};
#defineSYNCOOKIE_SECRET_SIZE 16