Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_output.c
Show First 20 Lines • Show All 1,172 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
/* Handle parallel SYN for ECN */ | /* Handle parallel SYN for ECN */ | ||||
if ((tp->t_state == TCPS_SYN_RECEIVED) && | if ((tp->t_state == TCPS_SYN_RECEIVED) && | ||||
(tp->t_flags2 & TF2_ECN_SND_ECE)) { | (tp->t_flags2 & TF2_ECN_SND_ECE)) { | ||||
flags |= TH_ECE; | flags |= TH_ECE; | ||||
tp->t_flags2 &= ~TF2_ECN_SND_ECE; | tp->t_flags2 &= ~TF2_ECN_SND_ECE; | ||||
} | } | ||||
if (tp->t_state == TCPS_ESTABLISHED && | if (((tp->t_state == TCPS_ESTABLISHED) && | ||||
(tp->t_flags2 & TF2_ECN_PERMIT)) { | (tp->t_flags2 & TF2_ECN_PERMIT)) || | ||||
((tp->t_state > TCPS_ESTABLISHED) && | |||||
(tp->t_flags2 & TF2_ECN_PERMIT) && | |||||
V_tcp_ecn_generalized) || | |||||
/* | /* | ||||
* Note that a passive open SYN,ACK | |||||
* is actually sent from tcp_syncache | |||||
*/ | |||||
(((flags & (TH_SYN|TH_ACK)) == (TH_SYN)) && | |||||
((flags & (TH_ECE|TH_CWR)) == (TH_ECE|TH_CWR)) && | |||||
V_tcp_ecn_generalized) || | |||||
(((flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) && | |||||
(flags & (TH_CWR|TH_ECE)) && | |||||
V_tcp_ecn_generalized)) { | |||||
/* | |||||
* If the peer has ECN, mark data packets with | * If the peer has ECN, mark data packets with | ||||
* ECN capable transmission (ECT). | * ECN capable transmission (ECT). | ||||
* Ignore pure ack packets, retransmissions and window probes. | * Ignore pure ack packets, retransmissions and | ||||
* window probes unless doing generalized ECN. | |||||
*/ | */ | ||||
if (len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) && | if (V_tcp_ecn_generalized || | ||||
((len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) && | |||||
(sack_rxmit == 0) && | (sack_rxmit == 0) && | ||||
!((tp->t_flags & TF_FORCEDATA) && len == 1 && | !((tp->t_flags & TF_FORCEDATA) && len == 1 && | ||||
SEQ_LT(tp->snd_una, tp->snd_max))) { | SEQ_LT(tp->snd_una, tp->snd_max))))) { | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (isipv6) | if (isipv6) | ||||
ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20); | ip6->ip6_flow |= htonl(IPTOS_ECN_ECT0 << 20); | ||||
else | else | ||||
#endif | #endif | ||||
ip->ip_tos |= IPTOS_ECN_ECT0; | ip->ip_tos |= IPTOS_ECN_ECT0; | ||||
TCPSTAT_INC(tcps_ecn_ect0); | TCPSTAT_INC(tcps_ecn_ect0); | ||||
/* | /* | ||||
* Reply with proper ECN notifications. | * Reply with proper ECN notifications. | ||||
* Only set CWR on new data segments. | * Only set CWR on new data segments. | ||||
*/ | */ | ||||
if (tp->t_flags2 & TF2_ECN_SND_CWR) { | if ((tp->t_flags2 & TF2_ECN_SND_CWR) && | ||||
(len > 0 && SEQ_GEQ(tp->snd_nxt, tp->snd_max) && | |||||
(sack_rxmit == 0))) { | |||||
flags |= TH_CWR; | flags |= TH_CWR; | ||||
tp->t_flags2 &= ~TF2_ECN_SND_CWR; | tp->t_flags2 &= ~TF2_ECN_SND_CWR; | ||||
} | } | ||||
} | } | ||||
if (tp->t_flags2 & TF2_ECN_SND_ECE) | if (tp->t_flags2 & TF2_ECN_SND_ECE) | ||||
flags |= TH_ECE; | flags |= TH_ECE; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 910 Lines • Show Last 20 Lines |