Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_timewait.c
Show First 20 Lines • Show All 403 Lines • ▼ Show 20 Lines | tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th, | ||||
* still present. This is undesirable, but temporarily necessary | * still present. This is undesirable, but temporarily necessary | ||||
* until we work out how to handle inpcb's who's timewait state has | * until we work out how to handle inpcb's who's timewait state has | ||||
* been removed. | * been removed. | ||||
*/ | */ | ||||
tw = intotw(inp); | tw = intotw(inp); | ||||
if (tw == NULL) | if (tw == NULL) | ||||
goto drop; | goto drop; | ||||
thflags = th->th_flags; | thflags = tcp_get_flags(th); | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if ((thflags & (TH_SYN | TH_ACK)) == TH_SYN) | if ((thflags & (TH_SYN | TH_ACK)) == TH_SYN) | ||||
INP_RLOCK_ASSERT(inp); | INP_RLOCK_ASSERT(inp); | ||||
else { | else { | ||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
KASSERT(to != NULL, | KASSERT(to != NULL, | ||||
("%s: called without options on a non-SYN segment", | ("%s: called without options on a non-SYN segment", | ||||
__func__)); | __func__)); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | if ((thflags & TH_SYN) && SEQ_GT(th->th_seq, tw->rcv_nxt)) { | ||||
TCPSTAT_INC(tcps_tw_recycles); | TCPSTAT_INC(tcps_tw_recycles); | ||||
return (1); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* Send RST if UDP port numbers don't match | * Send RST if UDP port numbers don't match | ||||
*/ | */ | ||||
if (tw->t_port != m->m_pkthdr.tcp_tun_port) { | if (tw->t_port != m->m_pkthdr.tcp_tun_port) { | ||||
if (th->th_flags & TH_ACK) { | if (tcp_get_flags(th) & TH_ACK) { | ||||
tcp_respond(NULL, mtod(m, void *), th, m, | tcp_respond(NULL, mtod(m, void *), th, m, | ||||
(tcp_seq)0, th->th_ack, TH_RST); | (tcp_seq)0, th->th_ack, TH_RST); | ||||
} else { | } else { | ||||
if (th->th_flags & TH_SYN) | if (tcp_get_flags(th) & TH_SYN) | ||||
tlen++; | tlen++; | ||||
if (th->th_flags & TH_FIN) | if (tcp_get_flags(th) & TH_FIN) | ||||
tlen++; | tlen++; | ||||
tcp_respond(NULL, mtod(m, void *), th, m, | tcp_respond(NULL, mtod(m, void *), th, m, | ||||
th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK); | th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK); | ||||
} | } | ||||
INP_UNLOCK(inp); | INP_UNLOCK(inp); | ||||
TCPSTAT_INC(tcps_tw_resets); | TCPSTAT_INC(tcps_tw_resets); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | #endif | ||||
m->m_len = hdrlen + optlen; | m->m_len = hdrlen + optlen; | ||||
m->m_pkthdr.len = m->m_len; | m->m_pkthdr.len = m->m_len; | ||||
KASSERT(max_linkhdr + m->m_len <= MHLEN, ("tcptw: mbuf too small")); | KASSERT(max_linkhdr + m->m_len <= MHLEN, ("tcptw: mbuf too small")); | ||||
th->th_seq = htonl(tw->snd_nxt); | th->th_seq = htonl(tw->snd_nxt); | ||||
th->th_ack = htonl(tw->rcv_nxt); | th->th_ack = htonl(tw->rcv_nxt); | ||||
th->th_off = (sizeof(struct tcphdr) + optlen) >> 2; | th->th_off = (sizeof(struct tcphdr) + optlen) >> 2; | ||||
th->th_flags = flags; | tcp_set_flags(th, flags); | ||||
th->th_win = htons(tw->last_win); | th->th_win = htons(tw->last_win); | ||||
#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) | #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) | ||||
if (tw->tw_flags & TF_SIGNATURE) { | if (tw->tw_flags & TF_SIGNATURE) { | ||||
if (!TCPMD5_ENABLED() || | if (!TCPMD5_ENABLED() || | ||||
TCPMD5_OUTPUT(m, th, to.to_signature) != 0) | TCPMD5_OUTPUT(m, th, to.to_signature) != 0) | ||||
return (-1); | return (-1); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 159 Lines • Show Last 20 Lines |