svn commit: r317208 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Thu Apr 20 19:19:35 UTC 2017
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
More information about the svn-src-all
mailing list