Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_syncache.c
Show First 20 Lines • Show All 621 Lines • ▼ Show 20 Lines | if (syncache_cookiesonly()) | ||||
return; | return; | ||||
sc = syncache_lookup(inc, &sch); /* returns locked sch */ | sc = syncache_lookup(inc, &sch); /* returns locked sch */ | ||||
SCH_LOCK_ASSERT(sch); | SCH_LOCK_ASSERT(sch); | ||||
/* | /* | ||||
* Any RST to our SYN|ACK must not carry ACK, SYN or FIN flags. | * Any RST to our SYN|ACK must not carry ACK, SYN or FIN flags. | ||||
* See RFC 793 page 65, section SEGMENT ARRIVES. | * See RFC 793 page 65, section SEGMENT ARRIVES. | ||||
*/ | */ | ||||
if (th->th_flags & (TH_ACK|TH_SYN|TH_FIN)) { | if (tcp_get_flags(th) & (TH_ACK|TH_SYN|TH_FIN)) { | ||||
if ((s = tcp_log_addrs(inc, th, NULL, NULL))) | if ((s = tcp_log_addrs(inc, th, NULL, NULL))) | ||||
log(LOG_DEBUG, "%s; %s: Spurious RST with ACK, SYN or " | log(LOG_DEBUG, "%s; %s: Spurious RST with ACK, SYN or " | ||||
"FIN flag set, segment ignored\n", s, __func__); | "FIN flag set, segment ignored\n", s, __func__); | ||||
TCPSTAT_INC(tcps_badrst); | TCPSTAT_INC(tcps_badrst); | ||||
goto done; | goto done; | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 453 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct syncache *sc; | struct syncache *sc; | ||||
struct syncache_head *sch; | struct syncache_head *sch; | ||||
struct syncache scs; | struct syncache scs; | ||||
char *s; | char *s; | ||||
bool locked; | bool locked; | ||||
NET_EPOCH_ASSERT(); | NET_EPOCH_ASSERT(); | ||||
KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK, | KASSERT((tcp_get_flags(th) & (TH_RST|TH_ACK|TH_SYN)) == TH_ACK, | ||||
("%s: can handle only ACK", __func__)); | ("%s: can handle only ACK", __func__)); | ||||
if (syncache_cookiesonly()) { | if (syncache_cookiesonly()) { | ||||
sc = NULL; | sc = NULL; | ||||
sch = syncache_hashbucket(inc); | sch = syncache_hashbucket(inc); | ||||
locked = false; | locked = false; | ||||
} else { | } else { | ||||
sc = syncache_lookup(inc, &sch); /* returns locked sch */ | sc = syncache_lookup(inc, &sch); /* returns locked sch */ | ||||
▲ Show 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | #endif | ||||
struct ucred *cred; | struct ucred *cred; | ||||
uint64_t tfo_response_cookie; | uint64_t tfo_response_cookie; | ||||
unsigned int *tfo_pending = NULL; | unsigned int *tfo_pending = NULL; | ||||
int tfo_cookie_valid = 0; | int tfo_cookie_valid = 0; | ||||
int tfo_response_cookie_valid = 0; | int tfo_response_cookie_valid = 0; | ||||
bool locked; | bool locked; | ||||
INP_RLOCK_ASSERT(inp); /* listen socket */ | INP_RLOCK_ASSERT(inp); /* listen socket */ | ||||
KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN, | KASSERT((tcp_get_flags(th) & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN, | ||||
("%s: unexpected tcp flags", __func__)); | ("%s: unexpected tcp flags", __func__)); | ||||
/* | /* | ||||
* Combine all so/tp operations very early to drop the INP lock as | * Combine all so/tp operations very early to drop the INP lock as | ||||
* soon as possible. | * soon as possible. | ||||
*/ | */ | ||||
KASSERT(SOLISTENING(so), ("%s: %p not listening", __func__, so)); | KASSERT(SOLISTENING(so), ("%s: %p not listening", __func__, so)); | ||||
tp = sototcpcb(so); | tp = sototcpcb(so); | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | if (sc != NULL) { | ||||
if ((sc->sc_flags & SCF_TIMESTAMP) && (to->to_flags & TOF_TS)) | if ((sc->sc_flags & SCF_TIMESTAMP) && (to->to_flags & TOF_TS)) | ||||
sc->sc_tsreflect = to->to_tsval; | sc->sc_tsreflect = to->to_tsval; | ||||
else | else | ||||
sc->sc_flags &= ~SCF_TIMESTAMP; | sc->sc_flags &= ~SCF_TIMESTAMP; | ||||
/* | /* | ||||
* Disable ECN if needed. | * Disable ECN if needed. | ||||
*/ | */ | ||||
if ((sc->sc_flags & SCF_ECN) && | if ((sc->sc_flags & SCF_ECN) && | ||||
((th->th_flags & (TH_ECE|TH_CWR)) != (TH_ECE|TH_CWR))) { | ((tcp_get_flags(th) & (TH_ECE|TH_CWR)) != (TH_ECE|TH_CWR))) { | ||||
sc->sc_flags &= ~SCF_ECN; | sc->sc_flags &= ~SCF_ECN; | ||||
} | } | ||||
#ifdef MAC | #ifdef MAC | ||||
/* | /* | ||||
* Since we have already unconditionally allocated label | * Since we have already unconditionally allocated label | ||||
* storage, free it up. The syncache entry will already | * storage, free it up. The syncache entry will already | ||||
* have an initialized label we can use. | * have an initialized label we can use. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | if (to->to_flags & TOF_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)) == (TH_ECE|TH_CWR)) && | if (((tcp_get_flags(th) & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR)) && | ||||
V_tcp_do_ecn) | V_tcp_do_ecn) | ||||
sc->sc_flags |= SCF_ECN; | sc->sc_flags |= SCF_ECN; | ||||
if (V_tcp_syncookies) | if (V_tcp_syncookies) | ||||
sc->sc_iss = syncookie_generate(sch, sc); | sc->sc_iss = syncookie_generate(sch, sc); | ||||
else | else | ||||
sc->sc_iss = arc4random(); | sc->sc_iss = arc4random(); | ||||
#ifdef INET6 | #ifdef INET6 | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | #endif /* INET */ | ||||
th->th_dport = sc->sc_inc.inc_fport; | th->th_dport = sc->sc_inc.inc_fport; | ||||
if (flags & TH_SYN) | if (flags & TH_SYN) | ||||
th->th_seq = htonl(sc->sc_iss); | th->th_seq = htonl(sc->sc_iss); | ||||
else | else | ||||
th->th_seq = htonl(sc->sc_iss + 1); | th->th_seq = htonl(sc->sc_iss + 1); | ||||
th->th_ack = htonl(sc->sc_irs + 1); | th->th_ack = htonl(sc->sc_irs + 1); | ||||
th->th_off = sizeof(struct tcphdr) >> 2; | th->th_off = sizeof(struct tcphdr) >> 2; | ||||
th->th_x2 = 0; | |||||
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; | flags |= TH_ECE; | ||||
TCPSTAT_INC(tcps_ecn_shs); | TCPSTAT_INC(tcps_ecn_shs); | ||||
} | } | ||||
tcp_set_flags(th, flags); | |||||
/* 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; | ||||
to.to_flags = TOF_MSS; | to.to_flags = TOF_MSS; | ||||
▲ Show 20 Lines • Show All 641 Lines • Show Last 20 Lines |