-/* $OpenBSD: dt_prov_static.c,v 1.21 2023/08/14 08:33:24 mpi Exp $ */
+/* $OpenBSD: dt_prov_static.c,v 1.22 2023/08/28 14:50:01 bluhm Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
DT_STATIC_PROBE3(refcnt, ifmaddr, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, inpcb, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, rtentry, "void *", "int", "int");
+DT_STATIC_PROBE3(refcnt, syncache, "void *", "int", "int");
DT_STATIC_PROBE3(refcnt, tdb, "void *", "int", "int");
/*
&_DT_STATIC_P(refcnt, ifmaddr),
&_DT_STATIC_P(refcnt, inpcb),
&_DT_STATIC_P(refcnt, rtentry),
+ &_DT_STATIC_P(refcnt, syncache),
&_DT_STATIC_P(refcnt, tdb),
};
-/* $OpenBSD: tcp_input.c,v 1.389 2023/07/06 09:15:23 bluhm Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.390 2023/08/28 14:50:01 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
void syn_cache_rm(struct syn_cache *);
int syn_cache_respond(struct syn_cache *, struct mbuf *, uint64_t);
void syn_cache_timer(void *);
-void syn_cache_reaper(void *);
void syn_cache_insert(struct syn_cache *, struct tcpcb *);
void syn_cache_reset(struct sockaddr *, struct sockaddr *,
struct tcphdr *, u_int);
int tcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
int tcp_syn_use_limit = 100000;
+struct pool syn_cache_pool;
struct syn_cache_set tcp_syn_cache[2];
int tcp_syn_cache_active;
TAILQ_REMOVE(&sc->sc_buckethead->sch_bucket, sc, sc_bucketq);
sc->sc_tp = NULL;
LIST_REMOVE(sc, sc_tpq);
+ refcnt_rele(&sc->sc_refcnt);
sc->sc_buckethead->sch_length--;
- timeout_del(&sc->sc_timer);
+ if (timeout_del(&sc->sc_timer))
+ refcnt_rele(&sc->sc_refcnt);
sc->sc_set->scs_count--;
}
void
syn_cache_put(struct syn_cache *sc)
{
+ if (refcnt_rele(&sc->sc_refcnt) == 0)
+ return;
+
m_free(sc->sc_ipopts);
if (sc->sc_route4.ro_rt != NULL) {
rtfree(sc->sc_route4.ro_rt);
sc->sc_route4.ro_rt = NULL;
}
- timeout_set(&sc->sc_timer, syn_cache_reaper, sc);
- timeout_add(&sc->sc_timer, 0);
+ pool_put(&syn_cache_pool, sc);
}
-struct pool syn_cache_pool;
-
/*
* We don't estimate RTT with SYNs, so each packet starts with the default
* RTT and each timer step has a fixed timeout value.
TCPT_RANGESET((sc)->sc_rxtcur, \
TCPTV_SRTTDFLT * tcp_backoff[(sc)->sc_rxtshift], TCPTV_MIN, \
TCPTV_REXMTMAX); \
- if (!timeout_initialized(&(sc)->sc_timer)) \
- timeout_set_proc(&(sc)->sc_timer, syn_cache_timer, (sc)); \
- timeout_add_msec(&(sc)->sc_timer, (sc)->sc_rxtcur); \
+ if (timeout_add_msec(&(sc)->sc_timer, (sc)->sc_rxtcur)) \
+ refcnt_take(&(sc)->sc_refcnt); \
} while (/*CONSTCOND*/0)
void
SYN_CACHE_TIMER_ARM(sc);
/* Link it from tcpcb entry */
+ refcnt_take(&sc->sc_refcnt);
LIST_INSERT_HEAD(&tp->t_sc, sc, sc_tpq);
/* Put it into the bucket. */
{
struct syn_cache *sc = arg;
uint64_t now;
+ int lastref;
NET_LOCK();
if (sc->sc_flags & SCF_DEAD)
- goto out;
+ goto freeit;
now = tcp_now();
sc->sc_rxtshift++;
SYN_CACHE_TIMER_ARM(sc);
- out:
+ /*
+ * Decrement reference of this timer. We know there is another timer
+ * as we just added it. So just deref, free is not necessary.
+ */
+ lastref = refcnt_rele(&sc->sc_refcnt);
+ KASSERT(lastref == 0);
+ (void)lastref;
NET_UNLOCK();
return;
dropit:
tcpstat_inc(tcps_sc_timed_out);
syn_cache_rm(sc);
+ /* Decrement reference of the timer and free object after remove. */
+ lastref = refcnt_rele(&sc->sc_refcnt);
+ KASSERT(lastref == 0);
+ (void)lastref;
+ freeit:
syn_cache_put(sc);
NET_UNLOCK();
}
-void
-syn_cache_reaper(void *arg)
-{
- struct syn_cache *sc = arg;
-
- pool_put(&syn_cache_pool, (sc));
- return;
-}
-
/*
* Remove syn cache created by the specified tcb entry,
* because this does not make sense to keep them
m_free(ipopts);
return (-1);
}
+ refcnt_init_trace(&sc->sc_refcnt, DT_REFCNT_IDX_SYNCACHE);
+ timeout_set_proc(&sc->sc_timer, syn_cache_timer, sc);
/*
* Fill in the cache, and put the necessary IP and TCP