Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_subr.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
#define TCPSTATES | #define TCPSTATES | ||||
#endif | #endif | ||||
#include <netinet/tcp_fsm.h> | #include <netinet/tcp_fsm.h> | ||||
#include <netinet/tcp_seq.h> | #include <netinet/tcp_seq.h> | ||||
#include <netinet/tcp_timer.h> | #include <netinet/tcp_timer.h> | ||||
#include <netinet/tcp_var.h> | #include <netinet/tcp_var.h> | ||||
#include <netinet/tcp_ecn.h> | |||||
#include <netinet/tcp_log_buf.h> | #include <netinet/tcp_log_buf.h> | ||||
#include <netinet/tcp_syncache.h> | #include <netinet/tcp_syncache.h> | ||||
#include <netinet/tcp_hpts.h> | #include <netinet/tcp_hpts.h> | ||||
#include <netinet/cc/cc.h> | #include <netinet/cc/cc.h> | ||||
#include <netinet/tcpip.h> | #include <netinet/tcpip.h> | ||||
#include <netinet/tcp_fastopen.h> | #include <netinet/tcp_fastopen.h> | ||||
#ifdef TCPPCAP | #ifdef TCPPCAP | ||||
#include <netinet/tcp_pcap.h> | #include <netinet/tcp_pcap.h> | ||||
▲ Show 20 Lines • Show All 1,657 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* In any case the ack and sequence number of the transmitted | * In any case the ack and sequence number of the transmitted | ||||
* segment are as specified by the parameters. | * segment are as specified by the parameters. | ||||
* | * | ||||
* NOTE: If m != NULL, then th must point to *inside* the mbuf. | * NOTE: If m != NULL, then th must point to *inside* the mbuf. | ||||
*/ | */ | ||||
void | void | ||||
tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, | tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, | ||||
tcp_seq ack, tcp_seq seq, int flags) | tcp_seq ack, tcp_seq seq, uint16_t flags) | ||||
{ | { | ||||
struct tcpopt to; | struct tcpopt to; | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
struct ip *ip; | struct ip *ip; | ||||
struct mbuf *optm; | struct mbuf *optm; | ||||
struct udphdr *uh = NULL; | struct udphdr *uh = NULL; | ||||
struct tcphdr *nth; | struct tcphdr *nth; | ||||
struct tcp_log_buffer *lgb; | struct tcp_log_buffer *lgb; | ||||
u_char *optp; | u_char *optp; | ||||
#ifdef INET6 | #ifdef INET6 | ||||
struct ip6_hdr *ip6; | struct ip6_hdr *ip6; | ||||
int isipv6; | int isipv6; | ||||
#endif /* INET6 */ | #endif /* INET6 */ | ||||
int optlen, tlen, win, ulen; | int optlen, tlen, win, ulen; | ||||
int ect = 0; | |||||
bool incl_opts; | bool incl_opts; | ||||
uint16_t port; | uint16_t port; | ||||
int output_ret; | int output_ret; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
int thflags = tcp_get_flags(th); | int thflags = tcp_get_flags(th); | ||||
#endif | #endif | ||||
KASSERT(tp != NULL || m != NULL, ("tcp_respond: tp and m both NULL")); | KASSERT(tp != NULL || m != NULL, ("tcp_respond: tp and m both NULL")); | ||||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | #ifdef INVARIANTS | ||||
m->m_len = 0; | m->m_len = 0; | ||||
KASSERT(M_TRAILINGSPACE(m) >= tlen, | KASSERT(M_TRAILINGSPACE(m) >= tlen, | ||||
("Not enough trailing space for message (m=%p, need=%d, have=%ld)", | ("Not enough trailing space for message (m=%p, need=%d, have=%ld)", | ||||
m, tlen, (long)M_TRAILINGSPACE(m))); | m, tlen, (long)M_TRAILINGSPACE(m))); | ||||
#endif | #endif | ||||
m->m_len = tlen; | m->m_len = tlen; | ||||
to.to_flags = 0; | to.to_flags = 0; | ||||
if (incl_opts) { | if (incl_opts) { | ||||
ect = tcp_ecn_output_established(tp, &flags, 0, false); | |||||
/* Make sure we have room. */ | /* Make sure we have room. */ | ||||
if (M_TRAILINGSPACE(m) < TCP_MAXOLEN) { | if (M_TRAILINGSPACE(m) < TCP_MAXOLEN) { | ||||
m->m_next = m_get(M_NOWAIT, MT_DATA); | m->m_next = m_get(M_NOWAIT, MT_DATA); | ||||
if (m->m_next) { | if (m->m_next) { | ||||
optp = mtod(m->m_next, u_char *); | optp = mtod(m->m_next, u_char *); | ||||
optm = m->m_next; | optm = m->m_next; | ||||
} else | } else | ||||
incl_opts = false; | incl_opts = false; | ||||
Show All 22 Lines | #endif | ||||
} else | } else | ||||
optlen = 0; | optlen = 0; | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (isipv6) { | if (isipv6) { | ||||
if (uh) { | if (uh) { | ||||
ulen = tlen - sizeof(struct ip6_hdr); | ulen = tlen - sizeof(struct ip6_hdr); | ||||
uh->uh_ulen = htons(ulen); | uh->uh_ulen = htons(ulen); | ||||
} | } | ||||
ip6->ip6_flow = 0; | ip6->ip6_flow = htonl(ect << 20); | ||||
ip6->ip6_vfc = IPV6_VERSION; | ip6->ip6_vfc = IPV6_VERSION; | ||||
if (port) | if (port) | ||||
ip6->ip6_nxt = IPPROTO_UDP; | ip6->ip6_nxt = IPPROTO_UDP; | ||||
else | else | ||||
ip6->ip6_nxt = IPPROTO_TCP; | ip6->ip6_nxt = IPPROTO_TCP; | ||||
ip6->ip6_plen = htons(tlen - sizeof(*ip6)); | ip6->ip6_plen = htons(tlen - sizeof(*ip6)); | ||||
} | } | ||||
#endif | #endif | ||||
#if defined(INET) && defined(INET6) | #if defined(INET) && defined(INET6) | ||||
else | else | ||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
{ | { | ||||
if (uh) { | if (uh) { | ||||
ulen = tlen - sizeof(struct ip); | ulen = tlen - sizeof(struct ip); | ||||
uh->uh_ulen = htons(ulen); | uh->uh_ulen = htons(ulen); | ||||
} | } | ||||
ip->ip_tos = ect; | |||||
ip->ip_len = htons(tlen); | ip->ip_len = htons(tlen); | ||||
ip->ip_ttl = V_ip_defttl; | ip->ip_ttl = V_ip_defttl; | ||||
if (port) { | if (port) { | ||||
ip->ip_p = IPPROTO_UDP; | ip->ip_p = IPPROTO_UDP; | ||||
} else { | } else { | ||||
ip->ip_p = IPPROTO_TCP; | ip->ip_p = IPPROTO_TCP; | ||||
} | } | ||||
if (V_path_mtu_discovery) | if (V_path_mtu_discovery) | ||||
▲ Show 20 Lines • Show All 2,056 Lines • Show Last 20 Lines |