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:
parent
30bef41b8a
commit
c94c54e4df
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137139
5
UPDATING
5
UPDATING
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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));
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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_ */
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user