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 developers choose to disable these features on build machines
to maximize performance. 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: 20041022:
The size of struct tcpcb has changed. You have to recompile The size of struct tcpcb has changed. You have to recompile
userland programs that read kmem for tcp sockets directly userland programs that read kmem for tcp sockets directly

View File

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

View File

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

View File

@ -38,7 +38,6 @@
#if __BSD_VISIBLE #if __BSD_VISIBLE
typedef u_int32_t tcp_seq; 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 tcp6_seq tcp_seq /* for KAME src sync over BSD*'s */
#define tcp6hdr tcphdr /* 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 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 TCPOPT_SIGNATURE 19 /* Keyed MD5: RFC 2385 */
#define TCPOLEN_SIGNATURE 18 #define TCPOLEN_SIGNATURE 18

View File

@ -121,7 +121,6 @@ struct hc_metrics {
u_long rmx_cwnd; /* congestion window */ u_long rmx_cwnd; /* congestion window */
u_long rmx_sendpipe; /* outbound delay-bandwidth product */ u_long rmx_sendpipe; /* outbound delay-bandwidth product */
u_long rmx_recvpipe; /* inbound 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 */ /* tcp hostcache internal data */
int rmx_expire; /* lifetime for object */ int rmx_expire; /* lifetime for object */
u_long rmx_hits; /* number of hits */ u_long rmx_hits; /* number of hits */
@ -456,28 +455,6 @@ tcp_hc_getmtu(struct in_conninfo *inc)
return mtu; 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. * External function: update the mtu value of an entry in the hostcache.
* Creates a new entry if none was found. * 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); 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 * Sysctl function: prints the list and values of all hostcache entries in
* unsorted order. * unsorted order.

View File

@ -98,7 +98,6 @@
#include <machine/in_cksum.h> #include <machine/in_cksum.h>
static const int tcprexmtthresh = 3; static const int tcprexmtthresh = 3;
tcp_cc tcp_ccgen;
struct tcpstat tcpstat; struct tcpstat tcpstat;
SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW, SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
@ -433,7 +432,6 @@ tcp_input(m, off0)
int todrop, acked, ourfinisacked, needoutput = 0; int todrop, acked, ourfinisacked, needoutput = 0;
u_long tiwin; u_long tiwin;
struct tcpopt to; /* options in this segment */ struct tcpopt to; /* options in this segment */
struct rmxp_tao tao; /* our TAO cache entry */
int headlocked = 0; int headlocked = 0;
#ifdef IPFIREWALL_FORWARD #ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag; struct m_tag *fwd_tag;
@ -460,7 +458,6 @@ tcp_input(m, off0)
#ifdef INET6 #ifdef INET6
isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0;
#endif #endif
bzero(&tao, sizeof(tao));
bzero((char *)&to, sizeof(to)); bzero((char *)&to, sizeof(to));
tcpstat.tcps_rcvtotal++; tcpstat.tcps_rcvtotal++;
@ -1090,8 +1087,6 @@ tcp_input(m, off0)
tp->ts_recent = to.to_tsval; tp->ts_recent = to.to_tsval;
tp->ts_recent_age = ticks; 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) if (to.to_flags & TOF_MSS)
tcp_mss(tp, to.to_mss); tcp_mss(tp, to.to_mss);
if (tp->sack_enable) { if (tp->sack_enable) {
@ -1132,16 +1127,8 @@ tcp_input(m, off0)
((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) &&
((to.to_flags & TOF_TS) == 0 || ((to.to_flags & TOF_TS) == 0 ||
TSTMP_GEQ(to.to_tsval, tp->ts_recent)) && TSTMP_GEQ(to.to_tsval, tp->ts_recent)) &&
/* th->th_seq == tp->rcv_nxt && tiwin && tiwin == tp->snd_wnd &&
* Using the CC option is compulsory if once started: tp->snd_nxt == tp->snd_max) {
* 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) {
/* /*
* If last ACK falls within this segment's sequence numbers, * 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 * continue processing rest of data/controls, beginning with URG
*/ */
case TCPS_SYN_SENT: case TCPS_SYN_SENT:
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if ((thflags & TH_ACK) && if ((thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) || (SEQ_LEQ(th->th_ack, tp->iss) ||
SEQ_GT(th->th_ack, tp->snd_max))) { SEQ_GT(th->th_ack, tp->snd_max))) {
/* rstreason = BANDLIM_UNLIMITED;
* If we have a cached CCsent for the remote host, goto dropwithreset;
* 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;
}
} }
if (thflags & TH_RST) { if (thflags & TH_RST) {
if (thflags & TH_ACK) if (thflags & TH_ACK)
@ -1374,30 +1346,10 @@ tcp_input(m, off0)
if ((thflags & TH_SYN) == 0) if ((thflags & TH_SYN) == 0)
goto drop; goto drop;
tp->snd_wnd = th->th_win; /* initial send window */ tp->snd_wnd = th->th_win; /* initial send window */
tp->cc_recv = to.to_cc; /* foreign CC */
tp->irs = th->th_seq; tp->irs = th->th_seq;
tcp_rcvseqinit(tp); tcp_rcvseqinit(tp);
if (thflags & TH_ACK) { 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++; tcpstat.tcps_connects++;
soisconnected(so); soisconnected(so);
#ifdef MAC #ifdef MAC
@ -1411,10 +1363,6 @@ tcp_input(m, off0)
tp->snd_scale = tp->requested_s_scale; tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_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->rcv_adv += tp->rcv_wnd;
tp->snd_una++; /* SYN is acked */ tp->snd_una++; /* SYN is acked */
/* /*
@ -1455,40 +1403,7 @@ tcp_input(m, off0)
*/ */
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
callout_stop(tp->tt_rexmt); callout_stop(tp->tt_rexmt);
if (to.to_flags & TOF_CC) { tp->t_state = TCPS_SYN_RECEIVED;
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;
}
} }
trimthenstep6: trimthenstep6:
@ -1526,36 +1441,14 @@ tcp_input(m, off0)
/* /*
* If the state is LAST_ACK or CLOSING or TIME_WAIT: * If the state is LAST_ACK or CLOSING or TIME_WAIT:
* if segment contains a SYN and CC [not CC.NEW] option: * do normal processing.
* if state == TIME_WAIT and connection duration > MSL,
* drop packet and send RST;
* *
* if SEG.CC > CCrecv then is new SYN, and can implicitly * NB: Leftover from RFC1644 T/TCP. Cases to be reused later.
* 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.
*/ */
case TCPS_LAST_ACK: case TCPS_LAST_ACK:
case TCPS_CLOSING: case TCPS_CLOSING:
case TCPS_TIME_WAIT: case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("timewait")); 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 */ 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 * In the SYN-RECEIVED state, validate that the packet belongs to
* this connection before trimming the data to fit the receive * 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->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_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: * Make transitions:
* SYN-RECEIVED -> ESTABLISHED * SYN-RECEIVED -> ESTABLISHED
@ -2682,34 +2555,6 @@ tcp_dooptions(tp, to, cp, cnt, is_syn, th)
(char *)&to->to_tsecr, sizeof(to->to_tsecr)); (char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr); to->to_tsecr = ntohl(to->to_tsecr);
break; 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 #ifdef TCP_SIGNATURE
/* /*
* XXX In order to reply to a host which has set the * 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 inpcb *inp = tp->t_inpcb;
struct socket *so; struct socket *so;
struct hc_metrics_lite metrics; struct hc_metrics_lite metrics;
struct rmxp_tao tao;
int origoffer = offer; int origoffer = offer;
#ifdef INET6 #ifdef INET6
int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0;
@ -2910,7 +2754,6 @@ tcp_mss(tp, offer)
#else #else
const size_t min_protoh = sizeof(struct tcpiphdr); const size_t min_protoh = sizeof(struct tcpiphdr);
#endif #endif
bzero(&tao, sizeof(tao));
/* initialize */ /* initialize */
#ifdef INET6 #ifdef INET6
@ -2947,13 +2790,8 @@ tcp_mss(tp, offer)
case -1: case -1:
/* /*
* Offer == -1 means that we didn't receive SYN yet, * Offer == -1 means that we didn't receive SYN yet.
* use cached value in that case;
*/ */
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if (tao.tao_mssopt != 0)
offer = tao.tao_mssopt;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
@ -2969,9 +2807,6 @@ tcp_mss(tp, offer)
* funny things may happen in tcp_output. * funny things may happen in tcp_output.
*/ */
offer = max(offer, 64); 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; tp->t_maxopd = mss;
/* /*
* In case of T/TCP, origoffer==-1 indicates, that no segments * origoffer==-1 indicates, that no segments were received yet.
* were received yet. In this case we just guess, otherwise * In this case we just guess.
* we do the same as before T/TCP.
*/ */
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(origoffer == -1 || (origoffer == -1 ||
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)) (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
mss -= TCPOLEN_TSTAMP_APPA; 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; tp->t_maxseg = mss;
#if (MCLBYTES & (MCLBYTES - 1)) == 0 #if (MCLBYTES & (MCLBYTES - 1)) == 0
@ -3251,27 +3081,6 @@ tcp_timewait(tw, to, th, m, tlen)
if (thflags & TH_RST) if (thflags & TH_RST)
goto drop; 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 #if 0
/* PAWS not needed at the moment */ /* PAWS not needed at the moment */
/* /*
@ -3323,7 +3132,6 @@ tcp_timewait(tw, to, th, m, tlen)
tcp_twrespond(tw, TH_ACK); tcp_twrespond(tw, TH_ACK);
goto drop; goto drop;
reset:
/* /*
* Generate a RST, dropping incoming segment. * Generate a RST, dropping incoming segment.
* Make ACK acceptable to originator of segment. * Make ACK acceptable to originator of segment.

View File

@ -129,12 +129,10 @@ tcp_output(struct tcpcb *tp)
#if 0 #if 0
int maxburst = TCP_MAXBURST; int maxburst = TCP_MAXBURST;
#endif #endif
struct rmxp_tao tao;
#ifdef INET6 #ifdef INET6
struct ip6_hdr *ip6 = NULL; struct ip6_hdr *ip6 = NULL;
int isipv6; int isipv6;
bzero(&tao, sizeof(tao));
isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0; isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0;
#endif #endif
@ -329,22 +327,14 @@ tcp_output(struct tcpcb *tp)
if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) { if ((flags & TH_SYN) && SEQ_GT(tp->snd_nxt, tp->snd_una)) {
flags &= ~TH_SYN; flags &= ~TH_SYN;
off--, len++; 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 * Be careful not to send data and/or FIN on SYN segments.
* in cases when no CC option will be sent.
* This measure is needed to prevent interoperability problems * This measure is needed to prevent interoperability problems
* with not fully conformant TCP implementations. * with not fully conformant TCP implementations.
*/ */
if ((flags & TH_SYN) && if ((flags & TH_SYN) && (tp->t_flags & TF_NOOPT)) {
((tp->t_flags & TF_NOOPT) || !(tp->t_flags & TF_REQ_CC) ||
((flags & TH_ACK) && !(tp->t_flags & TF_RCVD_CC)))) {
len = 0; len = 0;
flags &= ~TH_FIN; flags &= ~TH_FIN;
} }
@ -613,76 +603,6 @@ tcp_output(struct tcpcb *tp)
*olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2)); *olp = htonl(TCPOPT_SACK_HDR|(TCPOLEN_SACK*count+2));
optlen += TCPOLEN_SACK*count + 4; /* including leading NOPs */ 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 TCP_SIGNATURE
#ifdef INET6 #ifdef INET6

View File

@ -98,7 +98,6 @@
#include <machine/in_cksum.h> #include <machine/in_cksum.h>
static const int tcprexmtthresh = 3; static const int tcprexmtthresh = 3;
tcp_cc tcp_ccgen;
struct tcpstat tcpstat; struct tcpstat tcpstat;
SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW, SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
@ -433,7 +432,6 @@ tcp_input(m, off0)
int todrop, acked, ourfinisacked, needoutput = 0; int todrop, acked, ourfinisacked, needoutput = 0;
u_long tiwin; u_long tiwin;
struct tcpopt to; /* options in this segment */ struct tcpopt to; /* options in this segment */
struct rmxp_tao tao; /* our TAO cache entry */
int headlocked = 0; int headlocked = 0;
#ifdef IPFIREWALL_FORWARD #ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag; struct m_tag *fwd_tag;
@ -460,7 +458,6 @@ tcp_input(m, off0)
#ifdef INET6 #ifdef INET6
isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0;
#endif #endif
bzero(&tao, sizeof(tao));
bzero((char *)&to, sizeof(to)); bzero((char *)&to, sizeof(to));
tcpstat.tcps_rcvtotal++; tcpstat.tcps_rcvtotal++;
@ -1090,8 +1087,6 @@ tcp_input(m, off0)
tp->ts_recent = to.to_tsval; tp->ts_recent = to.to_tsval;
tp->ts_recent_age = ticks; 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) if (to.to_flags & TOF_MSS)
tcp_mss(tp, to.to_mss); tcp_mss(tp, to.to_mss);
if (tp->sack_enable) { if (tp->sack_enable) {
@ -1132,16 +1127,8 @@ tcp_input(m, off0)
((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) && ((tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) == 0) &&
((to.to_flags & TOF_TS) == 0 || ((to.to_flags & TOF_TS) == 0 ||
TSTMP_GEQ(to.to_tsval, tp->ts_recent)) && TSTMP_GEQ(to.to_tsval, tp->ts_recent)) &&
/* th->th_seq == tp->rcv_nxt && tiwin && tiwin == tp->snd_wnd &&
* Using the CC option is compulsory if once started: tp->snd_nxt == tp->snd_max) {
* 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) {
/* /*
* If last ACK falls within this segment's sequence numbers, * 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 * continue processing rest of data/controls, beginning with URG
*/ */
case TCPS_SYN_SENT: case TCPS_SYN_SENT:
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if ((thflags & TH_ACK) && if ((thflags & TH_ACK) &&
(SEQ_LEQ(th->th_ack, tp->iss) || (SEQ_LEQ(th->th_ack, tp->iss) ||
SEQ_GT(th->th_ack, tp->snd_max))) { SEQ_GT(th->th_ack, tp->snd_max))) {
/* rstreason = BANDLIM_UNLIMITED;
* If we have a cached CCsent for the remote host, goto dropwithreset;
* 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;
}
} }
if (thflags & TH_RST) { if (thflags & TH_RST) {
if (thflags & TH_ACK) if (thflags & TH_ACK)
@ -1374,30 +1346,10 @@ tcp_input(m, off0)
if ((thflags & TH_SYN) == 0) if ((thflags & TH_SYN) == 0)
goto drop; goto drop;
tp->snd_wnd = th->th_win; /* initial send window */ tp->snd_wnd = th->th_win; /* initial send window */
tp->cc_recv = to.to_cc; /* foreign CC */
tp->irs = th->th_seq; tp->irs = th->th_seq;
tcp_rcvseqinit(tp); tcp_rcvseqinit(tp);
if (thflags & TH_ACK) { 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++; tcpstat.tcps_connects++;
soisconnected(so); soisconnected(so);
#ifdef MAC #ifdef MAC
@ -1411,10 +1363,6 @@ tcp_input(m, off0)
tp->snd_scale = tp->requested_s_scale; tp->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_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->rcv_adv += tp->rcv_wnd;
tp->snd_una++; /* SYN is acked */ tp->snd_una++; /* SYN is acked */
/* /*
@ -1455,40 +1403,7 @@ tcp_input(m, off0)
*/ */
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
callout_stop(tp->tt_rexmt); callout_stop(tp->tt_rexmt);
if (to.to_flags & TOF_CC) { tp->t_state = TCPS_SYN_RECEIVED;
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;
}
} }
trimthenstep6: trimthenstep6:
@ -1526,36 +1441,14 @@ tcp_input(m, off0)
/* /*
* If the state is LAST_ACK or CLOSING or TIME_WAIT: * If the state is LAST_ACK or CLOSING or TIME_WAIT:
* if segment contains a SYN and CC [not CC.NEW] option: * do normal processing.
* if state == TIME_WAIT and connection duration > MSL,
* drop packet and send RST;
* *
* if SEG.CC > CCrecv then is new SYN, and can implicitly * NB: Leftover from RFC1644 T/TCP. Cases to be reused later.
* 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.
*/ */
case TCPS_LAST_ACK: case TCPS_LAST_ACK:
case TCPS_CLOSING: case TCPS_CLOSING:
case TCPS_TIME_WAIT: case TCPS_TIME_WAIT:
KASSERT(tp->t_state != TCPS_TIME_WAIT, ("timewait")); 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 */ 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 * In the SYN-RECEIVED state, validate that the packet belongs to
* this connection before trimming the data to fit the receive * 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->snd_scale = tp->requested_s_scale;
tp->rcv_scale = tp->request_r_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: * Make transitions:
* SYN-RECEIVED -> ESTABLISHED * SYN-RECEIVED -> ESTABLISHED
@ -2682,34 +2555,6 @@ tcp_dooptions(tp, to, cp, cnt, is_syn, th)
(char *)&to->to_tsecr, sizeof(to->to_tsecr)); (char *)&to->to_tsecr, sizeof(to->to_tsecr));
to->to_tsecr = ntohl(to->to_tsecr); to->to_tsecr = ntohl(to->to_tsecr);
break; 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 #ifdef TCP_SIGNATURE
/* /*
* XXX In order to reply to a host which has set the * 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 inpcb *inp = tp->t_inpcb;
struct socket *so; struct socket *so;
struct hc_metrics_lite metrics; struct hc_metrics_lite metrics;
struct rmxp_tao tao;
int origoffer = offer; int origoffer = offer;
#ifdef INET6 #ifdef INET6
int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0;
@ -2910,7 +2754,6 @@ tcp_mss(tp, offer)
#else #else
const size_t min_protoh = sizeof(struct tcpiphdr); const size_t min_protoh = sizeof(struct tcpiphdr);
#endif #endif
bzero(&tao, sizeof(tao));
/* initialize */ /* initialize */
#ifdef INET6 #ifdef INET6
@ -2947,13 +2790,8 @@ tcp_mss(tp, offer)
case -1: case -1:
/* /*
* Offer == -1 means that we didn't receive SYN yet, * Offer == -1 means that we didn't receive SYN yet.
* use cached value in that case;
*/ */
if (tcp_do_rfc1644)
tcp_hc_gettao(&inp->inp_inc, &tao);
if (tao.tao_mssopt != 0)
offer = tao.tao_mssopt;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
@ -2969,9 +2807,6 @@ tcp_mss(tp, offer)
* funny things may happen in tcp_output. * funny things may happen in tcp_output.
*/ */
offer = max(offer, 64); 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; tp->t_maxopd = mss;
/* /*
* In case of T/TCP, origoffer==-1 indicates, that no segments * origoffer==-1 indicates, that no segments were received yet.
* were received yet. In this case we just guess, otherwise * In this case we just guess.
* we do the same as before T/TCP.
*/ */
if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(origoffer == -1 || (origoffer == -1 ||
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)) (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
mss -= TCPOLEN_TSTAMP_APPA; 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; tp->t_maxseg = mss;
#if (MCLBYTES & (MCLBYTES - 1)) == 0 #if (MCLBYTES & (MCLBYTES - 1)) == 0
@ -3251,27 +3081,6 @@ tcp_timewait(tw, to, th, m, tlen)
if (thflags & TH_RST) if (thflags & TH_RST)
goto drop; 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 #if 0
/* PAWS not needed at the moment */ /* PAWS not needed at the moment */
/* /*
@ -3323,7 +3132,6 @@ tcp_timewait(tw, to, th, m, tlen)
tcp_twrespond(tw, TH_ACK); tcp_twrespond(tw, TH_ACK);
goto drop; goto drop;
reset:
/* /*
* Generate a RST, dropping incoming segment. * Generate a RST, dropping incoming segment.
* Make ACK acceptable to originator of segment. * Make ACK acceptable to originator of segment.

View File

@ -77,7 +77,4 @@
#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * hz) #define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * hz)
/* timestamp wrap-around time */ /* timestamp wrap-around time */
#ifdef _KERNEL
extern tcp_cc tcp_ccgen; /* global connection count */
#endif /* _KERNEL */
#endif /* _NETINET_TCP_SEQ_H_ */ #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, SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW,
&tcp_do_rfc1323 , 0, "Enable rfc1323 (high performance TCP) extensions"); &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; static int tcp_tcbhashsize = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN, SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN,
&tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
@ -246,8 +242,6 @@ tcp_init()
{ {
int hashsize = TCBHASHSIZE; int hashsize = TCBHASHSIZE;
tcp_ccgen = 1;
tcp_delacktime = TCPTV_DELACK; tcp_delacktime = TCPTV_DELACK;
tcp_keepinit = TCPTV_KEEP_INIT; tcp_keepinit = TCPTV_KEEP_INIT;
tcp_keepidle = TCPTV_KEEP_IDLE; tcp_keepidle = TCPTV_KEEP_IDLE;
@ -613,8 +607,6 @@ tcp_newtcpcb(inp)
if (tcp_do_rfc1323) if (tcp_do_rfc1323)
tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP); 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->sack_enable = tcp_do_sack;
tp->t_inpcb = inp; /* XXX */ tp->t_inpcb = inp; /* XXX */
/* /*
@ -1409,7 +1401,6 @@ tcp_mtudisc(inp, errno)
int errno; int errno;
{ {
struct tcpcb *tp = intotcpcb(inp); struct tcpcb *tp = intotcpcb(inp);
struct rmxp_tao tao;
struct socket *so = inp->inp_socket; struct socket *so = inp->inp_socket;
u_int maxmtu; u_int maxmtu;
u_int romtu; u_int romtu;
@ -1417,7 +1408,6 @@ tcp_mtudisc(inp, errno)
#ifdef INET6 #ifdef INET6
int isipv6; int isipv6;
#endif /* INET6 */ #endif /* INET6 */
bzero(&tao, sizeof(tao));
if (tp != NULL) { if (tp != NULL) {
#ifdef INET6 #ifdef INET6
@ -1452,11 +1442,6 @@ tcp_mtudisc(inp, errno)
#endif /* INET6 */ #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 * XXX - The above conditional probably violates the TCP
* spec. The problem is that, since we don't know the * 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 && if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP) (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
mss -= TCPOLEN_TSTAMP_APPA; 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 (MCLBYTES & (MCLBYTES - 1)) == 0
if (mss > MCLBYTES) if (mss > MCLBYTES)
mss &= ~(MCLBYTES-1); mss &= ~(MCLBYTES-1);
@ -1659,8 +1641,6 @@ tcp_twstart(tp)
tw->rcv_nxt = tp->rcv_nxt; tw->rcv_nxt = tp->rcv_nxt;
tw->iss = tp->iss; tw->iss = tp->iss;
tw->irs = tp->irs; tw->irs = tp->irs;
tw->cc_recv = tp->cc_recv;
tw->cc_send = tp->cc_send;
tw->t_starttime = tp->t_starttime; tw->t_starttime = tp->t_starttime;
tw->tw_time = 0; tw->tw_time = 0;
@ -1669,15 +1649,8 @@ tcp_twstart(tp)
* be used for fin-wait-2 state also, then we may need * be used for fin-wait-2 state also, then we may need
* a ts_recent from the last segment. * a ts_recent from the last segment.
*/ */
/* Shorten TIME_WAIT [RFC-1644, p.28] */ tw_time = 2 * tcp_msl;
if (tp->cc_recv != 0 && (ticks - tp->t_starttime) < tcp_msl) { acknow = tp->t_flags & TF_ACKNOW;
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;
}
tcp_discardcb(tp); tcp_discardcb(tp);
so = inp->inp_socket; so = inp->inp_socket;
ACCEPT_LOCK(); ACCEPT_LOCK();
@ -1803,16 +1776,6 @@ tcp_twrespond(struct tcptw *tw, int flags)
optp += TCPOLEN_TSTAMP_APPA; 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); optlen = optp - (u_int8_t *)(th + 1);
m->m_len = hdrlen + optlen; 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 = sc->sc_tsrecent;
tp->ts_recent_age = ticks; 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 #ifdef TCP_SIGNATURE
if (sc->sc_flags & SCF_SIGNATURE) if (sc->sc_flags & SCF_SIGNATURE)
tp->t_flags |= TF_SIGNATURE; tp->t_flags |= TF_SIGNATURE;
@ -831,7 +821,6 @@ syncache_add(inc, to, th, sop, m)
struct syncache *sc = NULL; struct syncache *sc = NULL;
struct syncache_head *sch; struct syncache_head *sch;
struct mbuf *ipopts = NULL; struct mbuf *ipopts = NULL;
struct rmxp_tao tao;
u_int32_t flowtmp; u_int32_t flowtmp;
int i, win; int i, win;
@ -839,7 +828,6 @@ syncache_add(inc, to, th, sop, m)
so = *sop; so = *sop;
tp = sototcpcb(so); tp = sototcpcb(so);
bzero(&tao, sizeof(tao));
/* /*
* Remember the IP options, if any. * Remember the IP options, if any.
@ -989,17 +977,6 @@ syncache_add(inc, to, th, sop, m)
sc->sc_flags |= SCF_WINSCALE; 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) if (tp->t_flags & TF_NOOPT)
sc->sc_flags = SCF_NOOPT; sc->sc_flags = SCF_NOOPT;
#ifdef TCP_SIGNATURE #ifdef TCP_SIGNATURE
@ -1018,58 +995,7 @@ syncache_add(inc, to, th, sop, m)
sc->sc_flags |= SCF_SACK; sc->sc_flags |= SCF_SACK;
/* /*
* XXX * Do a standard 3-way handshake.
* 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.
*/ */
#ifdef TCPDEBUG #ifdef TCPDEBUG
if (syncache_respond(sc, m, so) == 0) { if (syncache_respond(sc, m, so) == 0) {
@ -1127,8 +1053,7 @@ syncache_respond(sc, m)
} else { } else {
optlen = TCPOLEN_MAXSEG + optlen = TCPOLEN_MAXSEG +
((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) + ((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) +
((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0) + ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0);
((sc->sc_flags & SCF_CC) ? TCPOLEN_CC_APPA * 2 : 0);
#ifdef TCP_SIGNATURE #ifdef TCP_SIGNATURE
optlen += (sc->sc_flags & SCF_SIGNATURE) ? optlen += (sc->sc_flags & SCF_SIGNATURE) ?
TCPOLEN_SIGNATURE + 2 : 0; TCPOLEN_SIGNATURE + 2 : 0;
@ -1240,19 +1165,6 @@ syncache_respond(sc, m)
optp += TCPOLEN_TSTAMP_APPA; 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 #ifdef TCP_SIGNATURE
/* /*
* Handle TCP-MD5 passive opener response. * Handle TCP-MD5 passive opener response.

View File

@ -541,14 +541,14 @@ tcp_timer_rexmt(xtp)
TCPT_RANGESET(tp->t_rxtcur, rexmt, TCPT_RANGESET(tp->t_rxtcur, rexmt,
tp->t_rttmin, TCPTV_REXMTMAX); 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 * our third SYN to work-around some broken terminal servers
* (most of which have hopefully been retired) that have bad VJ * (most of which have hopefully been retired) that have bad VJ
* header compression code which trashes TCP segments containing * header compression code which trashes TCP segments containing
* unknown-to-them TCP options. * unknown-to-them TCP options.
*/ */
if ((tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3)) 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. * 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; * 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, SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_RW,
&tcp_do_rfc1323 , 0, "Enable rfc1323 (high performance TCP) extensions"); &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; static int tcp_tcbhashsize = 0;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN, SYSCTL_INT(_net_inet_tcp, OID_AUTO, tcbhashsize, CTLFLAG_RDTUN,
&tcp_tcbhashsize, 0, "Size of TCP control-block hashtable"); &tcp_tcbhashsize, 0, "Size of TCP control-block hashtable");
@ -246,8 +242,6 @@ tcp_init()
{ {
int hashsize = TCBHASHSIZE; int hashsize = TCBHASHSIZE;
tcp_ccgen = 1;
tcp_delacktime = TCPTV_DELACK; tcp_delacktime = TCPTV_DELACK;
tcp_keepinit = TCPTV_KEEP_INIT; tcp_keepinit = TCPTV_KEEP_INIT;
tcp_keepidle = TCPTV_KEEP_IDLE; tcp_keepidle = TCPTV_KEEP_IDLE;
@ -613,8 +607,6 @@ tcp_newtcpcb(inp)
if (tcp_do_rfc1323) if (tcp_do_rfc1323)
tp->t_flags = (TF_REQ_SCALE|TF_REQ_TSTMP); 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->sack_enable = tcp_do_sack;
tp->t_inpcb = inp; /* XXX */ tp->t_inpcb = inp; /* XXX */
/* /*
@ -1409,7 +1401,6 @@ tcp_mtudisc(inp, errno)
int errno; int errno;
{ {
struct tcpcb *tp = intotcpcb(inp); struct tcpcb *tp = intotcpcb(inp);
struct rmxp_tao tao;
struct socket *so = inp->inp_socket; struct socket *so = inp->inp_socket;
u_int maxmtu; u_int maxmtu;
u_int romtu; u_int romtu;
@ -1417,7 +1408,6 @@ tcp_mtudisc(inp, errno)
#ifdef INET6 #ifdef INET6
int isipv6; int isipv6;
#endif /* INET6 */ #endif /* INET6 */
bzero(&tao, sizeof(tao));
if (tp != NULL) { if (tp != NULL) {
#ifdef INET6 #ifdef INET6
@ -1452,11 +1442,6 @@ tcp_mtudisc(inp, errno)
#endif /* INET6 */ #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 * XXX - The above conditional probably violates the TCP
* spec. The problem is that, since we don't know the * 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 && if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
(tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP) (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
mss -= TCPOLEN_TSTAMP_APPA; 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 (MCLBYTES & (MCLBYTES - 1)) == 0
if (mss > MCLBYTES) if (mss > MCLBYTES)
mss &= ~(MCLBYTES-1); mss &= ~(MCLBYTES-1);
@ -1659,8 +1641,6 @@ tcp_twstart(tp)
tw->rcv_nxt = tp->rcv_nxt; tw->rcv_nxt = tp->rcv_nxt;
tw->iss = tp->iss; tw->iss = tp->iss;
tw->irs = tp->irs; tw->irs = tp->irs;
tw->cc_recv = tp->cc_recv;
tw->cc_send = tp->cc_send;
tw->t_starttime = tp->t_starttime; tw->t_starttime = tp->t_starttime;
tw->tw_time = 0; tw->tw_time = 0;
@ -1669,15 +1649,8 @@ tcp_twstart(tp)
* be used for fin-wait-2 state also, then we may need * be used for fin-wait-2 state also, then we may need
* a ts_recent from the last segment. * a ts_recent from the last segment.
*/ */
/* Shorten TIME_WAIT [RFC-1644, p.28] */ tw_time = 2 * tcp_msl;
if (tp->cc_recv != 0 && (ticks - tp->t_starttime) < tcp_msl) { acknow = tp->t_flags & TF_ACKNOW;
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;
}
tcp_discardcb(tp); tcp_discardcb(tp);
so = inp->inp_socket; so = inp->inp_socket;
ACCEPT_LOCK(); ACCEPT_LOCK();
@ -1803,16 +1776,6 @@ tcp_twrespond(struct tcptw *tw, int flags)
optp += TCPOLEN_TSTAMP_APPA; 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); optlen = optp - (u_int8_t *)(th + 1);
m->m_len = hdrlen + optlen; m->m_len = hdrlen + optlen;

View File

@ -815,14 +815,10 @@ tcp_connect(tp, nam, td)
{ {
struct inpcb *inp = tp->t_inpcb, *oinp; struct inpcb *inp = tp->t_inpcb, *oinp;
struct socket *so = inp->inp_socket; struct socket *so = inp->inp_socket;
struct tcptw *otw;
struct rmxp_tao tao;
struct in_addr laddr; struct in_addr laddr;
u_short lport; u_short lport;
int error; int error;
bzero(&tao, sizeof(tao));
if (inp->inp_lport == 0) { if (inp->inp_lport == 0) {
error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
if (error) if (error)
@ -840,17 +836,8 @@ tcp_connect(tp, nam, td)
&inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred); &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred);
if (error && oinp == NULL) if (error && oinp == NULL)
return error; return error;
if (oinp) { if (oinp)
if (oinp != inp && return EADDRINUSE;
(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;
}
inp->inp_laddr = laddr; inp->inp_laddr = laddr;
in_pcbrehash(inp); in_pcbrehash(inp);
@ -867,26 +854,6 @@ tcp_connect(tp, nam, td)
tp->t_bw_rtseq = tp->iss; tp->t_bw_rtseq = tp->iss;
tcp_sendseqinit(tp); 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; return 0;
} }
@ -899,14 +866,10 @@ tcp6_connect(tp, nam, td)
{ {
struct inpcb *inp = tp->t_inpcb, *oinp; struct inpcb *inp = tp->t_inpcb, *oinp;
struct socket *so = inp->inp_socket; struct socket *so = inp->inp_socket;
struct tcptw *otw;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
struct in6_addr *addr6; struct in6_addr *addr6;
struct rmxp_tao tao;
int error; int error;
bzero(&tao, sizeof(tao));
if (inp->inp_lport == 0) { if (inp->inp_lport == 0) {
error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
if (error) if (error)
@ -927,17 +890,8 @@ tcp6_connect(tp, nam, td)
? addr6 ? addr6
: &inp->in6p_laddr, : &inp->in6p_laddr,
inp->inp_lport, 0, NULL); inp->inp_lport, 0, NULL);
if (oinp) { if (oinp)
if (oinp != inp && return EADDRINUSE;
(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 (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
inp->in6p_laddr = *addr6; inp->in6p_laddr = *addr6;
inp->in6p_faddr = sin6->sin6_addr; inp->in6p_faddr = sin6->sin6_addr;
@ -962,25 +916,6 @@ tcp6_connect(tp, nam, td)
tp->t_bw_rtseq = tp->iss; tp->t_bw_rtseq = tp->iss;
tcp_sendseqinit(tp); 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; return 0;
} }
#endif /* INET6 */ #endif /* INET6 */

View File

@ -39,7 +39,6 @@
* Kernel variables for tcp. * Kernel variables for tcp.
*/ */
extern int tcp_do_rfc1323; extern int tcp_do_rfc1323;
extern int tcp_do_rfc1644;
/* TCP segment queue entry */ /* TCP segment queue entry */
struct tseg_qent { struct tseg_qent {
@ -102,9 +101,6 @@ struct tcpcb {
#define TF_NEEDSYN 0x000400 /* send SYN (implicit state) */ #define TF_NEEDSYN 0x000400 /* send SYN (implicit state) */
#define TF_NEEDFIN 0x000800 /* send FIN (implicit state) */ #define TF_NEEDFIN 0x000800 /* send FIN (implicit state) */
#define TF_NOPUSH 0x001000 /* don't push */ #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_MORETOCOME 0x010000 /* More data to be appended to sock */
#define TF_LQ_OVERFLOW 0x020000 /* listen queue overflow */ #define TF_LQ_OVERFLOW 0x020000 /* listen queue overflow */
#define TF_LASTIDLE 0x040000 /* connection was previously idle */ #define TF_LASTIDLE 0x040000 /* connection was previously idle */
@ -177,9 +173,6 @@ struct tcpcb {
u_long ts_recent_age; /* when last updated */ u_long ts_recent_age; /* when last updated */
tcp_seq last_ack_sent; tcp_seq last_ack_sent;
/* RFC 1644 variables */
tcp_cc cc_send; /* send connection count */
tcp_cc cc_recv; /* receive connection count */
/* experimental */ /* experimental */
u_long snd_cwnd_prev; /* cwnd prior to retransmit */ u_long snd_cwnd_prev; /* cwnd prior to retransmit */
u_long snd_ssthresh_prev; /* ssthresh prior to retransmit */ u_long snd_ssthresh_prev; /* ssthresh prior to retransmit */
@ -231,9 +224,6 @@ struct tcpcb {
struct tcpopt { struct tcpopt {
u_long to_flags; /* which options are present */ u_long to_flags; /* which options are present */
#define TOF_TS 0x0001 /* timestamp */ #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_MSS 0x0010
#define TOF_SCALE 0x0020 #define TOF_SCALE 0x0020
#define TOF_SIGNATURE 0x0040 /* signature option present */ #define TOF_SIGNATURE 0x0040 /* signature option present */
@ -241,8 +231,6 @@ struct tcpopt {
#define TOF_SACK 0x0100 /* Peer sent SACK option */ #define TOF_SACK 0x0100 /* Peer sent SACK option */
u_int32_t to_tsval; u_int32_t to_tsval;
u_int32_t to_tsecr; u_int32_t to_tsecr;
tcp_cc to_cc; /* holds CC or CCnew */
tcp_cc to_ccecho;
u_int16_t to_mss; u_int16_t to_mss;
u_int8_t to_requested_s_scale; u_int8_t to_requested_s_scale;
u_int8_t to_pad; u_int8_t to_pad;
@ -256,8 +244,6 @@ struct syncache {
struct in_conninfo sc_inc; /* addresses */ struct in_conninfo sc_inc; /* addresses */
u_int32_t sc_tsrecent; u_int32_t sc_tsrecent;
u_int32_t sc_flowlabel; /* IPv6 flowlabel */ 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_irs; /* seq from peer */
tcp_seq sc_iss; /* our ISS */ tcp_seq sc_iss; /* our ISS */
u_long sc_rxttime; /* retransmit time */ u_long sc_rxttime; /* retransmit time */
@ -270,7 +256,6 @@ struct syncache {
#define SCF_NOOPT 0x01 /* no TCP options */ #define SCF_NOOPT 0x01 /* no TCP options */
#define SCF_WINSCALE 0x02 /* negotiated window scaling */ #define SCF_WINSCALE 0x02 /* negotiated window scaling */
#define SCF_TIMESTAMP 0x04 /* negotiated timestamps */ #define SCF_TIMESTAMP 0x04 /* negotiated timestamps */
#define SCF_CC 0x08 /* negotiated CC */
#define SCF_UNREACH 0x10 /* icmp unreachable received */ #define SCF_UNREACH 0x10 /* icmp unreachable received */
#define SCF_SIGNATURE 0x20 /* send MD5 digests */ #define SCF_SIGNATURE 0x20 /* send MD5 digests */
#define SCF_SACK 0x80 /* send SACK option */ #define SCF_SACK 0x80 /* send SACK option */
@ -303,8 +288,6 @@ struct tcptw {
tcp_seq rcv_nxt; tcp_seq rcv_nxt;
tcp_seq iss; tcp_seq iss;
tcp_seq irs; tcp_seq irs;
tcp_cc cc_recv;
tcp_cc cc_send;
u_short last_win; /* cached window value */ u_short last_win; /* cached window value */
u_short tw_so_options; /* copy of so_options */ u_short tw_so_options; /* copy of so_options */
struct ucred *tw_cred; /* user credentials */ struct ucred *tw_cred; /* user credentials */
@ -314,21 +297,6 @@ struct tcptw {
LIST_ENTRY(tcptw) tw_2msl; 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 intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb)
#define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb) #define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb)
#define sototcpcb(so) (intotcpcb(sotoinpcb(so))) #define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
@ -487,7 +455,6 @@ struct xtcpcb {
* Names for TCP sysctl objects * Names for TCP sysctl objects
*/ */
#define TCPCTL_DO_RFC1323 1 /* use RFC-1323 extensions */ #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_MSSDFLT 3 /* MSS default */
#define TCPCTL_STATS 4 /* statistics (read-only) */ #define TCPCTL_STATS 4 /* statistics (read-only) */
#define TCPCTL_RTTDFLT 5 /* default RTT estimate */ #define TCPCTL_RTTDFLT 5 /* default RTT estimate */
@ -505,7 +472,6 @@ struct xtcpcb {
#define TCPCTL_NAMES { \ #define TCPCTL_NAMES { \
{ 0, 0 }, \ { 0, 0 }, \
{ "rfc1323", CTLTYPE_INT }, \ { "rfc1323", CTLTYPE_INT }, \
{ "rfc1644", CTLTYPE_INT }, \
{ "mssdflt", CTLTYPE_INT }, \ { "mssdflt", CTLTYPE_INT }, \
{ "stats", CTLTYPE_STRUCT }, \ { "stats", CTLTYPE_STRUCT }, \
{ "rttdflt", CTLTYPE_INT }, \ { "rttdflt", CTLTYPE_INT }, \
@ -600,14 +566,8 @@ void syncache_badack(struct in_conninfo *);
void tcp_hc_init(void); void tcp_hc_init(void);
void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *); void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *);
u_long tcp_hc_getmtu(struct in_conninfo *); 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_updatemtu(struct in_conninfo *, u_long);
void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *); 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 struct pr_usrreqs tcp_usrreqs;
extern u_long tcp_sendspace; extern u_long tcp_sendspace;