summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/tcp_syncache.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/tcp_syncache.c')
-rw-r--r--freebsd/sys/netinet/tcp_syncache.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/freebsd/sys/netinet/tcp_syncache.c b/freebsd/sys/netinet/tcp_syncache.c
index bfbf9f42..468aaab7 100644
--- a/freebsd/sys/netinet/tcp_syncache.c
+++ b/freebsd/sys/netinet/tcp_syncache.c
@@ -156,7 +156,12 @@ static int syncookie_cmp(struct in_conninfo *inc, struct syncache_head *sch,
/*
* Transmit the SYN,ACK fewer times than TCP_MAXRXTSHIFT specifies.
- * 3 retransmits corresponds to a timeout of 3 * (1 + 2 + 4 + 8) == 45 seconds,
+ * 3 retransmits corresponds to a timeout with default values of
+ * tcp_rexmit_initial * ( 1 +
+ * tcp_backoff[1] +
+ * tcp_backoff[2] +
+ * tcp_backoff[3]) + 3 * tcp_rexmit_slop,
+ * 1000 ms * (1 + 2 + 4 + 8) + 3 * 200 ms = 15600 ms,
* the odds are that the user has given up attempting to connect by then.
*/
#define SYNCACHE_MAXREXMTS 3
@@ -421,9 +426,10 @@ syncache_timeout(struct syncache *sc, struct syncache_head *sch, int docallout)
int rexmt;
if (sc->sc_rxmits == 0)
- rexmt = TCPTV_RTOBASE;
+ rexmt = tcp_rexmit_initial;
else
- TCPT_RANGESET(rexmt, TCPTV_RTOBASE * tcp_syn_backoff[sc->sc_rxmits],
+ TCPT_RANGESET(rexmt,
+ tcp_rexmit_initial * tcp_backoff[sc->sc_rxmits],
tcp_rexmit_min, TCPTV_REXMTMAX);
sc->sc_rxttime = ticks + rexmt;
sc->sc_rxmits++;
@@ -773,6 +779,9 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
if (m != NULL && M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) {
inp->inp_flowid = m->m_pkthdr.flowid;
inp->inp_flowtype = M_HASHTYPE_GET(m);
+#ifdef NUMA
+ inp->inp_numa_domain = m->m_pkthdr.numa_domain;
+#endif
}
/*
@@ -1143,6 +1152,28 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
}
}
#endif /* TCP_SIGNATURE */
+
+ /*
+ * RFC 7323 PAWS: If we have a timestamp on this segment and
+ * it's less than ts_recent, drop it.
+ * XXXMT: RFC 7323 also requires to send an ACK.
+ * In tcp_input.c this is only done for TCP segments
+ * with user data, so be consistent here and just drop
+ * the segment.
+ */
+ if (sc->sc_flags & SCF_TIMESTAMP && to->to_flags & TOF_TS &&
+ TSTMP_LT(to->to_tsval, sc->sc_tsreflect)) {
+ SCH_UNLOCK(sch);
+ if ((s = tcp_log_addrs(inc, th, NULL, NULL))) {
+ log(LOG_DEBUG,
+ "%s; %s: SEG.TSval %u < TS.Recent %u, "
+ "segment dropped\n", s, __func__,
+ to->to_tsval, sc->sc_tsreflect);
+ free(s, M_TCPLOG);
+ }
+ return (-1); /* Do not send RST */
+ }
+
/*
* Pull out the entry to unlock the bucket row.
*
@@ -1522,7 +1553,6 @@ skip_alloc:
sc->sc_todctx = todctx;
#endif
sc->sc_irs = th->th_seq;
- sc->sc_iss = arc4random();
sc->sc_flags = 0;
sc->sc_flowlabel = 0;
@@ -1596,6 +1626,8 @@ skip_alloc:
if (V_tcp_syncookies)
sc->sc_iss = syncookie_generate(sch, sc);
+ else
+ sc->sc_iss = arc4random();
#ifdef INET6
if (autoflowlabel) {
if (V_tcp_syncookies)