Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_syncache.c
Show First 20 Lines • Show All 958 Lines • ▼ Show 20 Lines | #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) | ||||
if (sc->sc_flags & SCF_SIGNATURE) | if (sc->sc_flags & SCF_SIGNATURE) | ||||
tp->t_flags |= TF_SIGNATURE; | tp->t_flags |= TF_SIGNATURE; | ||||
#endif | #endif | ||||
if (sc->sc_flags & SCF_SACK) | if (sc->sc_flags & SCF_SACK) | ||||
tp->t_flags |= TF_SACK_PERMIT; | tp->t_flags |= TF_SACK_PERMIT; | ||||
} | } | ||||
if (sc->sc_flags & SCF_ECN) | if (sc->sc_flags & SCF_ECN) | ||||
tp->t_flags |= TF_ECN_PERMIT; | tp->t_flags2 |= TF2_ECN_PERMIT; | ||||
if ((sc->sc_flags & SCF_ACE_N) || | |||||
(sc->sc_flags & SCF_ACE_0) || | |||||
(sc->sc_flags & SCF_ACE_1) || | |||||
(sc->sc_flags & SCF_ACE_CE)) { | |||||
tp->t_flags2 |= TF2_ACE_PERMIT; | |||||
tp->s_cep = 5; | |||||
tp->r_cep = 5; | |||||
if (sc->sc_flags & SCF_ACE_CE) { | |||||
tp->s_cep=6; | |||||
tp->r_cep=6; | |||||
} | |||||
} | |||||
/* | /* | ||||
* Set up MSS and get cached values from tcp_hostcache. | * Set up MSS and get cached values from tcp_hostcache. | ||||
* This might overwrite some of the defaults we just set. | * This might overwrite some of the defaults we just set. | ||||
*/ | */ | ||||
tcp_mss(tp, sc->sc_peer_mss); | tcp_mss(tp, sc->sc_peer_mss); | ||||
/* | /* | ||||
* If the SYN,ACK was retransmitted, indicate that CWND to be | * If the SYN,ACK was retransmitted, indicate that CWND to be | ||||
▲ Show 20 Lines • Show All 327 Lines • ▼ Show 20 Lines | |||||
* cookie is processed and a new socket is created. In this case, any data | * cookie is processed and a new socket is created. In this case, any data | ||||
* accompanying the SYN will be queued to the socket by tcp_input() and will | * accompanying the SYN will be queued to the socket by tcp_input() and will | ||||
* be ACKed either when the application sends response data or the delayed | * be ACKed either when the application sends response data or the delayed | ||||
* ACK timer expires, whichever comes first. | * ACK timer expires, whichever comes first. | ||||
*/ | */ | ||||
int | int | ||||
syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, | syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, | ||||
struct inpcb *inp, struct socket **lsop, struct mbuf *m, void *tod, | struct inpcb *inp, struct socket **lsop, struct mbuf *m, void *tod, | ||||
void *todctx) | void *todctx, uint8_t tos) | ||||
{ | { | ||||
struct tcpcb *tp; | struct tcpcb *tp; | ||||
struct socket *so; | struct socket *so; | ||||
struct syncache *sc = NULL; | struct syncache *sc = NULL; | ||||
struct syncache_head *sch; | struct syncache_head *sch; | ||||
struct mbuf *ipopts = NULL; | struct mbuf *ipopts = NULL; | ||||
u_int ltflags; | u_int ltflags; | ||||
int win, ip_ttl, ip_tos; | int win, ip_ttl, ip_tos; | ||||
▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | if (ltflags & TF_SIGNATURE) | ||||
sc->sc_flags |= SCF_SIGNATURE; | sc->sc_flags |= SCF_SIGNATURE; | ||||
#endif /* TCP_SIGNATURE */ | #endif /* TCP_SIGNATURE */ | ||||
if (to->to_flags & TOF_SACKPERM) | if (to->to_flags & TOF_SACKPERM) | ||||
sc->sc_flags |= SCF_SACK; | sc->sc_flags |= SCF_SACK; | ||||
if (to->to_flags & TOF_MSS) | if (to->to_flags & TOF_MSS) | ||||
sc->sc_peer_mss = to->to_mss; /* peer mss may be zero */ | sc->sc_peer_mss = to->to_mss; /* peer mss may be zero */ | ||||
if (ltflags & TF_NOOPT) | if (ltflags & TF_NOOPT) | ||||
sc->sc_flags |= SCF_NOOPT; | sc->sc_flags |= SCF_NOOPT; | ||||
if ((th->th_flags & (TH_ECE|TH_CWR)) && V_tcp_do_ecn) | /* ECN Handshake */ | ||||
if (V_tcp_do_ecn) { | |||||
int xflags; | |||||
xflags = ((th->th_x2 << 8) | th->th_flags) & (TH_AE|TH_CWR|TH_ECE); | |||||
switch (xflags) { | |||||
/* no ECN */ | |||||
case (0|0|0): | |||||
break; | |||||
/* legacy ECN */ | |||||
case (0|TH_CWR|TH_ECE): | |||||
sc->sc_flags |= SCF_ECN; | sc->sc_flags |= SCF_ECN; | ||||
break; | |||||
/* Accurate ECN */ | |||||
case (TH_AE|TH_CWR|TH_ECE): | |||||
if ((V_tcp_do_ecn == 3) || | |||||
(V_tcp_do_ecn == 4)) { | |||||
switch (tos & IPTOS_ECN_MASK) { | |||||
case IPTOS_ECN_CE: | |||||
sc->sc_flags |= SCF_ACE_CE; | |||||
break; | |||||
case IPTOS_ECN_ECT0: | |||||
sc->sc_flags |= SCF_ACE_0; | |||||
break; | |||||
case IPTOS_ECN_ECT1: | |||||
sc->sc_flags |= SCF_ACE_1; | |||||
break; | |||||
case IPTOS_ECN_NOTECT: | |||||
sc->sc_flags |= SCF_ACE_N; | |||||
break; | |||||
} | |||||
} else | |||||
sc->sc_flags |= SCF_ECN; | |||||
break; | |||||
/* Default Case (section 3.1.2) */ | |||||
default: | |||||
if ((V_tcp_do_ecn == 3) || | |||||
(V_tcp_do_ecn == 4)) { | |||||
switch (tos & IPTOS_ECN_MASK) { | |||||
case IPTOS_ECN_CE: | |||||
sc->sc_flags |= SCF_ACE_CE; | |||||
break; | |||||
case IPTOS_ECN_ECT0: | |||||
sc->sc_flags |= SCF_ACE_0; | |||||
break; | |||||
case IPTOS_ECN_ECT1: | |||||
sc->sc_flags |= SCF_ACE_1; | |||||
break; | |||||
case IPTOS_ECN_NOTECT: | |||||
sc->sc_flags |= SCF_ACE_N; | |||||
break; | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
} | |||||
if (V_tcp_syncookies) | if (V_tcp_syncookies) | ||||
sc->sc_iss = syncookie_generate(sch, sc); | sc->sc_iss = syncookie_generate(sch, sc); | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (autoflowlabel) { | if (autoflowlabel) { | ||||
if (V_tcp_syncookies) | if (V_tcp_syncookies) | ||||
sc->sc_flowlabel = sc->sc_iss; | sc->sc_flowlabel = sc->sc_iss; | ||||
else | else | ||||
sc->sc_flowlabel = ip6_randomflowlabel(); | sc->sc_flowlabel = ip6_randomflowlabel(); | ||||
▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | #endif /* INET */ | ||||
th->th_x2 = 0; | th->th_x2 = 0; | ||||
th->th_flags = flags; | th->th_flags = flags; | ||||
th->th_win = htons(sc->sc_wnd); | th->th_win = htons(sc->sc_wnd); | ||||
th->th_urp = 0; | th->th_urp = 0; | ||||
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ECN)) { | if ((flags & TH_SYN) && (sc->sc_flags & SCF_ECN)) { | ||||
th->th_flags |= TH_ECE; | th->th_flags |= TH_ECE; | ||||
TCPSTAT_INC(tcps_ecn_shs); | TCPSTAT_INC(tcps_ecn_shs); | ||||
} | |||||
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ACE_N)) { | |||||
th->th_flags |= TH_CWR; | |||||
TCPSTAT_INC(tcps_ecn_shs); | |||||
TCPSTAT_INC(tcps_ace_nect); | |||||
} | |||||
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ACE_0)) { | |||||
th->th_x2 |= (TH_AE >> 8); | |||||
TCPSTAT_INC(tcps_ecn_shs); | |||||
TCPSTAT_INC(tcps_ace_ect0); | |||||
} | |||||
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ACE_1)) { | |||||
th->th_flags |= (TH_ECE | TH_CWR); | |||||
TCPSTAT_INC(tcps_ecn_shs); | |||||
TCPSTAT_INC(tcps_ace_ect1); | |||||
} | |||||
if ((flags & TH_SYN) && (sc->sc_flags & SCF_ACE_CE)) { | |||||
th->th_flags |= TH_CWR; | |||||
th->th_x2 |= (TH_AE >> 8); | |||||
TCPSTAT_INC(tcps_ecn_shs); | |||||
TCPSTAT_INC(tcps_ace_ce); | |||||
} | } | ||||
/* Tack on the TCP options. */ | /* Tack on the TCP options. */ | ||||
if ((sc->sc_flags & SCF_NOOPT) == 0) { | if ((sc->sc_flags & SCF_NOOPT) == 0) { | ||||
to.to_flags = 0; | to.to_flags = 0; | ||||
if (flags & TH_SYN) { | if (flags & TH_SYN) { | ||||
to.to_mss = mssopt; | to.to_mss = mssopt; | ||||
▲ Show 20 Lines • Show All 527 Lines • Show Last 20 Lines |