45#include <sys/refcount.h>
46#include <sys/kernel.h>
47#include <sys/sysctl.h>
48#include <sys/limits.h>
51#include <sys/malloc.h>
54#include <sys/random.h>
55#include <sys/socket.h>
56#include <sys/socketvar.h>
57#include <sys/syslog.h>
61#include <crypto/siphash/siphash.h>
66#include <net/if_var.h>
81#include <netinet6/nd6.h>
82#include <netinet6/ip6_var.h>
83#include <netinet6/in6_pcb.h>
94#include <netinet6/tcp6_var.h>
102#include <netipsec/ipsec_support.h>
104#include <machine/in_cksum.h>
106#include <security/mac/mac_framework.h>
109#define V_tcp_syncookies VNET(tcp_syncookies)
110SYSCTL_INT(_net_inet_tcp, OID_AUTO, syncookies, CTLFLAG_VNET | CTLFLAG_RW,
111 &VNET_NAME(tcp_syncookies), 0,
112 "Use TCP SYN cookies if the syncache overflows");
115#define V_tcp_syncookiesonly VNET(tcp_syncookiesonly)
116SYSCTL_INT(_net_inet_tcp, OID_AUTO, syncookies_only, CTLFLAG_VNET | CTLFLAG_RW,
117 &VNET_NAME(tcp_syncookiesonly), 0,
118 "Use only TCP SYN cookies");
121#define V_functions_inherit_listen_socket_stack \
122 VNET(functions_inherit_listen_socket_stack)
123SYSCTL_INT(_net_inet_tcp, OID_AUTO, functions_inherit_listen_socket_stack,
124 CTLFLAG_VNET | CTLFLAG_RW,
125 &VNET_NAME(functions_inherit_listen_socket_stack), 0,
126 "Inherit listen socket's stack");
129#define ADDED_BY_TOE(sc) ((sc)->sc_tod != NULL)
168#define SYNCACHE_MAXREXMTS 3
171#define TCP_SYNCACHE_HASHSIZE 512
172#define TCP_SYNCACHE_BUCKETLIMIT 30
175#define V_tcp_syncache VNET(tcp_syncache)
178 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
181SYSCTL_UINT(_net_inet_tcp_syncache, OID_AUTO, bucketlimit, CTLFLAG_VNET | CTLFLAG_RDTUN,
183 "Per-bucket hash limit for syncache");
185SYSCTL_UINT(_net_inet_tcp_syncache, OID_AUTO, cachelimit, CTLFLAG_VNET | CTLFLAG_RDTUN,
187 "Overall entry limit for syncache");
192SYSCTL_UINT(_net_inet_tcp_syncache, OID_AUTO, hashsize, CTLFLAG_VNET | CTLFLAG_RDTUN,
194 "Size of TCP syncache hashtable");
196SYSCTL_BOOL(_net_inet_tcp_syncache, OID_AUTO, see_other, CTLFLAG_VNET |
198 "All syncache(4) entries are visible, ignoring UID/GID, jail(2) "
199 "and mac(4) checks");
208 error = sysctl_handle_int(oidp, &
new, 0, req);
209 if ((error == 0) && (req->newptr != NULL)) {
219 CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
222 "Limit on SYN/ACK retransmissions");
225SYSCTL_INT(_net_inet_tcp_syncache, OID_AUTO, rst_on_sock_fail,
226 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_sc_rst_sock_fail), 0,
227 "Send reset on socket allocation failure");
231#define SCH_LOCK(sch) mtx_lock(&(sch)->sch_mtx)
232#define SCH_UNLOCK(sch) mtx_unlock(&(sch)->sch_mtx)
233#define SCH_LOCK_ASSERT(sch) mtx_assert(&(sch)->sch_mtx, MA_OWNED)
247 mac_syncache_destroy(&sc->
sc_label);
263 TUNABLE_INT_FETCH(
"net.inet.tcp.syncache.hashsize",
265 TUNABLE_INT_FETCH(
"net.inet.tcp.syncache.bucketlimit",
269 printf(
"WARNING: syncache hash size is not a power of 2.\n");
277 TUNABLE_INT_FETCH(
"net.inet.tcp.syncache.cachelimit",
282 sizeof(
struct syncache_head), M_SYNCACHE, M_WAITOK | M_ZERO);
303 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
315 mtx_init(&
V_tcp_syncache.pause_mtx,
"tcp_sc_pause", NULL, MTX_DEF);
325syncache_destroy(
void)
351 TAILQ_FOREACH_SAFE(sc, &sch->sch_bucket, sc_hash, nsc)
354 KASSERT(TAILQ_EMPTY(&sch->sch_bucket),
355 (
"%s: sch->sch_bucket not empty", __func__));
356 KASSERT(sch->
sch_length == 0, (
"%s: sch->sch_length %d not 0",
362 (
"%s: cache_count not 0", __func__));
387 KASSERT(!TAILQ_EMPTY(&sch->sch_bucket),
388 (
"sch->sch_length incorrect"));
390 sc2 = TAILQ_LAST(&sch->sch_bucket, sch_head);
396 TAILQ_INSERT_HEAD(&sch->sch_bucket, sc, sc_hash);
400 if (ADDED_BY_TOE(sc)) {
429 TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
433 if (ADDED_BY_TOE(sc)) {
477 struct epoch_tracker et;
501 TAILQ_FOREACH_SAFE(sc, &sch->sch_bucket, sc_hash, nsc) {
524 log(LOG_DEBUG,
"%s; %s: Retransmits exhausted, "
525 "giving up and removing syncache entry\n",
534 log(LOG_DEBUG,
"%s; %s: Response timeout, "
535 "retransmitting (%u) SYN|ACK\n",
546 if (!TAILQ_EMPTY(&(sch)->sch_bucket))
547 callout_reset(&(sch)->sch_timer, (sch)->sch_nextc - tick,
600 TAILQ_FOREACH(sc, &sch->sch_bucket, sc_hash)
633 log(LOG_DEBUG,
"%s; %s: Spurious RST with ACK, SYN or "
634 "FIN flag set, segment ignored\n", s, __func__);
649 log(LOG_DEBUG,
"%s; %s: Spurious RST without matching "
650 "syncache entry (possibly syncookie only), "
651 "segment ignored\n", s, __func__);
659 log(LOG_DEBUG,
"%s; %s: Spurious RST with matching "
660 "syncache entry but non-matching UDP encaps port, "
661 "segment ignored\n", s, __func__);
696 th->th_seq == sc->
sc_irs + 1) {
700 "%s; %s: Our SYN|ACK was rejected, "
701 "connection attempt aborted by remote "
709 log(LOG_DEBUG,
"%s; %s: RST with invalid "
710 " SEQ %u != NXT %u (+WND %u), "
711 "sending challenge ACK\n",
718 log(LOG_DEBUG,
"%s; %s: RST with invalid SEQ %u != "
719 "NXT %u (+WND %u), segment ignored\n",
741 if ((sc != NULL) && (sc->
sc_port == port)) {
766 if (ntohl(th_seq) != sc->
sc_iss)
792static struct socket *
796 struct inpcb *inp = NULL;
810 so = sonewconn(lso, 0);
819 log(LOG_DEBUG,
"%s; %s: Socket create failed "
820 "due to limits or memory shortage\n",
827 mac_socketpeer_set_from_mbuf(m, so);
850 inp->in6p_laddr = sc->
sc_inc.inc6_laddr;
857 inp->inp_laddr = sc->
sc_inc.inc_laddr;
866 if (m != NULL && M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) {
874 inp->inp_lport = sc->
sc_inc.inc_lport;
896 struct in6_addr laddr6;
897 struct sockaddr_in6 sin6;
899 sin6.sin6_family = AF_INET6;
900 sin6.sin6_len =
sizeof(sin6);
901 sin6.sin6_addr = sc->
sc_inc.inc6_faddr;
902 sin6.sin6_port = sc->
sc_inc.inc_fport;
903 sin6.sin6_flowinfo = sin6.sin6_scope_id = 0;
904 laddr6 = inp->in6p_laddr;
905 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
906 inp->in6p_laddr = sc->
sc_inc.inc6_laddr;
907 if ((error = in6_pcbconnect_mbuf(inp, (
struct sockaddr *)&sin6,
908 thread0.td_ucred, m,
false)) != 0) {
909 inp->in6p_laddr = laddr6;
911 log(LOG_DEBUG,
"%s; %s: in6_pcbconnect failed "
920 inp->
inp_flow &= ~IPV6_FLOWLABEL_MASK;
924#if defined(INET) && defined(INET6)
944 laddr = inp->inp_laddr;
946 inp->inp_laddr = sc->
sc_inc.inc_laddr;
948 thread0.td_ucred,
false)) != 0) {
949 inp->inp_laddr = laddr;
951 log(LOG_DEBUG,
"%s; %s: in_pcbconnect failed "
961#if defined(IPSEC) || defined(IPSEC_SUPPORT)
963 if (ipsec_copy_pcbpolicy(
sotoinpcb(lso), inp) != 0)
964 printf(
"syncache_socket: could not copy policy\n");
984 KASSERT(rblk != NULL,
985 (
"cannot find blk %p out of syncache?", blk));
1023#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1053 if (ADDED_BY_TOE(sc)) {
1091 struct socket **lsop,
struct mbuf *m,
uint16_t port)
1100 KASSERT((
tcp_get_flags(th) & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK,
1101 (
"%s: can handle only ACK", __func__));
1119 syncookie_cmp(inc, sch, sc, th, to, *lsop, port);
1138 log(LOG_DEBUG,
"%s; %s: Spurious ACK, "
1139 "segment rejected (syncookies disabled)\n",
1147 log(LOG_DEBUG,
"%s; %s: Spurious ACK, "
1148 "segment rejected (no syncache entry)\n",
1152 bzero(&scs,
sizeof(scs));
1158 log(LOG_DEBUG,
"%s; %s: Segment failed "
1159 "SYNCOOKIE authentication, segment rejected "
1160 "(probably spoofed)\n", s, __func__);
1163#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1166 (!TCPMD5_ENABLED() ||
1170 log(LOG_DEBUG,
"%s; %s: Segment rejected, "
1171 "MD5 signature doesn't match.\n",
1184#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1197 log(LOG_DEBUG,
"%s; %s: Segment "
1198 "rejected, MD5 signature wasn't "
1199 "provided.\n", s, __func__);
1204 if (!TCPMD5_ENABLED() ||
1209 log(LOG_DEBUG,
"%s; %s: Segment "
1210 "rejected, MD5 signature doesn't "
1211 "match.\n", s, __func__);
1232 "%s; %s: SEG.TSval %u < TS.Recent %u, "
1233 "segment dropped\n", s, __func__,
1249 log(LOG_DEBUG,
"%s; %s: Timestamp not "
1250 "expected, segment processed normally\n",
1268 "%s; %s: Timestamp missing, "
1269 "segment processed normally\n",
1277 "%s; %s: Timestamp missing, "
1278 "segment silently dropped\n",
1296 TAILQ_REMOVE(&sch->sch_bucket, sc, sc_hash);
1299 if (ADDED_BY_TOE(sc)) {
1312 if (th->th_ack != sc->
sc_iss + 1) {
1314 log(LOG_DEBUG,
"%s; %s: ACK %u != ISS+1 %u, segment "
1315 "rejected\n", s, __func__, th->th_ack, sc->
sc_iss);
1326 log(LOG_DEBUG,
"%s; %s: SEQ %u != IRS+1 %u, segment "
1327 "rejected\n", s, __func__, th->th_seq, sc->
sc_irs);
1343 if (sc != NULL && sc != &scs)
1351static struct socket *
1353 uint64_t response_cookie)
1357 unsigned int *pending_counter;
1366 atomic_subtract_int(pending_counter, 1);
1403 struct inpcb *inp,
struct socket *so,
struct mbuf *m,
void *tod,
1407 struct socket *rv = NULL;
1410 struct mbuf *ipopts = NULL;
1415 int autoflowlabel = 0;
1418 struct label *maclabel;
1422 uint64_t tfo_response_cookie;
1423 unsigned int *tfo_pending = NULL;
1424 int tfo_cookie_valid = 0;
1425 int tfo_response_cookie_valid = 0;
1429 KASSERT((
tcp_get_flags(th) & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN,
1430 (
"%s: unexpected tcp flags", __func__));
1436 KASSERT(SOLISTENING(so), (
"%s: %p not listening", __func__, so));
1445 ip_ttl = in6_selecthlim(inp, NULL);
1454#if defined(INET6) && defined(INET)
1463 win = so->sol_sbrcv_hiwat;
1476 (so->sol_qlimit / 2)) {
1481 &tfo_response_cookie);
1482 tfo_cookie_valid = (result > 0);
1483 tfo_response_cookie_valid = (result >= 0);
1494 if (mac_syncache_init(&maclabel) != 0) {
1498 mac_syncache_create(maclabel, inp);
1500 if (!tfo_cookie_valid)
1515#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1526 if (!TCPMD5_ENABLED() ||
1530 if (TCPMD5_ENABLED() &&
1531 TCPMD5_INPUT(m, NULL, NULL) != ENOENT)
1559 if (tfo_cookie_valid)
1582 ((
tcp_get_flags(th) & (TH_ECE|TH_CWR)) != (TH_ECE|TH_CWR))) {
1591 mac_syncache_destroy(&maclabel);
1593 TCP_PROBE5(receive, NULL, NULL, m, NULL, th);
1596 log(LOG_DEBUG,
"%s; %s: Received duplicate SYN, "
1597 "resetting timer and retransmitting SYN|ACK\n",
1611 if (tfo_cookie_valid) {
1612 bzero(&scs,
sizeof(scs));
1622 bzero(&scs,
sizeof(scs));
1633 if ((sc = TAILQ_LAST(&sch->sch_bucket, sch_head)) != NULL) {
1641 bzero(&scs,
sizeof(scs));
1645 (
"%s: bucket unexpectedly unlocked",
1649 (void) m_free(ipopts);
1656 if (!tfo_cookie_valid && tfo_response_cookie_valid)
1685 win = imin(win, TCP_MAXWIN);
1723 while (wscale < TCP_MAX_WINSHIFT &&
1724 (TCP_MAXWIN << wscale) < sb_max)
1731#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1753 sc->
sc_iss = arc4random();
1755 if (autoflowlabel) {
1766 if (tfo_cookie_valid) {
1772 TCP_PROBE5(receive, NULL, NULL, m, NULL, th);
1779 else if (sc != &scs)
1791 TCP_PROBE5(receive, NULL, NULL, m, NULL, th);
1801 if (tfo_pending != NULL)
1809 mac_syncache_destroy(&maclabel);
1821 struct ip *
ip = NULL;
1823 struct tcphdr *th = NULL;
1824 struct udphdr *udp = NULL;
1825 int optlen, error = 0;
1826 u_int16_t hlen, tlen, mssopt, ulen;
1839 tlen = hlen +
sizeof(
struct tcphdr);
1841 tlen +=
sizeof(
struct udphdr);
1850 KASSERT(max_linkhdr + tlen + TCP_MAXOLEN <= MHLEN,
1851 (
"syncache: mbuf too small: hlen %u, sc_port %u, max_linkhdr %d + "
1852 "tlen %d + TCP_MAXOLEN %ju <= MHLEN %d", hlen, sc->
sc_port,
1853 max_linkhdr, tlen, (uintmax_t)TCP_MAXOLEN, MHLEN));
1856 m = m_gethdr(M_NOWAIT, MT_DATA);
1860 mac_syncache_create_mbuf(sc->
sc_label, m);
1862 m->m_data += max_linkhdr;
1864 m->m_pkthdr.len = tlen;
1865 m->m_pkthdr.rcvif = NULL;
1869 ip6 = mtod(m,
struct ip6_hdr *);
1873 ip6->ip6_plen = htons(tlen - hlen);
1876 ip6->ip6_flow &= ~IPV6_FLOWINFO_MASK;
1880 udp = (
struct udphdr *)(ip6 + 1);
1883 ulen = (tlen -
sizeof(
struct ip6_hdr));
1884 th = (
struct tcphdr *)(udp + 1);
1887 th = (
struct tcphdr *)(ip6 + 1);
1889 ip6->ip6_flow |= htonl(sc->
sc_ip_tos << 20);
1892#if defined(INET6) && defined(INET)
1897 ip = mtod(m,
struct ip *);
1920 th = (
struct tcphdr *)(
ip + 1);
1926 ulen = (tlen -
sizeof(
struct ip));
1927 th = (
struct tcphdr *)(udp + 1);
1931 th->th_sport = sc->
sc_inc.inc_lport;
1932 th->th_dport = sc->
sc_inc.inc_fport;
1935 th->th_seq = htonl(sc->
sc_iss);
1937 th->th_seq = htonl(sc->
sc_iss + 1);
1938 th->th_ack = htonl(sc->
sc_irs + 1);
1939 th->th_off =
sizeof(
struct tcphdr) >> 2;
1940 th->th_win = htons(sc->
sc_wnd);
1950 if (flags & TH_SYN) {
1959#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1979 th->th_off = (
sizeof(
struct tcphdr) + optlen) >> 2;
1981 m->m_pkthdr.len += optlen;
1984 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) + optlen);
1988#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1991 (
"tcp_addoptions() didn't set tcp_signature"));
1994 if (!TCPMD5_ENABLED() ||
2014 if (m0 != NULL && M_HASHTYPE_GET(m0) != M_HASHTYPE_NONE) {
2015 m->m_pkthdr.flowid = m0->m_pkthdr.flowid;
2016 M_HASHTYPE_SET(m, M_HASHTYPE_GET(m0));
2021 m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
2022 m->m_pkthdr.csum_data = offsetof(
struct udphdr, uh_sum);
2023 udp->
uh_sum = in6_cksum_pseudo(ip6, ulen,
2025 th->th_sum = htons(0);
2027 m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
2028 m->m_pkthdr.csum_data = offsetof(
struct tcphdr, th_sum);
2029 th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen,
2034 if (ADDED_BY_TOE(sc)) {
2043 error = ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
2046#if defined(INET6) && defined(INET)
2052 m->m_pkthdr.csum_flags = CSUM_UDP;
2053 m->m_pkthdr.csum_data = offsetof(
struct udphdr, uh_sum);
2056 th->th_sum = htons(0);
2058 m->m_pkthdr.csum_flags = CSUM_TCP;
2059 m->m_pkthdr.csum_data = offsetof(
struct tcphdr, th_sum);
2064 if (ADDED_BY_TOE(sc)) {
2203 uint8_t *secbits, uintptr_t secmod)
2208 SipHash24_Init(&ctx);
2209 SipHash_SetKey(&ctx, secbits);
2213 SipHash_Update(&ctx, &inc->inc_faddr,
sizeof(inc->inc_faddr));
2214 SipHash_Update(&ctx, &inc->inc_laddr,
sizeof(inc->inc_laddr));
2219 SipHash_Update(&ctx, &inc->inc6_faddr,
sizeof(inc->inc6_faddr));
2220 SipHash_Update(&ctx, &inc->inc6_laddr,
sizeof(inc->inc6_laddr));
2224 SipHash_Update(&ctx, &inc->inc_fport,
sizeof(inc->inc_fport));
2225 SipHash_Update(&ctx, &inc->inc_lport,
sizeof(inc->inc_lport));
2226 SipHash_Update(&ctx, &irs,
sizeof(irs));
2227 SipHash_Update(&ctx, &flags,
sizeof(flags));
2228 SipHash_Update(&ctx, &secmod,
sizeof(secmod));
2229 SipHash_Final((u_int8_t *)&siphash, &ctx);
2231 return (siphash[0] ^ siphash[1]);
2237 u_int i, secbit, wscale;
2249 cookie.flags.mss_idx = i;
2261 cookie.flags.wscale_idx = i;
2266 cookie.flags.sack_ok = 1;
2270 cookie.flags.odd_even = secbit;
2283 iss |=
cookie.cookie ^ (hash >> 24);
2297 int wnd, wscale = 0;
2304 ack = th->th_ack - 1;
2305 seq = th->th_seq - 1;
2311 cookie.cookie = (ack & 0xff) ^ (ack >> 24);
2319 if ((ack & ~0xff) != (hash & ~0xff))
2349 while (wscale < TCP_MAX_WINSHIFT && (TCP_MAXWIN << wscale) < sb_max)
2353 if (
cookie.flags.wscale_idx > 0) {
2359 wnd = lso->sol_sbrcv_hiwat;
2361 wnd = imin(wnd, TCP_MAXWIN);
2364 if (
cookie.flags.sack_ok)
2393 bzero(&scs,
sizeof(scs));
2401 log(LOG_DEBUG,
"%s; %s: mss different %i vs %i\n",
2405 log(LOG_DEBUG,
"%s; %s: rwscale different %i vs %i\n",
2410 log(LOG_DEBUG,
"%s; %s: swscale different %i vs %i\n",
2415 log(LOG_DEBUG,
"%s; %s: SACK different\n", s, __func__);
2509 s = (
const char *)NULL;
2510 log(LOG_WARNING,
"TCP syncache overflow detected; using syncookies for "
2511 "the next %lld seconds%s%s%s\n", (
long long)delta,
2512 (s != NULL) ?
" (last SYN: " :
"", (s != NULL) ? s :
"",
2513 (s != NULL) ?
")" :
"");
2514 free(__DECONST(
void *, s), M_TCPLOG);
2531 mtx_assert(&sc->
pause_mtx, MA_OWNED | MA_NOTRECURSED);
2539 callout_schedule(&sc->
pause_co, delta * hz);
2561 bzero(&xt,
sizeof(xt));
2562 xt.xt_len =
sizeof(xt);
2565 xt.xt_inp.xi_socket.xso_len =
sizeof (
struct xsocket);
2566 xt.xt_inp.xi_socket.so_type = SOCK_STREAM;
2567 xt.xt_inp.xi_socket.so_state = SS_ISCONNECTING;
2572 TAILQ_FOREACH(sc, &sch->sch_bucket, sc_hash) {
2574 cr_cansee(req->td->td_ucred, sc->
sc_cred) != 0)
2580 xt.xt_encaps_port = sc->
sc_port;
2581 bcopy(&sc->
sc_inc, &xt.xt_inp.inp_inc,
2583 error = SYSCTL_OUT(req, &xt,
sizeof xt);
u_short in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
const struct encaptab * cookie
#define TCP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4)
#define INP_HASH_WUNLOCK(ipi)
int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *, bool)
#define INP_HASH_WLOCK(ipi)
#define IN6P_AUTOFLOWLABEL
#define INP_RLOCK_ASSERT(inp)
#define IPV6_FLOWLABEL_MASK
struct mbuf * ip_srcroute(struct mbuf *m0)
int ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp)
struct in_endpoints inc_ie
struct ip6_pktopts * in6p_outputopts
struct mbuf * inp_options
struct in_conninfo inp_inc
struct in_addr ip_src ip_dst
struct tcp_syncache * sch_sc
u_int8_t sc_requested_s_scale
struct in_conninfo sc_inc
u_int8_t sc_requested_r_scale
uint8_t key[2][SYNCOOKIE_SECRET_SIZE]
volatile uint32_t tfb_refcnt
void(* tfb_tcp_fb_fini)(struct tcpcb *, int)
int(* tfb_tcp_fb_init)(struct tcpcb *)
struct syncookie_secret secret
unsigned int * t_tfo_pending
union tcpcb::@55 t_tfo_cookie
struct tcp_function_block * t_fb
int(* tod_syncache_respond)(struct toedev *, void *, struct mbuf *)
void(* tod_offload_socket)(struct toedev *, void *, struct socket *)
void(* tod_syncache_removed)(struct toedev *, void *)
void(* tod_syncache_added)(struct toedev *, void *)
uint16_t tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc)
int tcp_ecn_syncache_add(uint16_t thflags, int iptos)
void tcp_ecn_syncache_socket(struct tcpcb *tp, struct syncache *sc)
int tcp_fastopen_check_cookie(struct in_conninfo *inc, uint8_t *cookie, unsigned int len, uint64_t *latest_cookie)
void tcp_fastopen_decrement_counter(unsigned int *counter)
#define V_tcp_fastopen_server_enable
#define TCP_FASTOPEN_COOKIE_LEN
#define TCPS_SYN_RECEIVED
int tcp_addoptions(struct tcpopt *to, u_char *optp)
static __inline uint32_t tcp_ts_getticks(void)
#define tcp_rcvseqinit(tp)
#define tcp_sendseqinit(tp)
char * tcp_log_addrs(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr, const void *ip6hdr)
void tcp_state_change(struct tcpcb *tp, int newstate)
uint32_t tcp_new_ts_offset(struct in_conninfo *inc)
struct tcp_function_block * find_and_ref_tcp_fb(struct tcp_function_block *blk)
static int sysctl_net_inet_tcp_syncache_rexmtlimit_check(SYSCTL_HANDLER_ARGS)
static void syncache_timer(void *)
static void syncache_drop(struct syncache *, struct syncache_head *)
VNET_DEFINE(int, tcp_sc_rst_sock_fail)
SYSCTL_UINT(_net_inet_tcp_syncache, OID_AUTO, bucketlimit, CTLFLAG_VNET|CTLFLAG_RDTUN, &VNET_NAME(tcp_syncache.bucket_limit), 0, "Per-bucket hash limit for syncache")
static uint32_t syncookie_mac(struct in_conninfo *, tcp_seq, uint8_t, uint8_t *, uintptr_t)
#define SCH_LOCK_ASSERT(sch)
static struct socket * syncache_tfo_expand(struct syncache *sc, struct socket *lso, struct mbuf *m, uint64_t response_cookie)
#define V_tcp_syncookiesonly
static void syncookie_reseed(void *)
static struct socket * syncache_socket(struct syncache *, struct socket *, struct mbuf *m)
struct socket * syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, struct inpcb *inp, struct socket *so, struct mbuf *m, void *tod, void *todctx, uint8_t iptos, uint16_t port)
static void syncache_insert(struct syncache *, struct syncache_head *)
static void syncache_timeout(struct syncache *sc, struct syncache_head *sch, int docallout)
static tcp_seq syncookie_generate(struct syncache_head *, struct syncache *)
static void syncache_unpause(void *)
void syncache_chkrst(struct in_conninfo *inc, struct tcphdr *th, struct mbuf *m, uint16_t port)
SYSCTL_BOOL(_net_inet_tcp_syncache, OID_AUTO, see_other, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(tcp_syncache.see_other), 0, "All syncache(4) entries are visible, ignoring UID/GID, jail(2) " "and mac(4) checks")
static int tcp_sc_wstab[]
SYSCTL_INT(_net_inet_tcp, OID_AUTO, syncookies, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(tcp_syncookies), 0, "Use TCP SYN cookies if the syncache overflows")
static bool syncache_cookiesonly(void)
#define TCP_SYNCACHE_HASHSIZE
#define SYNCACHE_MAXREXMTS
static int tcp_sc_msstab[]
int syncache_pcblist(struct sysctl_req *req)
SYSCTL_UMA_CUR(_net_inet_tcp_syncache, OID_AUTO, count, CTLFLAG_VNET, &VNET_NAME(tcp_syncache.zone), "Current number of entries in syncache")
static struct syncache_head * syncache_hashbucket(struct in_conninfo *inc)
#define TCP_SYNCACHE_BUCKETLIMIT
static struct syncache * syncookie_lookup(struct in_conninfo *, struct syncache_head *, struct syncache *, struct tcphdr *, struct tcpopt *, struct socket *, uint16_t)
static SYSCTL_NODE(_net_inet_tcp, OID_AUTO, syncache, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "TCP SYN cache")
static void syncache_pause(struct in_conninfo *)
static int syncache_respond(struct syncache *, const struct mbuf *, int)
static void syncache_free(struct syncache *)
VNET_DEFINE_STATIC(int, tcp_syncookies)
int syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, struct socket **lsop, struct mbuf *m, uint16_t port)
static MALLOC_DEFINE(M_SYNCACHE, "syncache", "TCP syncache")
void syncache_badack(struct in_conninfo *inc, uint16_t port)
static struct syncache * syncache_lookup(struct in_conninfo *inc, struct syncache_head **schp)
void syncache_unreach(struct in_conninfo *inc, tcp_seq th_seq, uint16_t port)
SYSCTL_PROC(_net_inet_tcp_syncache, OID_AUTO, rexmtlimit, CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW|CTLFLAG_NEEDGIANT, &VNET_NAME(tcp_syncache.rexmt_limit), 0, sysctl_net_inet_tcp_syncache_rexmtlimit_check, "UI", "Limit on SYN/ACK retransmissions")
#define V_functions_inherit_listen_socket_stack
#define SYNCOOKIE_LIFETIME
#define SYNCOOKIE_SECRET_SIZE
#define TCP_SYNCACHE_MAX_BACKOFF
#define TCP_SYNCACHE_PAUSE_TIME
int tcp_backoff[TCP_MAXRXTSHIFT+1]
void tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
#define TCPT_RANGESET(tv, value, tvmin, tvmax)
static uint16_t tcp_get_flags(const struct tcphdr *th)
static void tcp_set_flags(struct tcphdr *th, uint16_t flags)
#define TCPSTATES_DEC(state)
#define V_tcp_udp_tunneling_port
#define V_tcp_insecure_rst
#define V_tcp_udp_tunneling_overhead
#define V_tcp_ecn_maxretries
#define TCPSTATES_INC(state)
#define V_tcp_tolerate_missing_ts
#define TCPSTAT_INC(name)
#define IS_FASTOPEN(t_flags)
#define V_path_mtu_discovery