Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/tcp_output.c
Show First 20 Lines • Show All 882 Lines • ▼ Show 20 Lines | #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) | ||||
/* TCP-MD5 (RFC2385). */ | /* TCP-MD5 (RFC2385). */ | ||||
/* | /* | ||||
* Check that TCP_MD5SIG is enabled in tcpcb to | * Check that TCP_MD5SIG is enabled in tcpcb to | ||||
* account the size needed to set this TCP option. | * account the size needed to set this TCP option. | ||||
*/ | */ | ||||
if (tp->t_flags & TF_SIGNATURE) | if (tp->t_flags & TF_SIGNATURE) | ||||
to.to_flags |= TOF_SIGNATURE; | to.to_flags |= TOF_SIGNATURE; | ||||
#endif /* TCP_SIGNATURE */ | #endif /* TCP_SIGNATURE */ | ||||
/* | |||||
* AccECN option | |||||
* Don't send on <SYN>, only on <SYN,ACK> or | |||||
* when doing an AccECN session | |||||
*/ | |||||
if (V_tcp_ecn_option && | |||||
((V_tcp_do_ecn == 3) || (V_tcp_do_ecn == 4)) && | |||||
((tp->t_flags2 & TF2_ACE_PERMIT) || | |||||
((flags & TH_SYN) && (flags & TH_ACK)))) { | |||||
to.to_flags |= TOF_ACCECNOPT; | |||||
to.to_ae = &tp->t_ae; | |||||
to.to_flags |= ((tp->t_flags2 & TF2_ACO_E0) ? TOF_ACCE_E0 : 0) | | |||||
((tp->t_flags2 & TF2_ACO_E1) ? TOF_ACCE_E1 : 0) | | |||||
((tp->t_flags2 & TF2_ACO_CE) ? TOF_ACCE_CE : 0); | |||||
if (flags & TH_SYN) | |||||
to.to_flags |= TOF_ACCE_SYN; | |||||
if (tp->t_flags & TF_ACKNOW) | |||||
to.to_flags |= TOF_ACCE_ACKNOW; | |||||
} | |||||
/* Processing the options. */ | /* Processing the options. */ | ||||
hdrlen += optlen = tcp_addoptions(&to, opt); | hdrlen += optlen = tcp_addoptions(&to, opt); | ||||
if (to.to_flags & TOF_ACCECNOPT) { | |||||
if ((to.to_flags & TOF_ACCE_E0) == 0) | |||||
tp->t_flags2 &= ~TF2_ACO_E0; | |||||
if ((to.to_flags & TOF_ACCE_E1) == 0) | |||||
tp->t_flags2 &= ~TF2_ACO_E1; | |||||
if ((to.to_flags & TOF_ACCE_CE) == 0) | |||||
tp->t_flags2 &= ~TF2_ACO_CE; | |||||
} | |||||
/* | /* | ||||
* If we wanted a TFO option to be added, but it was unable | * If we wanted a TFO option to be added, but it was unable | ||||
* to fit, ensure no data is sent. | * to fit, ensure no data is sent. | ||||
*/ | */ | ||||
if (IS_FASTOPEN(tp->t_flags) && wanted_cookie && | if (IS_FASTOPEN(tp->t_flags) && wanted_cookie && | ||||
!(to.to_flags & TOF_FASTOPEN)) | !(to.to_flags & TOF_FASTOPEN)) | ||||
len = 0; | len = 0; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,045 Lines • ▼ Show 20 Lines | case TOF_FASTOPEN: | ||||
*optp++ = TCPOPT_FAST_OPEN; | *optp++ = TCPOPT_FAST_OPEN; | ||||
*optp++ = total_len; | *optp++ = total_len; | ||||
if (to->to_tfo_len > 0) { | if (to->to_tfo_len > 0) { | ||||
bcopy(to->to_tfo_cookie, optp, to->to_tfo_len); | bcopy(to->to_tfo_cookie, optp, to->to_tfo_len); | ||||
optp += to->to_tfo_len; | optp += to->to_tfo_len; | ||||
} | } | ||||
optlen += total_len; | optlen += total_len; | ||||
break; | break; | ||||
} | |||||
case TOF_ACCECNOPT: | |||||
{ | |||||
int max_len = TCP_MAXOLEN - optlen; | |||||
if (max_len < TCPOLEN_ACCECN_EMPTY) { | |||||
to->to_flags &= ~TOF_ACCECNOPT; | |||||
continue; | |||||
} | |||||
if (max_len < (TCPOLEN_ACCECN_EMPTY + | |||||
1 * TCPOLEN_ACCECN_COUNTER)) { | |||||
if (to->to_flags & TOF_ACCE_SYN) { | |||||
*optp++ = TCPOPT_ACCECN0; | |||||
optlen += TCPOLEN_ACCECN_EMPTY; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY; | |||||
continue; | |||||
} else { | |||||
to->to_flags &= ~TOF_ACCECNOPT; | |||||
continue; | |||||
} | |||||
} | |||||
if (max_len < (TCPOLEN_ACCECN_EMPTY + | |||||
2 * TCPOLEN_ACCECN_COUNTER)) { | |||||
if (to->to_flags & TOF_ACCE_E1) { | |||||
*optp++ = TCPOPT_ACCECN1; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY + | |||||
TCPOLEN_ACCECN_COUNTER; | |||||
optlen += TCPOLEN_ACCECN_EMPTY + | |||||
TCPOLEN_ACCECN_COUNTER; | |||||
*optp++ = (char)(to->to_ae->re1b >> 16); | |||||
*optp++ = (char)(to->to_ae->re1b >> 8); | |||||
*optp++ = (char)(to->to_ae->re1b); | |||||
to->to_flags &= ~TOF_ACCE_E1; | |||||
continue; | |||||
} | |||||
*optp++ = TCPOPT_ACCECN0; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY + | |||||
TCPOLEN_ACCECN_COUNTER; | |||||
optlen += TCPOLEN_ACCECN_EMPTY + | |||||
TCPOLEN_ACCECN_COUNTER; | |||||
*optp++ = (char)(to->to_ae->re0b >> 16); | |||||
*optp++ = (char)(to->to_ae->re0b >> 8); | |||||
*optp++ = (char)(to->to_ae->re0b); | |||||
to->to_flags &= ~TOF_ACCE_E0; | |||||
continue; | |||||
} | |||||
if (max_len < (TCPOLEN_ACCECN_EMPTY + | |||||
3 * TCPOLEN_ACCECN_COUNTER)) { | |||||
if (to->to_flags & TOF_ACCE_E1) { | |||||
*optp++ = TCPOPT_ACCECN1; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY + | |||||
2 * TCPOLEN_ACCECN_COUNTER; | |||||
optlen += TCPOLEN_ACCECN_EMPTY + | |||||
2 * TCPOLEN_ACCECN_COUNTER; | |||||
*optp++ = (char)(to->to_ae->re1b >> 16); | |||||
*optp++ = (char)(to->to_ae->re1b >> 8); | |||||
*optp++ = (char)(to->to_ae->re1b); | |||||
to->to_flags &= ~TOF_ACCE_E1; | |||||
*optp++ = (char)(to->to_ae->rceb >> 16); | |||||
*optp++ = (char)(to->to_ae->rceb >> 8); | |||||
*optp++ = (char)(to->to_ae->rceb); | |||||
to->to_flags &= ~TOF_ACCE_CE; | |||||
continue; | |||||
} | |||||
*optp++ = TCPOPT_ACCECN0; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY + | |||||
2 * TCPOLEN_ACCECN_COUNTER; | |||||
optlen += TCPOLEN_ACCECN_EMPTY + | |||||
2 * TCPOLEN_ACCECN_COUNTER; | |||||
*optp++ = (char)(to->to_ae->re0b >> 16); | |||||
*optp++ = (char)(to->to_ae->re0b >> 8); | |||||
*optp++ = (char)(to->to_ae->re0b); | |||||
to->to_flags &= ~TOF_ACCE_E0; | |||||
*optp++ = (char)(to->to_ae->rceb >> 16); | |||||
*optp++ = (char)(to->to_ae->rceb >> 8); | |||||
*optp++ = (char)(to->to_ae->rceb); | |||||
to->to_flags &= ~TOF_ACCE_CE; | |||||
continue; | |||||
} | |||||
/* | |||||
* TCP option sufficient to hold full AccECN option | |||||
* but only send changed counters normally, | |||||
* full counters on ACKNOW | |||||
*/ | |||||
if (to->to_flags & TOF_ACCE_E1) { | |||||
*optp++ = TCPOPT_ACCECN1; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY + | |||||
3 * TCPOLEN_ACCECN_COUNTER; | |||||
optlen += TCPOLEN_ACCECN_EMPTY + | |||||
3 * TCPOLEN_ACCECN_COUNTER; | |||||
*optp++ = (char)(to->to_ae->re1b >> 16); | |||||
*optp++ = (char)(to->to_ae->re1b >> 8); | |||||
*optp++ = (char)(to->to_ae->re1b); | |||||
to->to_flags &= ~TOF_ACCE_E1; | |||||
*optp++ = (char)(to->to_ae->rceb >> 16); | |||||
*optp++ = (char)(to->to_ae->rceb >> 8); | |||||
*optp++ = (char)(to->to_ae->rceb); | |||||
to->to_flags &= ~TOF_ACCE_CE; | |||||
*optp++ = (char)(to->to_ae->re0b >> 16); | |||||
*optp++ = (char)(to->to_ae->re0b >> 8); | |||||
*optp++ = (char)(to->to_ae->re0b); | |||||
to->to_flags &= ~TOF_ACCE_E0; | |||||
continue; | |||||
} else { | |||||
*optp++ = TCPOPT_ACCECN0; | |||||
*optp++ = TCPOLEN_ACCECN_EMPTY + | |||||
3 * TCPOLEN_ACCECN_COUNTER; | |||||
optlen += TCPOLEN_ACCECN_EMPTY + | |||||
3 * TCPOLEN_ACCECN_COUNTER; | |||||
*optp++ = (char)(to->to_ae->re0b >> 16); | |||||
*optp++ = (char)(to->to_ae->re0b >> 8); | |||||
*optp++ = (char)(to->to_ae->re0b); | |||||
to->to_flags &= ~TOF_ACCE_E0; | |||||
*optp++ = (char)(to->to_ae->rceb >> 16); | |||||
*optp++ = (char)(to->to_ae->rceb >> 8); | |||||
*optp++ = (char)(to->to_ae->rceb); | |||||
to->to_flags &= ~TOF_ACCE_CE; | |||||
*optp++ = (char)(to->to_ae->re1b >> 16); | |||||
*optp++ = (char)(to->to_ae->re1b >> 8); | |||||
*optp++ = (char)(to->to_ae->re1b); | |||||
to->to_flags &= ~TOF_ACCE_E1; | |||||
continue; | |||||
} | |||||
} | } | ||||
default: | default: | ||||
panic("%s: unknown TCP option type", __func__); | panic("%s: unknown TCP option type", __func__); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* Terminate and pad TCP options to a 4 byte boundary. */ | /* Terminate and pad TCP options to a 4 byte boundary. */ | ||||
▲ Show 20 Lines • Show All 246 Lines • Show Last 20 Lines |