Remove RFC1644 T/TCP support from the TCP side of the network stack.

A complete rationale and discussion is given in this message
and the resulting discussion:

 http://docs.freebsd.org/cgi/mid.cgi?4177C8AD.6060706

Note that this commit removes only the functional part of T/TCP
from the tcp_* related functions in the kernel.  Other features
introduced with RFC1644 are left intact (socket layer changes,
sendmsg(2) on connection oriented protocols)  and are meant to
be reused by a simpler and less intrusive reimplemention of the
previous T/TCP functionality.

Discussed on:	-arch
This commit is contained in:
Andre Oppermann 2004-11-02 22:22:22 +00:00
parent 30bef41b8a
commit c94c54e4df
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137139
15 changed files with 41 additions and 854 deletions

View File

@ -23,6 +23,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 6.x IS SLOW:
developers choose to disable these features on build machines
to maximize performance.
20041102:
The size of struct tcpcb has changed again due to the removal
of RFC1644 T/TCP. You have to recompile userland programs that
read kmem for tcp sockets directly (netstat, sockstat, etc.)
20041022:
The size of struct tcpcb has changed. You have to recompile
userland programs that read kmem for tcp sockets directly

View File

@ -32,7 +32,7 @@
.\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
.Dd October 23, 2004
.Dd November 2, 2004
.Dt TCP 4
.Os
.Sh NAME
@ -233,16 +233,11 @@ protocol implements a number of variables in the
branch of the
.Xr sysctl 3
MIB.
.Bl -tag -width ".Va TCPCTL_DO_RFC1644"
.Bl -tag -width ".Va TCPCTL_DO_RFC1323"
.It Dv TCPCTL_DO_RFC1323
.Pq Va rfc1323
Implement the window scaling and timestamp options of RFC 1323
(default is true).
.It Dv TCPCTL_DO_RFC1644
.Pq Va rfc1644
Implement Transaction
.Tn TCP ,
as described in RFC 1644.
.It Dv TCPCTL_MSSDFLT
.Pq Va mssdflt
The default value used for the maximum segment size
@ -517,7 +512,6 @@ address.
.Xr intro 4 ,
.Xr ip 4 ,
.Xr syncache 4 ,
.Xr ttcp 4 ,
.Xr setkey 8
.Rs
.%A "V. Jacobson"
@ -527,11 +521,6 @@ address.
.%O "RFC 1323"
.Re
.Rs
.%A "R. Braden"
.%T "T/TCP - TCP Extensions for Transactions"
.%O "RFC 1644"
.Re
.Rs
.%A "A. Heffernan"
.%T "Protection of BGP Sessions via the TCP MD5 Signature Option"
.%O "RFC 2385"

View File

@ -412,11 +412,6 @@ tcpopts_match(struct ip *ip, ipfw_insn *cmd)
bits |= IP_FW_TCPOPT_TS;
break;
case TCPOPT_CC:
case TCPOPT_CCNEW:
case TCPOPT_CCECHO:
bits |= IP_FW_TCPOPT_CC;
break;
}
}
return (flags_match(cmd, bits));

View File

@ -38,7 +38,6 @@
#if __BSD_VISIBLE
typedef u_int32_t tcp_seq;
typedef u_int32_t tcp_cc; /* connection count per rfc1644 */
#define tcp6_seq tcp_seq /* for KAME src sync over BSD*'s */
#define tcp6hdr tcphdr /* for KAME src sync over BSD*'s */
@ -94,13 +93,6 @@ struct tcphdr {
#define MAX_TCPOPTLEN 40 /* Absolute maximum TCP options len */
#define TCPOPT_CC 11 /* CC options: RFC-1644 */
#define TCPOPT_CCNEW 12
#define TCPOPT_CCECHO 13
#define TCPOLEN_CC 6
#define TCPOLEN_CC_APPA (TCPOLEN_CC+2)
#define TCPOPT_CC_HDR(ccopt) \
(TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)
#define TCPOPT_SIGNATURE 19 /* Keyed MD5: RFC 2385 */
#define TCPOLEN_SIGNATURE 18

View File

@ -121,7 +121,6 @@ struct hc_metrics {
u_long rmx_cwnd; /* congestion window */
u_long rmx_sendpipe; /* outbound delay-bandwidth product */
u_long rmx_recvpipe; /* inbound delay-bandwidth product */
struct rmxp_tao rmx_tao; /* TAO cache for T/TCP */
/* tcp hostcache internal data */
int rmx_expire; /* lifetime for object */
u_long rmx_hits; /* number of hits */
@ -456,28 +455,6 @@ tcp_hc_getmtu(struct in_conninfo *inc)
return mtu;
}
/*
* External function: lookup an entry in the hostcache and fill out the
* supplied t/tcp tao structure. Fills in null when no entry was found
* or a value is not set.
*/
void
tcp_hc_gettao(struct in_conninfo *inc, struct rmxp_tao *tao)
{
struct hc_metrics *hc_entry;
hc_entry = tcp_hc_lookup(inc);
if (hc_entry == NULL) {
bzero(tao, sizeof(*tao));
return;
}
hc_entry->rmx_hits++;
hc_entry->rmx_expire = tcp_hostcache.expire; /* start over again */
bcopy(&hc_entry->rmx_tao, tao, sizeof(*tao));
THC_UNLOCK(&hc_entry->rmx_head->hch_mtx);
}
/*
* External function: update the mtu value of an entry in the hostcache.
* Creates a new entry if none was found.
@ -597,43 +574,6 @@ tcp_hc_update(struct in_conninfo *inc, struct hc_metrics_lite *hcml)
THC_UNLOCK(&hc_entry->rmx_head->hch_mtx);
}
/*
* External function: update the t/tcp tao of an entry in the hostcache.
* Creates a new entry if none was found.
*/
void
tcp_hc_updatetao(struct in_conninfo *inc, int field, tcp_cc ccount, u_short mss)
{
struct hc_metrics *hc_entry;
hc_entry = tcp_hc_lookup(inc);
if (hc_entry == NULL) {
hc_entry = tcp_hc_insert(inc);
if (hc_entry == NULL)
return;
}
hc_entry->rmx_updates++;
hc_entry->rmx_expire = tcp_hostcache.expire; /* start over again */
switch(field) {
case TCP_HC_TAO_CC:
hc_entry->rmx_tao.tao_cc = ccount;
break;
case TCP_HC_TAO_CCSENT:
hc_entry->rmx_tao.tao_ccsent = ccount;
break;
case TCP_HC_TAO_MSSOPT:
hc_entry->rmx_tao.tao_mssopt = mss;
break;
}
TAILQ_REMOVE(&hc_entry->rmx_head->hch_bucket, hc_entry, rmx_q);
TAILQ_INSERT_HEAD(&hc_entry->rmx_head->hch_bucket, hc_entry, rmx_q);
THC_UNLOCK(&hc_entry->rmx_head->hch_mtx);
}
/*
* Sysctl function: prints the list and values of all hostcache entries in
* unsorted order.

View File

@ -98,7 +98,6 @@
#include <machine/in_cksum.h>
static const int tcprexmtthresh = 3;
tcp_cc tcp_ccgen;
struct tcpstat tcpstat;
SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
@ -433,7 +432,6 @@ tcp_input(m, off0)
int todrop, acked, ourfinisacked, needoutput = 0;
u_long tiwin;
struct tcpopt to; /* options in this segment */
struct rmxp_tao tao; /* our TAO cache entry */
int headlocked = 0;
#ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag;
@ -460,7 +458,6 @@ tcp_input(m, off0)
#ifdef INET6
isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0;
#endif
bzero(&tao, sizeof(tao));
bzero((char *)&to, sizeof(to));
tcpstat.tcps_rcvtotal++;
@ -1090,8 +1087,6 @@ tcp_input(m, off0)
tp->ts_recent = to.to_tsval;
tp->ts_recent_age = ticks;
}
if (to.to_flags & (TOF_CC|TOF_CCNEW))
tp->t_flags |= TF_RCVD_CC;
if (to.to_flags & TOF_MSS)
tcp_mss(tp, to.to_mss);
if (tp->sack_enable) {
@ -1132,16 +1127,8 @@ tcp_input(m, off0)
((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) &&
((to.to_flags & TOF_TS) == 0 ||
TSTMP_GEQ(to.to_tsval, tp->ts_recent)) &&
/*
* Using the CC option is compulsory if once started:
* the segment is OK if no T/TCP was negotiated or
* if the segment has a CC option equal to CCrecv
*/
((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) != (TF_REQ_CC|TF_RCVD_CC) ||
((to.to_flags & TOF_CC) != 0 && to.to_cc == tp->cc_recv)) &&
th->th_seq == tp->rcv_nxt &&
tiwin && tiwin == tp->snd_wnd &&
tp->snd_nxt == tp->snd_max) {
th->th_seq == tp->rcv_nxt && tiwin && tiwin == tp->snd_wnd &&
tp->snd_nxt == tp->snd_max) {
/*
* If last ACK falls within this segment's sequence numbers,
@ -1345,26 +1332,11 @@ tcp_input(m, off0)
* continue processing rest of data/controls, beginning with URG
*/
case TCPS_SYN_SENT:
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if ((thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
/*
* If we have a cached CCsent for the remote host,
* hence we haven't just crashed and restarted,
* do not send a RST. This may be a retransmission
* from the other side after our earlier ACK was lost.
* Our new SYN, when it arrives, will serve as the
* needed ACK.
*/
if (tao.tao_ccsent != 0)
goto drop;
else {
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
if (thflags & TH_RST) {
if (thflags & TH_ACK)
@ -1374,30 +1346,10 @@ tcp_input(m, off0)
if ((thflags & TH_SYN) == 0)
goto drop;
tp->snd_wnd = th->th_win; /* initial send window */
tp->cc_recv = to.to_cc; /* foreign CC */
tp->irs = th->th_seq;
tcp_rcvseqinit(tp);
if (thflags & TH_ACK) {
/*
* Our SYN was acked. If segment contains CC.ECHO
* option, check it to make sure this segment really
* matches our SYN. If not, just drop it as old
* duplicate, but send an RST if we're still playing
* by the old rules. If no CC.ECHO option, make sure
* we don't get fooled into using T/TCP.
*/
if (to.to_flags & TOF_CCECHO) {
if (tp->cc_send != to.to_ccecho) {
if (tao.tao_ccsent != 0)
goto drop;
else {
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
}
} else
tp->t_flags &= ~TF_RCVD_CC;
tcpstat.tcps_connects++;
soisconnected(so);
#ifdef MAC
@ -1411,10 +1363,6 @@ tcp_input(m, off0)
tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_scale;
}
/* Segment is acceptable, update cache if undefined. */
if (tao.tao_ccsent == 0 && tcp_do_rfc1644)
tcp_hc_updatetao(&inp->inp_inc, TCP_HC_TAO_CCSENT, to.to_ccecho, 0);
tp->rcv_adv += tp->rcv_wnd;
tp->snd_una++; /* SYN is acked */
/*
@ -1455,40 +1403,7 @@ tcp_input(m, off0)
*/
tp->t_flags |= TF_ACKNOW;
callout_stop(tp->tt_rexmt);
if (to.to_flags & TOF_CC) {
if (tao.tao_cc != 0 &&
CC_GT(to.to_cc, tao.tao_cc)) {
/*
* update cache and make transition:
* SYN-SENT -> ESTABLISHED*
* SYN-SENT* -> FIN-WAIT-1*
*/
tao.tao_cc = to.to_cc;
tcp_hc_updatetao(&inp->inp_inc,
TCP_HC_TAO_CC, to.to_cc, 0);
tp->t_starttime = ticks;
if (tp->t_flags & TF_NEEDFIN) {
tp->t_state = TCPS_FIN_WAIT_1;
tp->t_flags &= ~TF_NEEDFIN;
} else {
tp->t_state = TCPS_ESTABLISHED;
callout_reset(tp->tt_keep,
tcp_keepidle,
tcp_timer_keep,
tp);
}
tp->t_flags |= TF_NEEDSYN;
} else
tp->t_state = TCPS_SYN_RECEIVED;
} else {
if (tcp_do_rfc1644) {
/* CC.NEW or no option => invalidate cache */
tao.tao_cc = 0;
tcp_hc_updatetao(&inp->inp_inc,
TCP_HC_TAO_CC, to.to_cc, 0);
}
tp->t_state = TCPS_SYN_RECEIVED;
}
tp->t_state = TCPS_SYN_RECEIVED;
}
trimthenstep6:
@ -1526,36 +1441,14 @@ tcp_input(m, off0)
/*
* If the state is LAST_ACK or CLOSING or TIME_WAIT:
* if segment contains a SYN and CC [not CC.NEW] option:
* if state == TIME_WAIT and connection duration > MSL,
* drop packet and send RST;
* do normal processing.
*
* if SEG.CC > CCrecv then is new SYN, and can implicitly
* ack the FIN (and data) in retransmission queue.
* Complete close and delete TCPCB. Then reprocess
* segment, hoping to find new TCPCB in LISTEN state;
*
* else must be old SYN; drop it.
* else do normal processing.
* NB: Leftover from RFC1644 T/TCP. Cases to be reused later.
*/
case TCPS_LAST_ACK:
case TCPS_CLOSING:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("timewait"));
if ((thflags & TH_SYN) &&
(to.to_flags & TOF_CC) && tp->cc_recv != 0) {
if (tp->t_state == TCPS_TIME_WAIT &&
(ticks - tp->t_starttime) > tcp_msl) {
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
if (CC_GT(to.to_cc, tp->cc_recv)) {
tp = tcp_close(tp);
goto findpcb;
}
else
goto drop;
}
break; /* continue normal processing */
}
@ -1690,16 +1583,6 @@ tcp_input(m, off0)
}
}
/*
* T/TCP mechanism
* If T/TCP was negotiated and the segment doesn't have CC,
* or if its CC is wrong then drop the segment.
* RST segments do not have to comply with this.
*/
if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
((to.to_flags & TOF_CC) == 0 || tp->cc_recv != to.to_cc))
goto dropafterack;
/*
* In the SYN-RECEIVED state, validate that the packet belongs to
* this connection before trimming the data to fit the receive
@ -1866,16 +1749,6 @@ tcp_input(m, off0)
tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_scale;
}
/*
* Upon successful completion of 3-way handshake,
* update cache.CC, pass any queued data to the user,
* and advance state appropriately.
*/
if (tcp_do_rfc1644) {
tao.tao_cc = tp->cc_recv;
tcp_hc_updatetao(&inp->inp_inc, TCP_HC_TAO_CC,
tp->cc_recv, 0);
}
/*
* Make transitions:
* SYN-RECEIVED -> ESTABLISHED
@ -2682,34 +2555,6 @@ tcp_dooptions(tp, to, cp, cnt, is_syn, th)
(char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr);
break;
case TCPOPT_CC:
if (optlen != TCPOLEN_CC)
continue;
to->to_flags |= TOF_CC;
bcopy((char *)cp + 2,
(char *)&to->to_cc, sizeof(to->to_cc));
to->to_cc = ntohl(to->to_cc);
break;
case TCPOPT_CCNEW:
if (optlen != TCPOLEN_CC)
continue;
if (!is_syn)
continue;
to->to_flags |= TOF_CCNEW;
bcopy((char *)cp + 2,
(char *)&to->to_cc, sizeof(to->to_cc));
to->to_cc = ntohl(to->to_cc);
break;
case TCPOPT_CCECHO:
if (optlen != TCPOLEN_CC)
continue;
if (!is_syn)
continue;
to->to_flags |= TOF_CCECHO;
bcopy((char *)cp + 2,
(char *)&to->to_ccecho, sizeof(to->to_ccecho));
to->to_ccecho = ntohl(to->to_ccecho);
break;
#ifdef TCP_SIGNATURE
/*
* XXX In order to reply to a host which has set the
@ -2900,7 +2745,6 @@ tcp_mss(tp, offer)
struct inpcb *inp = tp->t_inpcb;
struct socket *so;
struct hc_metrics_lite metrics;
struct rmxp_tao tao;
int origoffer = offer;
#ifdef INET6
int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0;
@ -2910,7 +2754,6 @@ tcp_mss(tp, offer)
#else
const size_t min_protoh = sizeof(struct tcpiphdr);
#endif
bzero(&tao, sizeof(tao));
/* initialize */
#ifdef INET6
@ -2947,13 +2790,8 @@ tcp_mss(tp, offer)
case -1:
/*
* Offer == -1 means that we didn't receive SYN yet,
* use cached value in that case;
* Offer == -1 means that we didn't receive SYN yet.
*/
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if (tao.tao_mssopt != 0)
offer = tao.tao_mssopt;
/* FALLTHROUGH */
default:
@ -2969,9 +2807,6 @@ tcp_mss(tp, offer)
* funny things may happen in tcp_output.
*/
offer = max(offer, 64);
if (tcp_do_rfc1644)
tcp_hc_updatetao(&inp->inp_inc,
TCP_HC_TAO_MSSOPT, 0, offer);
}
/*
@ -3013,18 +2848,13 @@ tcp_mss(tp, offer)
tp->t_maxopd = mss;
/*
* In case of T/TCP, origoffer==-1 indicates, that no segments
* were received yet. In this case we just guess, otherwise
* we do the same as before T/TCP.
* origoffer==-1 indicates, that no segments were received yet.
* In this case we just guess.
*/
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(origoffer == -1 ||
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
mss -= TCPOLEN_TSTAMP_APPA;
if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
(origoffer == -1 ||
(tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC))
mss -= TCPOLEN_CC_APPA;
tp->t_maxseg = mss;
#if (MCLBYTES & (MCLBYTES - 1)) == 0
@ -3251,27 +3081,6 @@ tcp_timewait(tw, to, th, m, tlen)
if (thflags & TH_RST)
goto drop;
/*
* If segment contains a SYN and CC [not CC.NEW] option:
* if connection duration > MSL, drop packet and send RST;
*
* if SEG.CC > CCrecv then is new SYN.
* Complete close and delete TCPCB. Then reprocess
* segment, hoping to find new TCPCB in LISTEN state;
*
* else must be old SYN; drop it.
* else do normal processing.
*/
if ((thflags & TH_SYN) && (to->to_flags & TOF_CC) && tw->cc_recv != 0) {
if ((ticks - tw->t_starttime) > tcp_msl)
goto reset;
if (CC_GT(to->to_cc, tw->cc_recv)) {
(void) tcp_twclose(tw, 0);
return (1);
}
goto drop;
}
#if 0
/* PAWS not needed at the moment */
/*
@ -3323,7 +3132,6 @@ tcp_timewait(tw, to, th, m, tlen)
tcp_twrespond(tw, TH_ACK);
goto drop;
reset:
/*
* Generate a RST, dropping incoming segment.
* Make ACK acceptable to originator of segment.

View File

@ -129,12 +129,10 @@ tcp_output(struct tcpcb *tp)
#if 0
int maxburst = TCP_MAXBURST;
#endif
struct rmxp_tao tao;
#ifdef INET6
struct ip6_hdr *ip6 = NULL;
int isipv6;
bzero(&tao, sizeof(tao));
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0;
#endif
@ -329,22 +327,14 @@ tcp_output(struct tcpcb *tp)
if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) {
flags &= ~TH_SYN;
off--, len++;
if (tcp_do_rfc1644)
tcp_hc_gettao(&tp->t_inpcb->inp_inc, &tao);
if (len > 0 && tp->t_state == TCPS_SYN_SENT &&
tao.tao_ccsent == 0)
goto just_return;
}
/*
* Be careful not to send data and/or FIN on SYN segments
* in cases when no CC option will be sent.
* Be careful not to send data and/or FIN on SYN segments.
* This measure is needed to prevent interoperability problems
* with not fully conformant TCP implementations.
*/
if ((flags & TH_SYN) &&
((tp->t_flags & TF_NOOPT) || !(tp->t_flags & TF_REQ_CC) ||
((flags & TH_ACK) && !(tp->t_flags & TF_RCVD_CC)))) {
if ((flags & TH_SYN) && (tp->t_flags & TF_NOOPT)) {
len = 0;
flags &= ~TH_FIN;
}
@ -613,76 +603,6 @@ tcp_output(struct tcpcb *tp)
*olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2));
optlen += TCPOLEN_SACK*count + 4; /* including leading NOPs */
}
/*
* Send `CC-family' options if our side wants to use them (TF_REQ_CC),
* options are allowed (!TF_NOOPT) and it's not a RST.
*/
if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
(flags & TH_RST) == 0) {
switch (flags & (TH_SYN|TH_ACK)) {
/*
* This is a normal ACK, send CC if we received CC before
* from our peer.
*/
case TH_ACK:
if (!(tp->t_flags & TF_RCVD_CC))
break;
/*FALLTHROUGH*/
/*
* We can only get here in T/TCP's SYN_SENT* state, when
* we're a sending a non-SYN segment without waiting for
* the ACK of our SYN. A check above assures that we only
* do this if our peer understands T/TCP.
*/
case 0:
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_CC;
opt[optlen++] = TCPOLEN_CC;
*(u_int32_t *)&opt[optlen] = htonl(tp->cc_send);
optlen += 4;
break;
/*
* This is our initial SYN, check whether we have to use
* CC or CC.new.
*/
case TH_SYN:
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = tp->t_flags & TF_SENDCCNEW ?
TCPOPT_CCNEW : TCPOPT_CC;
opt[optlen++] = TCPOLEN_CC;
*(u_int32_t *)&opt[optlen] = htonl(tp->cc_send);
optlen += 4;
break;
/*
* This is a SYN,ACK; send CC and CC.echo if we received
* CC from our peer.
*/
case (TH_SYN|TH_ACK):
if (tp->t_flags & TF_RCVD_CC) {
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_CC;
opt[optlen++] = TCPOLEN_CC;
*(u_int32_t *)&opt[optlen] =
htonl(tp->cc_send);
optlen += 4;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_CCECHO;
opt[optlen++] = TCPOLEN_CC;
*(u_int32_t *)&opt[optlen] =
htonl(tp->cc_recv);
optlen += 4;
}
break;
}
}
#ifdef TCP_SIGNATURE
#ifdef INET6

View File

@ -98,7 +98,6 @@
#include <machine/in_cksum.h>
static const int tcprexmtthresh = 3;
tcp_cc tcp_ccgen;
struct tcpstat tcpstat;
SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
@ -433,7 +432,6 @@ tcp_input(m, off0)
int todrop, acked, ourfinisacked, needoutput = 0;
u_long tiwin;
struct tcpopt to; /* options in this segment */
struct rmxp_tao tao; /* our TAO cache entry */
int headlocked = 0;
#ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag;
@ -460,7 +458,6 @@ tcp_input(m, off0)
#ifdef INET6
isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0;
#endif
bzero(&tao, sizeof(tao));
bzero((char *)&to, sizeof(to));
tcpstat.tcps_rcvtotal++;
@ -1090,8 +1087,6 @@ tcp_input(m, off0)
tp->ts_recent = to.to_tsval;
tp->ts_recent_age = ticks;
}
if (to.to_flags & (TOF_CC|TOF_CCNEW))
tp->t_flags |= TF_RCVD_CC;
if (to.to_flags & TOF_MSS)
tcp_mss(tp, to.to_mss);
if (tp->sack_enable) {
@ -1132,16 +1127,8 @@ tcp_input(m, off0)
((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) &&
((to.to_flags & TOF_TS) == 0 ||
TSTMP_GEQ(to.to_tsval, tp->ts_recent)) &&
/*
* Using the CC option is compulsory if once started:
* the segment is OK if no T/TCP was negotiated or
* if the segment has a CC option equal to CCrecv
*/
((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) != (TF_REQ_CC|TF_RCVD_CC) ||
((to.to_flags & TOF_CC) != 0 && to.to_cc == tp->cc_recv)) &&
th->th_seq == tp->rcv_nxt &&
tiwin && tiwin == tp->snd_wnd &&
tp->snd_nxt == tp->snd_max) {
th->th_seq == tp->rcv_nxt && tiwin && tiwin == tp->snd_wnd &&
tp->snd_nxt == tp->snd_max) {
/*
* If last ACK falls within this segment's sequence numbers,
@ -1345,26 +1332,11 @@ tcp_input(m, off0)
* continue processing rest of data/controls, beginning with URG
*/
case TCPS_SYN_SENT:
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if ((thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) ||
SEQ_GT(th->th_ack, tp->snd_max))) {
/*
* If we have a cached CCsent for the remote host,
* hence we haven't just crashed and restarted,
* do not send a RST. This may be a retransmission
* from the other side after our earlier ACK was lost.
* Our new SYN, when it arrives, will serve as the
* needed ACK.
*/
if (tao.tao_ccsent != 0)
goto drop;
else {
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
if (thflags & TH_RST) {
if (thflags & TH_ACK)
@ -1374,30 +1346,10 @@ tcp_input(m, off0)
if ((thflags & TH_SYN) == 0)
goto drop;
tp->snd_wnd = th->th_win; /* initial send window */
tp->cc_recv = to.to_cc; /* foreign CC */
tp->irs = th->th_seq;
tcp_rcvseqinit(tp);
if (thflags & TH_ACK) {
/*
* Our SYN was acked. If segment contains CC.ECHO
* option, check it to make sure this segment really
* matches our SYN. If not, just drop it as old
* duplicate, but send an RST if we're still playing
* by the old rules. If no CC.ECHO option, make sure
* we don't get fooled into using T/TCP.
*/
if (to.to_flags & TOF_CCECHO) {
if (tp->cc_send != to.to_ccecho) {
if (tao.tao_ccsent != 0)
goto drop;
else {
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
}
} else
tp->t_flags &= ~TF_RCVD_CC;
tcpstat.tcps_connects++;
soisconnected(so);
#ifdef MAC
@ -1411,10 +1363,6 @@ tcp_input(m, off0)
tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_scale;
}
/* Segment is acceptable, update cache if undefined. */
if (tao.tao_ccsent == 0 && tcp_do_rfc1644)
tcp_hc_updatetao(&inp->inp_inc, TCP_HC_TAO_CCSENT, to.to_ccecho, 0);
tp->rcv_adv += tp->rcv_wnd;
tp->snd_una++; /* SYN is acked */
/*
@ -1455,40 +1403,7 @@ tcp_input(m, off0)
*/
tp->t_flags |= TF_ACKNOW;
callout_stop(tp->tt_rexmt);
if (to.to_flags & TOF_CC) {
if (tao.tao_cc != 0 &&
CC_GT(to.to_cc, tao.tao_cc)) {
/*
* update cache and make transition:
* SYN-SENT -> ESTABLISHED*
* SYN-SENT* -> FIN-WAIT-1*
*/
tao.tao_cc = to.to_cc;
tcp_hc_updatetao(&inp->inp_inc,
TCP_HC_TAO_CC, to.to_cc, 0);
tp->t_starttime = ticks;
if (tp->t_flags & TF_NEEDFIN) {
tp->t_state = TCPS_FIN_WAIT_1;
tp->t_flags &= ~TF_NEEDFIN;
} else {
tp->t_state = TCPS_ESTABLISHED;
callout_reset(tp->tt_keep,
tcp_keepidle,
tcp_timer_keep,
tp);
}
tp->t_flags |= TF_NEEDSYN;
} else
tp->t_state = TCPS_SYN_RECEIVED;
} else {
if (tcp_do_rfc1644) {
/* CC.NEW or no option => invalidate cache */
tao.tao_cc = 0;
tcp_hc_updatetao(&inp->inp_inc,
TCP_HC_TAO_CC, to.to_cc, 0);
}
tp->t_state = TCPS_SYN_RECEIVED;
}
tp->t_state = TCPS_SYN_RECEIVED;
}
trimthenstep6:
@ -1526,36 +1441,14 @@ tcp_input(m, off0)
/*
* If the state is LAST_ACK or CLOSING or TIME_WAIT:
* if segment contains a SYN and CC [not CC.NEW] option:
* if state == TIME_WAIT and connection duration > MSL,
* drop packet and send RST;
* do normal processing.
*
* if SEG.CC > CCrecv then is new SYN, and can implicitly
* ack the FIN (and data) in retransmission queue.
* Complete close and delete TCPCB. Then reprocess
* segment, hoping to find new TCPCB in LISTEN state;
*
* else must be old SYN; drop it.
* else do normal processing.
* NB: Leftover from RFC1644 T/TCP. Cases to be reused later.
*/
case TCPS_LAST_ACK:
case TCPS_CLOSING:
case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("timewait"));
if ((thflags & TH_SYN) &&
(to.to_flags & TOF_CC) && tp->cc_recv != 0) {
if (tp->t_state == TCPS_TIME_WAIT &&
(ticks - tp->t_starttime) > tcp_msl) {
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
if (CC_GT(to.to_cc, tp->cc_recv)) {
tp = tcp_close(tp);
goto findpcb;
}
else
goto drop;
}
break; /* continue normal processing */
}
@ -1690,16 +1583,6 @@ tcp_input(m, off0)
}
}
/*
* T/TCP mechanism
* If T/TCP was negotiated and the segment doesn't have CC,
* or if its CC is wrong then drop the segment.
* RST segments do not have to comply with this.
*/
if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
((to.to_flags & TOF_CC) == 0 || tp->cc_recv != to.to_cc))
goto dropafterack;
/*
* In the SYN-RECEIVED state, validate that the packet belongs to
* this connection before trimming the data to fit the receive
@ -1866,16 +1749,6 @@ tcp_input(m, off0)
tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_scale;
}
/*
* Upon successful completion of 3-way handshake,
* update cache.CC, pass any queued data to the user,
* and advance state appropriately.
*/
if (tcp_do_rfc1644) {
tao.tao_cc = tp->cc_recv;
tcp_hc_updatetao(&inp->inp_inc, TCP_HC_TAO_CC,
tp->cc_recv, 0);
}
/*
* Make transitions:
* SYN-RECEIVED -> ESTABLISHED
@ -2682,34 +2555,6 @@ tcp_dooptions(tp, to, cp, cnt, is_syn, th)
(char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr);
break;
case TCPOPT_CC:
if (optlen != TCPOLEN_CC)
continue;
to->to_flags |= TOF_CC;
bcopy((char *)cp + 2,
(char *)&to->to_cc, sizeof(to->to_cc));
to->to_cc = ntohl(to->to_cc);
break;
case TCPOPT_CCNEW:
if (optlen != TCPOLEN_CC)
continue;
if (!is_syn)
continue;
to->to_flags |= TOF_CCNEW;
bcopy((char *)cp + 2,
(char *)&to->to_cc, sizeof(to->to_cc));
to->to_cc = ntohl(to->to_cc);
break;
case TCPOPT_CCECHO:
if (optlen != TCPOLEN_CC)
continue;
if (!is_syn)
continue;
to->to_flags |= TOF_CCECHO;
bcopy((char *)cp + 2,
(char *)&to->to_ccecho, sizeof(to->to_ccecho));
to->to_ccecho = ntohl(to->to_ccecho);
break;
#ifdef TCP_SIGNATURE
/*
* XXX In order to reply to a host which has set the
@ -2900,7 +2745,6 @@ tcp_mss(tp, offer)
struct inpcb *inp = tp->t_inpcb;
struct socket *so;
struct hc_metrics_lite metrics;
struct rmxp_tao tao;
int origoffer = offer;
#ifdef INET6
int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0;
@ -2910,7 +2754,6 @@ tcp_mss(tp, offer)
#else
const size_t min_protoh = sizeof(struct tcpiphdr);
#endif
bzero(&tao, sizeof(tao));
/* initialize */
#ifdef INET6
@ -2947,13 +2790,8 @@ tcp_mss(tp, offer)
case -1:
/*
* Offer == -1 means that we didn't receive SYN yet,
* use cached value in that case;
* Offer == -1 means that we didn't receive SYN yet.
*/
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if (tao.tao_mssopt != 0)
offer = tao.tao_mssopt;
/* FALLTHROUGH */
default:
@ -2969,9 +2807,6 @@ tcp_mss(tp, offer)
* funny things may happen in tcp_output.
*/
offer = max(offer, 64);
if (tcp_do_rfc1644)
tcp_hc_updatetao(&inp->inp_inc,
TCP_HC_TAO_MSSOPT, 0, offer);
}
/*
@ -3013,18 +2848,13 @@ tcp_mss(tp, offer)
tp->t_maxopd = mss;
/*
* In case of T/TCP, origoffer==-1 indicates, that no segments
* were received yet. In this case we just guess, otherwise
* we do the same as before T/TCP.
* origoffer==-1 indicates, that no segments were received yet.
* In this case we just guess.
*/
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(origoffer == -1 ||
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
mss -= TCPOLEN_TSTAMP_APPA;
if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
(origoffer == -1 ||
(tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC))
mss -= TCPOLEN_CC_APPA;
tp->t_maxseg = mss;
#if (MCLBYTES & (MCLBYTES - 1)) == 0
@ -3251,27 +3081,6 @@ tcp_timewait(tw, to, th, m, tlen)
if (thflags & TH_RST)
goto drop;
/*
* If segment contains a SYN and CC [not CC.NEW] option:
* if connection duration > MSL, drop packet and send RST;
*
* if SEG.CC > CCrecv then is new SYN.
* Complete close and delete TCPCB. Then reprocess
* segment, hoping to find new TCPCB in LISTEN state;
*
* else must be old SYN; drop it.
* else do normal processing.
*/
if ((thflags & TH_SYN) && (to->to_flags & TOF_CC) && tw->cc_recv != 0) {
if ((ticks - tw->t_starttime) > tcp_msl)
goto reset;
if (CC_GT(to->to_cc, tw->cc_recv)) {
(void) tcp_twclose(tw, 0);
return (1);
}
goto drop;
}
#if 0
/* PAWS not needed at the moment */
/*
@ -3323,7 +3132,6 @@ tcp_timewait(tw, to, th, m, tlen)
tcp_twrespond(tw, TH_ACK);
goto drop;
reset:
/*
* Generate a RST, dropping incoming segment.
* Make ACK acceptable to originator of segment.

View File

@ -77,7 +77,4 @@
#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * hz)
/* timestamp wrap-around time */
#ifdef _KERNEL
extern tcp_cc tcp_ccgen; /* global connection count */
#endif /* _KERNEL */
#endif /* _NETINET_TCP_SEQ_H_ */

View File

@ -155,10 +155,6 @@ int tcp_do_rfc1323 = 1;
SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW,
&tcp_do_rfc1323 , 0, "Enable rfc1323 (high performance TCP) extensions");
int tcp_do_rfc1644 = 0;
SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1644, rfc1644, CTLFLAG_RW,
&tcp_do_rfc1644 , 0, "Enable rfc1644 (TTCP) extensions");
static int tcp_tcbhashsize = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN,
&tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
@ -246,8 +242,6 @@ tcp_init()
{
int hashsize = TCBHASHSIZE;
tcp_ccgen = 1;
tcp_delacktime = TCPTV_DELACK;
tcp_keepinit = TCPTV_KEEP_INIT;
tcp_keepidle = TCPTV_KEEP_IDLE;
@ -613,8 +607,6 @@ tcp_newtcpcb(inp)
if (tcp_do_rfc1323)
tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP);
if (tcp_do_rfc1644)
tp->t_flags |= TF_REQ_CC;
tp->sack_enable = tcp_do_sack;
tp->t_inpcb = inp; /* XXX */
/*
@ -1409,7 +1401,6 @@ tcp_mtudisc(inp, errno)
int errno;
{
struct tcpcb *tp = intotcpcb(inp);
struct rmxp_tao tao;
struct socket *so = inp->inp_socket;
u_int maxmtu;
u_int romtu;
@ -1417,7 +1408,6 @@ tcp_mtudisc(inp, errno)
#ifdef INET6
int isipv6;
#endif /* INET6 */
bzero(&tao, sizeof(tao));
if (tp != NULL) {
#ifdef INET6
@ -1452,11 +1442,6 @@ tcp_mtudisc(inp, errno)
#endif /* INET6 */
;
if (tcp_do_rfc1644) {
tcp_hc_gettao(&inp->inp_inc, &tao);
if (tao.tao_mssopt)
mss = min(mss, tao.tao_mssopt);
}
/*
* XXX - The above conditional probably violates the TCP
* spec. The problem is that, since we don't know the
@ -1481,9 +1466,6 @@ tcp_mtudisc(inp, errno)
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
mss -= TCPOLEN_TSTAMP_APPA;
if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
(tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC)
mss -= TCPOLEN_CC_APPA;
#if (MCLBYTES & (MCLBYTES - 1)) == 0
if (mss > MCLBYTES)
mss &= ~(MCLBYTES-1);
@ -1659,8 +1641,6 @@ tcp_twstart(tp)
tw->rcv_nxt = tp->rcv_nxt;
tw->iss = tp->iss;
tw->irs = tp->irs;
tw->cc_recv = tp->cc_recv;
tw->cc_send = tp->cc_send;
tw->t_starttime = tp->t_starttime;
tw->tw_time = 0;
@ -1669,15 +1649,8 @@ tcp_twstart(tp)
* be used for fin-wait-2 state also, then we may need
* a ts_recent from the last segment.
*/
/* Shorten TIME_WAIT [RFC-1644, p.28] */
if (tp->cc_recv != 0 && (ticks - tp->t_starttime) < tcp_msl) {
tw_time = tp->t_rxtcur * TCPTV_TWTRUNC;
/* For T/TCP client, force ACK now. */
acknow = 1;
} else {
tw_time = 2 * tcp_msl;
acknow = tp->t_flags & TF_ACKNOW;
}
tw_time = 2 * tcp_msl;
acknow = tp->t_flags & TF_ACKNOW;
tcp_discardcb(tp);
so = inp->inp_socket;
ACCEPT_LOCK();
@ -1803,16 +1776,6 @@ tcp_twrespond(struct tcptw *tw, int flags)
optp += TCPOLEN_TSTAMP_APPA;
}
/*
* Send `CC-family' options if needed, and it's not a RST.
*/
if (tw->cc_recv != 0 && flags == TH_ACK) {
u_int32_t *lp = (u_int32_t *)optp;
*lp++ = htonl(TCPOPT_CC_HDR(TCPOPT_CC));
*lp = htonl(tw->cc_send);
optp += TCPOLEN_CC_APPA;
}
optlen = optp - (u_int8_t *)(th + 1);
m->m_len = hdrlen + optlen;

View File

@ -694,16 +694,6 @@ syncache_socket(sc, lso, m)
tp->ts_recent = sc->sc_tsrecent;
tp->ts_recent_age = ticks;
}
if (sc->sc_flags & SCF_CC) {
/*
* Initialization of the tcpcb for transaction;
* set SND.WND = SEG.WND,
* initialize CCsend and CCrecv.
*/
tp->t_flags |= TF_REQ_CC|TF_RCVD_CC;
tp->cc_send = sc->sc_cc_send;
tp->cc_recv = sc->sc_cc_recv;
}
#ifdef TCP_SIGNATURE
if (sc->sc_flags & SCF_SIGNATURE)
tp->t_flags |= TF_SIGNATURE;
@ -831,7 +821,6 @@ syncache_add(inc, to, th, sop, m)
struct syncache *sc = NULL;
struct syncache_head *sch;
struct mbuf *ipopts = NULL;
struct rmxp_tao tao;
u_int32_t flowtmp;
int i, win;
@ -839,7 +828,6 @@ syncache_add(inc, to, th, sop, m)
so = *sop;
tp = sototcpcb(so);
bzero(&tao, sizeof(tao));
/*
* Remember the IP options, if any.
@ -989,17 +977,6 @@ syncache_add(inc, to, th, sop, m)
sc->sc_flags |= SCF_WINSCALE;
}
}
if (tcp_do_rfc1644) {
/*
* A CC or CC.new option received in a SYN makes
* it ok to send CC in subsequent segments.
*/
if (to->to_flags & (TOF_CC|TOF_CCNEW)) {
sc->sc_cc_recv = to->to_cc;
sc->sc_cc_send = CC_INC(tcp_ccgen);
sc->sc_flags |= SCF_CC;
}
}
if (tp->t_flags & TF_NOOPT)
sc->sc_flags = SCF_NOOPT;
#ifdef TCP_SIGNATURE
@ -1018,58 +995,7 @@ syncache_add(inc, to, th, sop, m)
sc->sc_flags |= SCF_SACK;
/*
* XXX
* We have the option here of not doing TAO (even if the segment
* qualifies) and instead fall back to a normal 3WHS via the syncache.
* This allows us to apply synflood protection to TAO-qualifying SYNs
* also. However, there should be a hueristic to determine when to
* do this, and is not present at the moment.
*/
/*
* Perform TAO test on incoming CC (SEG.CC) option, if any.
* - compare SEG.CC against cached CC from the same host, if any.
* - if SEG.CC > chached value, SYN must be new and is accepted
* immediately: save new CC in the cache, mark the socket
* connected, enter ESTABLISHED state, turn on flag to
* send a SYN in the next segment.
* A virtual advertised window is set in rcv_adv to
* initialize SWS prevention. Then enter normal segment
* processing: drop SYN, process data and FIN.
* - otherwise do a normal 3-way handshake.
*/
if (tcp_do_rfc1644)
tcp_hc_gettao(&sc->sc_inc, &tao);
if ((to->to_flags & TOF_CC) != 0) {
if (((tp->t_flags & TF_NOPUSH) != 0) &&
sc->sc_flags & SCF_CC && tao.tao_cc != 0 &&
CC_GT(to->to_cc, tao.tao_cc)) {
sc->sc_rxtslot = 0;
so = syncache_socket(sc, *sop, m);
if (so != NULL) {
tao.tao_cc = to->to_cc;
tcp_hc_updatetao(&sc->sc_inc, TCP_HC_TAO_CC,
tao.tao_cc, 0);
*sop = so;
}
syncache_free(sc);
return (so != NULL);
}
} else {
/*
* No CC option, but maybe CC.NEW: invalidate cached value.
*/
if (tcp_do_rfc1644) {
tao.tao_cc = 0;
tcp_hc_updatetao(&sc->sc_inc, TCP_HC_TAO_CC,
tao.tao_cc, 0);
}
}
/*
* TAO test failed or there was no CC option,
* do a standard 3-way handshake.
* Do a standard 3-way handshake.
*/
#ifdef TCPDEBUG
if (syncache_respond(sc, m, so) == 0) {
@ -1127,8 +1053,7 @@ syncache_respond(sc, m)
} else {
optlen = TCPOLEN_MAXSEG +
((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) +
((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0) +
((sc->sc_flags & SCF_CC) ? TCPOLEN_CC_APPA * 2 : 0);
((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0);
#ifdef TCP_SIGNATURE
optlen += (sc->sc_flags & SCF_SIGNATURE) ?
TCPOLEN_SIGNATURE + 2 : 0;
@ -1240,19 +1165,6 @@ syncache_respond(sc, m)
optp += TCPOLEN_TSTAMP_APPA;
}
/*
* Send CC and CC.echo if we received CC from our peer.
*/
if (sc->sc_flags & SCF_CC) {
u_int32_t *lp = (u_int32_t *)(optp);
*lp++ = htonl(TCPOPT_CC_HDR(TCPOPT_CC));
*lp++ = htonl(sc->sc_cc_send);
*lp++ = htonl(TCPOPT_CC_HDR(TCPOPT_CCECHO));
*lp = htonl(sc->sc_cc_recv);
optp += TCPOLEN_CC_APPA * 2;
}
#ifdef TCP_SIGNATURE
/*
* Handle TCP-MD5 passive opener response.

View File

@ -541,14 +541,14 @@ tcp_timer_rexmt(xtp)
TCPT_RANGESET(tp->t_rxtcur, rexmt,
tp->t_rttmin, TCPTV_REXMTMAX);
/*
* Disable rfc1323 and rfc1644 if we havn't got any response to
* Disable rfc1323 if we havn't got any response to
* our third SYN to work-around some broken terminal servers
* (most of which have hopefully been retired) that have bad VJ
* header compression code which trashes TCP segments containing
* unknown-to-them TCP options.
*/
if ((tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3))
tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_REQ_CC);
tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP);
/*
* If we backed off this far, our srtt estimate is probably bogus.
* Clobber it so we'll take the next rtt measurement as our srtt;

View File

@ -155,10 +155,6 @@ int tcp_do_rfc1323 = 1;
SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW,
&tcp_do_rfc1323 , 0, "Enable rfc1323 (high performance TCP) extensions");
int tcp_do_rfc1644 = 0;
SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1644, rfc1644, CTLFLAG_RW,
&tcp_do_rfc1644 , 0, "Enable rfc1644 (TTCP) extensions");
static int tcp_tcbhashsize = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN,
&tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
@ -246,8 +242,6 @@ tcp_init()
{
int hashsize = TCBHASHSIZE;
tcp_ccgen = 1;
tcp_delacktime = TCPTV_DELACK;
tcp_keepinit = TCPTV_KEEP_INIT;
tcp_keepidle = TCPTV_KEEP_IDLE;
@ -613,8 +607,6 @@ tcp_newtcpcb(inp)
if (tcp_do_rfc1323)
tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP);
if (tcp_do_rfc1644)
tp->t_flags |= TF_REQ_CC;
tp->sack_enable = tcp_do_sack;
tp->t_inpcb = inp; /* XXX */
/*
@ -1409,7 +1401,6 @@ tcp_mtudisc(inp, errno)
int errno;
{
struct tcpcb *tp = intotcpcb(inp);
struct rmxp_tao tao;
struct socket *so = inp->inp_socket;
u_int maxmtu;
u_int romtu;
@ -1417,7 +1408,6 @@ tcp_mtudisc(inp, errno)
#ifdef INET6
int isipv6;
#endif /* INET6 */
bzero(&tao, sizeof(tao));
if (tp != NULL) {
#ifdef INET6
@ -1452,11 +1442,6 @@ tcp_mtudisc(inp, errno)
#endif /* INET6 */
;
if (tcp_do_rfc1644) {
tcp_hc_gettao(&inp->inp_inc, &tao);
if (tao.tao_mssopt)
mss = min(mss, tao.tao_mssopt);
}
/*
* XXX - The above conditional probably violates the TCP
* spec. The problem is that, since we don't know the
@ -1481,9 +1466,6 @@ tcp_mtudisc(inp, errno)
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
mss -= TCPOLEN_TSTAMP_APPA;
if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
(tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC)
mss -= TCPOLEN_CC_APPA;
#if (MCLBYTES & (MCLBYTES - 1)) == 0
if (mss > MCLBYTES)
mss &= ~(MCLBYTES-1);
@ -1659,8 +1641,6 @@ tcp_twstart(tp)
tw->rcv_nxt = tp->rcv_nxt;
tw->iss = tp->iss;
tw->irs = tp->irs;
tw->cc_recv = tp->cc_recv;
tw->cc_send = tp->cc_send;
tw->t_starttime = tp->t_starttime;
tw->tw_time = 0;
@ -1669,15 +1649,8 @@ tcp_twstart(tp)
* be used for fin-wait-2 state also, then we may need
* a ts_recent from the last segment.
*/
/* Shorten TIME_WAIT [RFC-1644, p.28] */
if (tp->cc_recv != 0 && (ticks - tp->t_starttime) < tcp_msl) {
tw_time = tp->t_rxtcur * TCPTV_TWTRUNC;
/* For T/TCP client, force ACK now. */
acknow = 1;
} else {
tw_time = 2 * tcp_msl;
acknow = tp->t_flags & TF_ACKNOW;
}
tw_time = 2 * tcp_msl;
acknow = tp->t_flags & TF_ACKNOW;
tcp_discardcb(tp);
so = inp->inp_socket;
ACCEPT_LOCK();
@ -1803,16 +1776,6 @@ tcp_twrespond(struct tcptw *tw, int flags)
optp += TCPOLEN_TSTAMP_APPA;
}
/*
* Send `CC-family' options if needed, and it's not a RST.
*/
if (tw->cc_recv != 0 && flags == TH_ACK) {
u_int32_t *lp = (u_int32_t *)optp;
*lp++ = htonl(TCPOPT_CC_HDR(TCPOPT_CC));
*lp = htonl(tw->cc_send);
optp += TCPOLEN_CC_APPA;
}
optlen = optp - (u_int8_t *)(th + 1);
m->m_len = hdrlen + optlen;

View File

@ -815,14 +815,10 @@ tcp_connect(tp, nam, td)
{
struct inpcb *inp = tp->t_inpcb, *oinp;
struct socket *so = inp->inp_socket;
struct tcptw *otw;
struct rmxp_tao tao;
struct in_addr laddr;
u_short lport;
int error;
bzero(&tao, sizeof(tao));
if (inp->inp_lport == 0) {
error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
if (error)
@ -840,17 +836,8 @@ tcp_connect(tp, nam, td)
&inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred);
if (error && oinp == NULL)
return error;
if (oinp) {
if (oinp != inp &&
(oinp->inp_vflag & INP_TIMEWAIT) &&
(ticks - (otw = intotw(oinp))->t_starttime) < tcp_msl &&
otw->cc_recv != 0) {
inp->inp_faddr = oinp->inp_faddr;
inp->inp_fport = oinp->inp_fport;
(void) tcp_twclose(otw, 0);
} else
return EADDRINUSE;
}
if (oinp)
return EADDRINUSE;
inp->inp_laddr = laddr;
in_pcbrehash(inp);
@ -867,26 +854,6 @@ tcp_connect(tp, nam, td)
tp->t_bw_rtseq = tp->iss;
tcp_sendseqinit(tp);
/*
* Generate a CC value for this connection and
* check whether CC or CCnew should be used.
*/
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
tp->cc_send = CC_INC(tcp_ccgen);
if (tao.tao_ccsent != 0 &&
CC_GEQ(tp->cc_send, tao.tao_ccsent)) {
tao.tao_ccsent = tp->cc_send;
} else {
tao.tao_ccsent = 0;
tp->t_flags |= TF_SENDCCNEW;
}
if (tcp_do_rfc1644)
tcp_hc_updatetao(&inp->inp_inc, TCP_HC_TAO_CCSENT,
tao.tao_ccsent, 0);
return 0;
}
@ -899,14 +866,10 @@ tcp6_connect(tp, nam, td)
{
struct inpcb *inp = tp->t_inpcb, *oinp;
struct socket *so = inp->inp_socket;
struct tcptw *otw;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
struct in6_addr *addr6;
struct rmxp_tao tao;
int error;
bzero(&tao, sizeof(tao));
if (inp->inp_lport == 0) {
error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
if (error)
@ -927,17 +890,8 @@ tcp6_connect(tp, nam, td)
? addr6
: &inp->in6p_laddr,
inp->inp_lport, 0, NULL);
if (oinp) {
if (oinp != inp &&
(oinp->inp_vflag & INP_TIMEWAIT) &&
(ticks - (otw = intotw(oinp))->t_starttime) < tcp_msl &&
otw->cc_recv != 0) {
inp->inp_faddr = oinp->inp_faddr;
inp->inp_fport = oinp->inp_fport;
(void) tcp_twclose(otw, 0);
} else
return EADDRINUSE;
}
if (oinp)
return EADDRINUSE;
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
inp->in6p_laddr = *addr6;
inp->in6p_faddr = sin6->sin6_addr;
@ -962,25 +916,6 @@ tcp6_connect(tp, nam, td)
tp->t_bw_rtseq = tp->iss;
tcp_sendseqinit(tp);
/*
* Generate a CC value for this connection and
* check whether CC or CCnew should be used.
*/
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
tp->cc_send = CC_INC(tcp_ccgen);
if (tao.tao_ccsent != 0 &&
CC_GEQ(tp->cc_send, tao.tao_ccsent)) {
tao.tao_ccsent = tp->cc_send;
} else {
tao.tao_ccsent = 0;
tp->t_flags |= TF_SENDCCNEW;
}
if (tcp_do_rfc1644)
tcp_hc_updatetao(&inp->inp_inc, TCP_HC_TAO_CCSENT,
tao.tao_ccsent, 0);
return 0;
}
#endif /* INET6 */

View File

@ -39,7 +39,6 @@
* Kernel variables for tcp.
*/
extern int tcp_do_rfc1323;
extern int tcp_do_rfc1644;
/* TCP segment queue entry */
struct tseg_qent {
@ -102,9 +101,6 @@ struct tcpcb {
#define TF_NEEDSYN 0x000400 /* send SYN (implicit state) */
#define TF_NEEDFIN 0x000800 /* send FIN (implicit state) */
#define TF_NOPUSH 0x001000 /* don't push */
#define TF_REQ_CC 0x002000 /* have/will request CC */
#define TF_RCVD_CC 0x004000 /* a CC was received in SYN */
#define TF_SENDCCNEW 0x008000 /* send CCnew instead of CC in SYN */
#define TF_MORETOCOME 0x010000 /* More data to be appended to sock */
#define TF_LQ_OVERFLOW 0x020000 /* listen queue overflow */
#define TF_LASTIDLE 0x040000 /* connection was previously idle */
@ -177,9 +173,6 @@ struct tcpcb {
u_long ts_recent_age; /* when last updated */
tcp_seq last_ack_sent;
/* RFC 1644 variables */
tcp_cc cc_send; /* send connection count */
tcp_cc cc_recv; /* receive connection count */
/* experimental */
u_long snd_cwnd_prev; /* cwnd prior to retransmit */
u_long snd_ssthresh_prev; /* ssthresh prior to retransmit */
@ -231,9 +224,6 @@ struct tcpcb {
struct tcpopt {
u_long to_flags; /* which options are present */
#define TOF_TS 0x0001 /* timestamp */
#define TOF_CC 0x0002 /* CC and CCnew are exclusive */
#define TOF_CCNEW 0x0004
#define TOF_CCECHO 0x0008
#define TOF_MSS 0x0010
#define TOF_SCALE 0x0020
#define TOF_SIGNATURE 0x0040 /* signature option present */
@ -241,8 +231,6 @@ struct tcpopt {
#define TOF_SACK 0x0100 /* Peer sent SACK option */
u_int32_t to_tsval;
u_int32_t to_tsecr;
tcp_cc to_cc; /* holds CC or CCnew */
tcp_cc to_ccecho;
u_int16_t to_mss;
u_int8_t to_requested_s_scale;
u_int8_t to_pad;
@ -256,8 +244,6 @@ struct syncache {
struct in_conninfo sc_inc; /* addresses */
u_int32_t sc_tsrecent;
u_int32_t sc_flowlabel; /* IPv6 flowlabel */
tcp_cc sc_cc_send; /* holds CC or CCnew */
tcp_cc sc_cc_recv;
tcp_seq sc_irs; /* seq from peer */
tcp_seq sc_iss; /* our ISS */
u_long sc_rxttime; /* retransmit time */
@ -270,7 +256,6 @@ struct syncache {
#define SCF_NOOPT 0x01 /* no TCP options */
#define SCF_WINSCALE 0x02 /* negotiated window scaling */
#define SCF_TIMESTAMP 0x04 /* negotiated timestamps */
#define SCF_CC 0x08 /* negotiated CC */
#define SCF_UNREACH 0x10 /* icmp unreachable received */
#define SCF_SIGNATURE 0x20 /* send MD5 digests */
#define SCF_SACK 0x80 /* send SACK option */
@ -303,8 +288,6 @@ struct tcptw {
tcp_seq rcv_nxt;
tcp_seq iss;
tcp_seq irs;
tcp_cc cc_recv;
tcp_cc cc_send;
u_short last_win; /* cached window value */
u_short tw_so_options; /* copy of so_options */
struct ucred *tw_cred; /* user credentials */
@ -314,21 +297,6 @@ struct tcptw {
LIST_ENTRY(tcptw) tw_2msl;
};
/*
* The TAO cache entry which is stored in the tcp hostcache.
*/
struct rmxp_tao {
tcp_cc tao_cc; /* latest CC in valid SYN */
tcp_cc tao_ccsent; /* latest CC sent to peer */
u_short tao_mssopt; /* peer's cached MSS */
#ifdef notyet
u_short tao_flags; /* cache status flags */
#define TAOF_DONT 0x0001 /* peer doesn't understand rfc1644 */
#define TAOF_OK 0x0002 /* peer does understand rfc1644 */
#define TAOF_UNDEF 0 /* we don't know yet */
#endif /* notyet */
};
#define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
#define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb)
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
@ -487,7 +455,6 @@ struct xtcpcb {
* Names for TCP sysctl objects
*/
#define TCPCTL_DO_RFC1323 1 /* use RFC-1323 extensions */
#define TCPCTL_DO_RFC1644 2 /* use RFC-1644 extensions */
#define TCPCTL_MSSDFLT 3 /* MSS default */
#define TCPCTL_STATS 4 /* statistics (read-only) */
#define TCPCTL_RTTDFLT 5 /* default RTT estimate */
@ -505,7 +472,6 @@ struct xtcpcb {
#define TCPCTL_NAMES { \
{ 0, 0 }, \
{ "rfc1323", CTLTYPE_INT }, \
{ "rfc1644", CTLTYPE_INT }, \
{ "mssdflt", CTLTYPE_INT }, \
{ "stats", CTLTYPE_STRUCT }, \
{ "rttdflt", CTLTYPE_INT }, \
@ -600,14 +566,8 @@ void syncache_badack(struct in_conninfo *);
void tcp_hc_init(void);
void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
u_long tcp_hc_getmtu(struct in_conninfo *);
void tcp_hc_gettao(struct in_conninfo *, struct rmxp_tao *);
void tcp_hc_updatemtu(struct in_conninfo *, u_long);
void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *);
void tcp_hc_updatetao(struct in_conninfo *, int, tcp_cc, u_short);
/* update which tao field */
#define TCP_HC_TAO_CC 0x1
#define TCP_HC_TAO_CCSENT 0x2
#define TCP_HC_TAO_MSSOPT 0x3
extern struct pr_usrreqs tcp_usrreqs;
extern u_long tcp_sendspace;