40#include "opt_kern_tls.h"
41#include "opt_tcpdebug.h"
46#include <sys/domain.h>
50#include <sys/kernel.h>
57#include <sys/protosw.h>
60#include <sys/socket.h>
61#include <sys/socketvar.h>
62#include <sys/sysctl.h>
67#include <net/route/nhop.h>
78#include <netinet6/in6_pcb.h>
80#include <netinet6/ip6_var.h>
104#include <netipsec/ipsec_support.h>
108#include <machine/in_cksum.h>
110#include <security/mac/mac_framework.h>
113SYSCTL_INT(_net_inet_tcp, OID_AUTO, path_mtu_discovery, CTLFLAG_VNET | CTLFLAG_RW,
114 &VNET_NAME(path_mtu_discovery), 1,
115 "Enable Path MTU Discovery");
118SYSCTL_INT(_net_inet_tcp, OID_AUTO, tso, CTLFLAG_VNET | CTLFLAG_RW,
119 &VNET_NAME(tcp_do_tso), 0,
120 "Enable TCP Segmentation Offload");
123#define V_tcp_sendspace VNET(tcp_sendspace)
125 &VNET_NAME(tcp_sendspace), 0,
"Initial send socket buffer size");
128SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto, CTLFLAG_VNET | CTLFLAG_RW,
129 &VNET_NAME(tcp_do_autosndbuf), 0,
130 "Enable automatic send buffer sizing");
133SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_inc, CTLFLAG_VNET | CTLFLAG_RW,
134 &VNET_NAME(tcp_autosndbuf_inc), 0,
135 "Incrementor step size of automatic send buffer");
138SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW,
139 &VNET_NAME(tcp_autosndbuf_max), 0,
140 "Max size of automatic send buffer");
143#define V_tcp_sendbuf_auto_lowat VNET(tcp_sendbuf_auto_lowat)
144SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_auto_lowat, CTLFLAG_VNET | CTLFLAG_RW,
145 &VNET_NAME(tcp_sendbuf_auto_lowat), 0,
146 "Modify threshold for auto send buffer growth to account for SO_SNDLOWAT");
152#define TCP_XMIT_TIMER_ASSERT(tp, len, th_flags) \
153 KASSERT(((len) == 0 && ((th_flags) & (TH_SYN | TH_FIN)) == 0) ||\
154 tcp_timer_active((tp), TT_REXMT) || \
155 tcp_timer_active((tp), TT_PERSIST), \
156 ("neither rexmt nor persist timer is set"))
165hhook_run_tcp_est_out(
struct tcpcb *tp,
struct tcphdr *th,
174 hhook_data.len =
len;
175 hhook_data.tso =
tso;
206 u_int if_hw_tsomaxsegcount = 0;
207 u_int if_hw_tsomaxsegsize = 0;
209 struct ip *
ip = NULL;
211 struct ipovly *ipov = NULL;
214 u_char opt[TCP_MAXOLEN];
215 unsigned ipoptlen, optlen, hdrlen, ulen;
216#if defined(IPSEC) || defined(IPSEC_SUPPORT)
217 unsigned ipsec_optlen = 0;
219 int idle, sendalot, curticks;
220 int sack_rxmit, sack_bytes_rxmt;
224 struct udphdr *udp = NULL;
225 unsigned int wanted_cookie = 0;
226 unsigned int dont_sendalot = 0;
228 int maxburst = TCP_MAXBURST;
237 const bool hw_tls = (so->so_snd.sb_flags & SB_TLS_IFNET) != 0;
239 const bool hw_tls =
false;
294 flags = tcp_outflags[tp->
t_state];
330 goto after_sack_rexmit;
333 len = ((int32_t)ulmin(cwin,
336 len = ((int32_t)ulmin(cwin, p->
end - p->
rxmit));
338 KASSERT(off >= 0,(
"%s: sack block to the left of una : %d",
358 SOCKBUF_LOCK(&so->so_snd);
383 if (off < sbused(&so->so_snd))
407 if (sack_rxmit == 0) {
408 if (sack_bytes_rxmt == 0)
409 len = ((int32_t)min(sbavail(&so->so_snd), sendwin) -
419 len = ((int32_t)min(sbavail(&so->so_snd), tp->
snd_wnd) -
435 len = imin(len, cwin);
481 (((flags & TH_SYN) && (tp->
t_rxtshift > 0)) ||
505 (off < (
int) sbavail(&so->so_snd))) {
515 KASSERT(len >= 0, (
"[%s:%d]: len < 0", __func__, __LINE__));
535#if defined(IPSEC) || defined(IPSEC_SUPPORT)
541 if (isipv6 && IPSEC_ENABLED(ipv6))
542 ipsec_optlen = IPSEC_HDRSIZE(ipv6, tp->
t_inpcb);
548 if (IPSEC_ENABLED(ipv4))
549 ipsec_optlen = IPSEC_HDRSIZE(ipv4, tp->
t_inpcb);
554 ipoptlen = ip6_optlen(tp->
t_inpcb);
559 offsetof(
struct ipoption, ipopt_list);
562#if defined(IPSEC) || defined(IPSEC_SUPPORT)
563 ipoptlen += ipsec_optlen;
570 ipoptlen == 0 && !(flags & TH_SYN))
578 sbused(&so->so_snd)))
582 recwin = lmin(lmax(sbspace(&so->so_rcv), 0),
609 PADTCPOLEN(TCPOLEN_SIGNATURE) : 0) +
611 PADTCPOLEN(TCPOLEN_TIMESTAMP) : 0) +
695 if (adv >= (int32_t)(2 * tp->
t_maxseg) &&
696 (adv >= (int32_t)(so->so_rcv.sb_hiwat / 4) ||
697 recwin <= (so->so_rcv.sb_hiwat / 8) ||
698 so->so_rcv.sb_hiwat <= 8 * tp->
t_maxseg ||
701 if (2 * adv >= (int32_t)so->so_rcv.sb_hiwat)
712 if ((flags & TH_RST) ||
721 if (flags & TH_FIN &&
768 SOCKBUF_UNLOCK(&so->so_snd);
772 SOCKBUF_LOCK_ASSERT(&so->so_snd);
777 tp->
t_flags2 &= ~TF2_PLPMTU_MAXSEGSNT;
790 hdrlen =
sizeof (
struct ip6_hdr) + sizeof (struct tcphdr);
795 if (flags & TH_SYN) {
808 if (flags & TH_SYN) {
865 (so->so_rcv.sb_flags & SB_AUTOSIZE))
879#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
902 SOCKBUF_UNLOCK(&so->so_snd);
903 return (EHOSTUNREACH);
905 hdrlen +=
sizeof(
struct udphdr);
913 if (len + optlen + ipoptlen > tp->
t_maxseg) {
931 KASSERT(ipoptlen == 0,
932 (
"%s: TSO can't do IP options", __func__));
938 if (if_hw_tsomax != 0) {
940 max_len = (if_hw_tsomax - hdrlen -
944 }
else if (len > max_len) {
957 sbavail(&so->so_snd)) {
958 moff = len % max_len;
969 if (len <= max_len) {
985 if (optlen + ipoptlen >= tp->
t_maxseg) {
994 SOCKBUF_UNLOCK(&so->so_snd);
999 len = tp->
t_maxseg - optlen - ipoptlen;
1008 (
"%s: len > IP_MAXPACKET", __func__));
1012 if (max_linkhdr + hdrlen > MCLBYTES)
1014 if (max_linkhdr + hdrlen > MHLEN)
1016 panic(
"tcphdr too big");
1023 KASSERT(len >= 0, (
"[%s:%d]: len < 0", __func__, __LINE__));
1032 struct sockbuf *msb;
1039 stats_voi_update_abs_u32(tp->
t_stats,
1042 stats_voi_update_abs_u64(tp->
t_stats,
1062 if (MHLEN < hdrlen + max_linkhdr)
1063 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1066 m = m_gethdr(M_NOWAIT, MT_DATA);
1069 SOCKBUF_UNLOCK(&so->so_snd);
1075 m->m_data += max_linkhdr;
1082 mb = sbsndptr_noadv(&so->so_snd, off, &moff);
1083 if (len <= MHLEN - hdrlen - max_linkhdr && !hw_tls) {
1084 m_copydata(mb, moff, len,
1085 mtod(m, caddr_t) + hdrlen);
1087 sbsndptr_adv(&so->so_snd, mb, len);
1095 &len, if_hw_tsomaxsegcount,
1096 if_hw_tsomaxsegsize, msb, hw_tls);
1097 if (len <= (tp->
t_maxseg - optlen)) {
1106 if (m->m_next == NULL) {
1107 SOCKBUF_UNLOCK(&so->so_snd);
1124 SOCKBUF_UNLOCK(&so->so_snd);
1126 SOCKBUF_UNLOCK(&so->so_snd);
1129 else if (flags & (TH_SYN|TH_FIN|TH_RST))
1136 m = m_gethdr(M_NOWAIT, MT_DATA);
1143 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) &&
1148 m->m_data += max_linkhdr;
1151 SOCKBUF_UNLOCK_ASSERT(&so->so_snd);
1152 m->m_pkthdr.rcvif = (
struct ifnet *)0;
1154 mac_inpcb_create_mbuf(tp->
t_inpcb, m);
1158 ip6 = mtod(m,
struct ip6_hdr *);
1160 udp = (
struct udphdr *)((caddr_t)ip6 +
sizeof(
struct ip6_hdr));
1163 ulen = hdrlen + len -
sizeof(
struct ip6_hdr);
1165 th = (
struct tcphdr *)(udp + 1);
1167 th = (
struct tcphdr *)(ip6 + 1);
1173 ip = mtod(m,
struct ip *);
1178 udp = (
struct udphdr *)((caddr_t)
ip +
sizeof(
struct ip));
1181 ulen = hdrlen + len -
sizeof(
struct ip);
1183 th = (
struct tcphdr *)(udp + 1);
1185 th = (
struct tcphdr *)(
ip + 1);
1216 ip6->ip6_flow |= htonl(ect << 20);
1239 if (sack_rxmit == 0) {
1240 if (len || (flags & (TH_SYN|TH_FIN)) ||
1242 th->th_seq = htonl(tp->
snd_nxt);
1244 th->th_seq = htonl(tp->
snd_max);
1246 th->th_seq = htonl(p->
rxmit);
1266 th->th_ack = htonl(tp->
rcv_nxt);
1268 bcopy(opt, th + 1, optlen);
1269 th->th_off = (
sizeof (
struct tcphdr) + optlen) >> 2;
1277 if (flags & TH_RST) {
1280 if (recwin < (so->so_rcv.sb_hiwat / 4) &&
1281 recwin < tp->t_maxseg)
1293 th->th_win = htons((u_short)
1294 (min(sbspace(&so->so_rcv), TCP_MAXWIN)));
1297 recwin = roundup2(recwin, 1 << tp->
rcv_scale);
1298 th->th_win = htons((u_short)(recwin >> tp->
rcv_scale));
1309 if (th->th_win == 0) {
1313 tp->
t_flags &= ~TF_RXWIN0SENT;
1316 th->th_flags |= TH_URG;
1330 m->m_pkthdr.len = hdrlen + len;
1332#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
1340 if (!TCPMD5_ENABLED() || (error = TCPMD5_OUTPUT(m, th,
1358 m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
1359 m->m_pkthdr.csum_data = offsetof(
struct udphdr, uh_sum);
1361 th->th_sum = htons(0);
1364 m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
1365 m->m_pkthdr.csum_data = offsetof(
struct tcphdr, th_sum);
1366 th->th_sum = in6_cksum_pseudo(ip6,
1367 sizeof(
struct tcphdr) + optlen + len,
IPPROTO_TCP,
1372#if defined(INET6) && defined(INET)
1378 m->m_pkthdr.csum_flags = CSUM_UDP;
1379 m->m_pkthdr.csum_data = offsetof(
struct udphdr, uh_sum);
1382 th->th_sum = htons(0);
1385 m->m_pkthdr.csum_flags = CSUM_TCP;
1386 m->m_pkthdr.csum_data = offsetof(
struct tcphdr, th_sum);
1394 (
"%s: IP version incorrect: %d", __func__,
ip->
ip_v));
1403 KASSERT(len > tp->
t_maxseg - optlen,
1404 (
"%s: len <= tso_segsz", __func__));
1405 m->m_pkthdr.csum_flags |= CSUM_TSO;
1406 m->m_pkthdr.tso_segsz = tp->
t_maxseg - optlen;
1409 KASSERT(len + hdrlen == m_length(m, NULL),
1410 (
"%s: mbuf chain shorter than expected: %d + %u != %u",
1411 __func__, len, hdrlen, m_length(m, NULL)));
1415 hhook_run_tcp_est_out(tp, th, &to, len, tso);
1422 if (so->so_options & SO_DEBUG) {
1429 ipov->
ih_len = htons(m->m_pkthdr.len );
1462 ip6->ip6_hlim = in6_selecthlim(tp->
t_inpcb, NULL);
1469 ip6->ip6_plen = htons(m->m_pkthdr.len -
sizeof(*ip6));
1477 TCP_PROBE5(connect__request, NULL, tp, ip6, tp, th);
1496#if defined(INET) && defined(INET6)
1501 ip->
ip_len = htons(m->m_pkthdr.len);
1534 ((so->so_options & SO_DONTROUTE) ?
IP_ROUTETOIF : 0), 0,
1551 tcp_seq startseq = tp->
snd_nxt;
1556 if (flags & (TH_SYN|TH_FIN)) {
1559 if (flags & TH_FIN) {
1584 ulmin(sbavail(&so->so_snd) - off, sendwin);
1607 }
else if (len == 0 && sbavail(&so->so_snd) &&
1640 if (flags & TH_FIN) {
1657 error, 0, NULL,
false);
1674 ((flags & TH_SYN) == 0) &&
1680 (
"sackhint bytes rtx >= 0"));
1684 SOCKBUF_UNLOCK_ASSERT(&so->so_snd);
1745 if (sendalot && --maxburst)
1761 panic(
"tcp_setpersist: retransmit pending");
1792 u_int32_t mask, optlen = 0;
1794 for (mask = 1; mask <
TOF_MAXOPT; mask <<= 1) {
1797 if (optlen == TCP_MAXOLEN)
1801 while (optlen % 4) {
1802 optlen += TCPOLEN_NOP;
1803 *optp++ = TCPOPT_NOP;
1805 if (TCP_MAXOLEN - optlen < TCPOLEN_MAXSEG)
1807 optlen += TCPOLEN_MAXSEG;
1808 *optp++ = TCPOPT_MAXSEG;
1809 *optp++ = TCPOLEN_MAXSEG;
1811 bcopy((u_char *)&to->
to_mss, optp,
sizeof(to->
to_mss));
1812 optp +=
sizeof(to->
to_mss);
1815 while (!optlen || optlen % 2 != 1) {
1816 optlen += TCPOLEN_NOP;
1817 *optp++ = TCPOPT_NOP;
1819 if (TCP_MAXOLEN - optlen < TCPOLEN_WINDOW)
1821 optlen += TCPOLEN_WINDOW;
1822 *optp++ = TCPOPT_WINDOW;
1823 *optp++ = TCPOLEN_WINDOW;
1827 while (optlen % 2) {
1828 optlen += TCPOLEN_NOP;
1829 *optp++ = TCPOPT_NOP;
1831 if (TCP_MAXOLEN - optlen < TCPOLEN_SACK_PERMITTED)
1833 optlen += TCPOLEN_SACK_PERMITTED;
1834 *optp++ = TCPOPT_SACK_PERMITTED;
1835 *optp++ = TCPOLEN_SACK_PERMITTED;
1838 while (!optlen || optlen % 4 != 2) {
1839 optlen += TCPOLEN_NOP;
1840 *optp++ = TCPOPT_NOP;
1842 if (TCP_MAXOLEN - optlen < TCPOLEN_TIMESTAMP)
1844 optlen += TCPOLEN_TIMESTAMP;
1845 *optp++ = TCPOPT_TIMESTAMP;
1846 *optp++ = TCPOLEN_TIMESTAMP;
1856 int siglen = TCPOLEN_SIGNATURE - 2;
1858 while (!optlen || optlen % 4 != 2) {
1859 optlen += TCPOLEN_NOP;
1860 *optp++ = TCPOPT_NOP;
1862 if (TCP_MAXOLEN - optlen < TCPOLEN_SIGNATURE) {
1866 optlen += TCPOLEN_SIGNATURE;
1867 *optp++ = TCPOPT_SIGNATURE;
1868 *optp++ = TCPOLEN_SIGNATURE;
1880 while (!optlen || optlen % 4 != 2) {
1881 optlen += TCPOLEN_NOP;
1882 *optp++ = TCPOPT_NOP;
1884 if (TCP_MAXOLEN - optlen < TCPOLEN_SACKHDR + TCPOLEN_SACK)
1886 optlen += TCPOLEN_SACKHDR;
1887 *optp++ = TCPOPT_SACK;
1889 (TCP_MAXOLEN - optlen) / TCPOLEN_SACK);
1890 *optp++ = TCPOLEN_SACKHDR + sackblks * TCPOLEN_SACK;
1891 while (sackblks--) {
1892 sack_seq = htonl(sack->
start);
1893 bcopy((u_char *)&sack_seq, optp,
sizeof(sack_seq));
1894 optp +=
sizeof(sack_seq);
1895 sack_seq = htonl(sack->
end);
1896 bcopy((u_char *)&sack_seq, optp,
sizeof(sack_seq));
1897 optp +=
sizeof(sack_seq);
1898 optlen += TCPOLEN_SACK;
1909 total_len = TCPOLEN_FAST_OPEN_EMPTY + to->
to_tfo_len;
1910 if (TCP_MAXOLEN - optlen < total_len) {
1914 *optp++ = TCPOPT_FAST_OPEN;
1915 *optp++ = total_len;
1920 optlen += total_len;
1924 panic(
"%s: unknown TCP option type", __func__);
1931 optlen += TCPOLEN_EOL;
1932 *optp++ = TCPOPT_EOL;
1940 while (optlen % 4) {
1941 optlen += TCPOLEN_PAD;
1942 *optp++ = TCPOPT_PAD;
1945 KASSERT(optlen <= TCP_MAXOLEN, (
"%s: TCP options too long", __func__));
1955 int32_t seglimit, int32_t segsize,
struct sockbuf *sb,
bool hw_tls)
1958 struct ktls_session *tls, *ntls;
1961 struct mbuf *n, **np;
1964 int32_t len = *plen;
1971 KASSERT(off >= 0, (
"tcp_m_copym, negative off %d", off));
1972 KASSERT(len >= 0, (
"tcp_m_copym, negative len %d", len));
1973 if (off == 0 && m->m_flags & M_PKTHDR)
1978 KASSERT(m != NULL, (
"tcp_m_copym, offset > size of mbuf chain"));
1982 if ((sb) && (m == sb->sb_sndptr)) {
1983 sb->sb_sndptroff += m->m_len;
1984 sb->sb_sndptr = m->m_next;
1992 if (hw_tls && (m->m_flags & M_EXTPG))
2000 KASSERT(len == M_COPYALL,
2001 (
"tcp_m_copym, length > size of mbuf chain"));
2003 if (pkthdrlen != NULL)
2004 *pkthdrlen = len_cp;
2009 if (m->m_flags & M_EXTPG)
2010 ntls = m->m_epg_tls;
2022 if (pkthdrlen != NULL)
2023 *pkthdrlen = len_cp;
2028 mlen = min(len, m->m_len - off);
2038 if (m->m_flags & M_EXTPG) {
2039 fragsize = min(segsize, PAGE_SIZE);
2047 if ((frags + 1) >= seglimit) {
2049 if (pkthdrlen != NULL)
2050 *pkthdrlen = len_cp;
2060 if ((frags + howmany(mlen, fragsize)) >= seglimit) {
2061 mlen = (seglimit - frags - 1) * fragsize;
2063 *plen = len_cp + len;
2064 if (pkthdrlen != NULL)
2067 frags += howmany(mlen, fragsize);
2071 KASSERT(seglimit > 0,
2072 (
"%s: seglimit went too low", __func__));
2075 n = m_gethdr(M_NOWAIT, m->m_type);
2077 n = m_get(M_NOWAIT, m->m_type);
2082 if (!m_dup_pkthdr(n, m, M_NOWAIT))
2084 if (len == M_COPYALL)
2085 n->m_pkthdr.len -= off0;
2087 n->m_pkthdr.len = len;
2088 pkthdrlen = &n->m_pkthdr.len;
2093 if (m->m_flags & (M_EXT|M_EXTPG)) {
2094 n->m_data = m->m_data + off;
2097 bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
2100 if (sb && (sb->sb_sndptr == m) &&
2101 ((n->m_len + off) >= m->m_len) && m->m_next) {
2102 sb->sb_sndptroff += m->m_len;
2103 sb->sb_sndptr = m->m_next;
2106 if (len != M_COPYALL) {
2163 if ((tp->
snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat - lowat &&
2164 sbused(&so->so_snd) >=
2165 (so->so_snd.sb_hiwat / 8 * 7) - lowat &&
2167 sendwin >= (sbused(&so->so_snd) -
2169 if (!sbreserve_locked(&so->so_snd,
2172 so->so_snd.sb_flags &= ~SB_AUTOSIZE;
u_short in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
#define TCP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4)
#define TCP_PROBE3(probe, arg0, arg1, arg2)
#define INP_WLOCK_ASSERT(inp)
int ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp)
struct socket * inp_socket
struct ip6_pktopts * in6p_outputopts
struct route_in6 inp_route6
struct mbuf * inp_options
struct in_conninfo inp_inc
struct in_addr ip_src ip_dst
int32_t sack_bytes_rexmit
struct sackblk sackblks[MAX_SACK_BLKS]
union tcpcb::@55 t_tfo_cookie
struct statsblob * t_stats
uint8_t t_tfo_client_cookie_len
uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN]
void tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen, struct tcphdr *th, int req)
int tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rxmit)
uint16_t tcp_ecn_output_syn_sent(struct tcpcb *tp)
#define TCP_FASTOPEN_COOKIE_LEN
#define TCPS_HAVERCVDSYN(s)
#define TCPS_HAVERCVDFIN(s)
#define TCPS_SYN_RECEIVED
#define TCPS_HAVEESTABLISHED(s)
#define TCP_LOG_EVENT(tp, th, rxbuf, txbuf, eventid, errornum, len, stackinfo, th_hostorder)
int tcp_offload_output(struct tcpcb *tp)
#define V_tcp_sendbuf_auto_lowat
#define TCP_XMIT_TIMER_ASSERT(tp, len, th_flags)
int tcp_addoptions(struct tcpopt *to, u_char *optp)
static void cc_after_idle(struct tcpcb *tp)
void tcp_setpersist(struct tcpcb *tp)
void tcp_sndbuf_autoscale(struct tcpcb *tp, struct socket *so, uint32_t sendwin)
struct mbuf * tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen, int32_t seglimit, int32_t segsize, struct sockbuf *sb, bool hw_tls)
SYSCTL_INT(_net_inet_tcp, OID_AUTO, path_mtu_discovery, CTLFLAG_VNET|CTLFLAG_RW, &VNET_NAME(path_mtu_discovery), 1, "Enable Path MTU Discovery")
VNET_DEFINE(int, path_mtu_discovery)
int tcp_default_output(struct tcpcb *tp)
void tcp_pcap_add(struct tcphdr *th, struct mbuf *m, struct mbufq *queue)
struct sackhole * tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt)
void tcp_sack_adjust(struct tcpcb *tp)
void tcp_clean_dsack_blocks(struct tcpcb *tp)
static __inline uint32_t tcp_ts_getticks(void)
u_int tcp_maxseg(const struct tcpcb *tp)
void tcpip_fillheaders(struct inpcb *inp, uint16_t port, void *ip_ptr, void *tcp_ptr)
int tcp_timer_active(struct tcpcb *tp, uint32_t timer_type)
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)
#define V_tcp_do_autosndbuf
#define TF2_PLPMTU_MAXSEGSNT
#define IN_FASTRECOVERY(t_flags)
static void tcp_set_flags(struct tcphdr *th, uint16_t flags)
#define V_tcp_udp_tunneling_port
#define V_tcp_udp_tunneling_overhead
#define V_tcp_autosndbuf_max
#define TCPSTAT_ADD(name, val)
#define V_tcp_autosndbuf_inc
#define IN_RECOVERY(t_flags)
#define TCPSTAT_INC(name)
#define IS_FASTOPEN(t_flags)
#define HHOOK_TCP_EST_OUT
#define V_path_mtu_discovery
static void tcp_account_for_send(struct tcpcb *tp, uint32_t len, uint8_t is_rxt, uint8_t is_tlp, int hw_tls)
#define UDPSTAT_INC(name)