Deleted Added
full compact
tcp_input.c (132044) tcp_input.c (133874)
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95
30 * $FreeBSD: head/sys/netinet/tcp_input.c 132044 2004-07-12 19:28:07Z rwatson $
30 * $FreeBSD: head/sys/netinet/tcp_input.c 133874 2004-08-16 18:32:07Z rwatson $
31 */
32
33#include "opt_ipfw.h" /* for ipfw_fwd */
34#include "opt_inet.h"
35#include "opt_inet6.h"
36#include "opt_ipsec.h"
37#include "opt_mac.h"
38#include "opt_tcpdebug.h"

--- 61 unchanged lines hidden (view full) ---

100static const int tcprexmtthresh = 3;
101tcp_cc tcp_ccgen;
102
103struct tcpstat tcpstat;
104SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
105 &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)");
106
107static int log_in_vain = 0;
31 */
32
33#include "opt_ipfw.h" /* for ipfw_fwd */
34#include "opt_inet.h"
35#include "opt_inet6.h"
36#include "opt_ipsec.h"
37#include "opt_mac.h"
38#include "opt_tcpdebug.h"

--- 61 unchanged lines hidden (view full) ---

100static const int tcprexmtthresh = 3;
101tcp_cc tcp_ccgen;
102
103struct tcpstat tcpstat;
104SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
105 &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)");
106
107static int log_in_vain = 0;
108SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW,
108SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW,
109 &log_in_vain, 0, "Log all incoming TCP connections");
110
111static int blackhole = 0;
112SYSCTL_INT(_net_inet_tcp, OID_AUTO, blackhole, CTLFLAG_RW,
113 &blackhole, 0, "Do not send RST when dropping refused connections");
114
115int tcp_delack_enabled = 1;
109 &log_in_vain, 0, "Log all incoming TCP connections");
110
111static int blackhole = 0;
112SYSCTL_INT(_net_inet_tcp, OID_AUTO, blackhole, CTLFLAG_RW,
113 &blackhole, 0, "Do not send RST when dropping refused connections");
114
115int tcp_delack_enabled = 1;
116SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW,
117 &tcp_delack_enabled, 0,
116SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW,
117 &tcp_delack_enabled, 0,
118 "Delay ACK to try and piggyback it onto a data packet");
119
120#ifdef TCP_DROP_SYNFIN
121static int drop_synfin = 0;
122SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW,
123 &drop_synfin, 0, "Drop TCP packets with SYN+FIN set");
124#endif
125

--- 263 unchanged lines hidden (view full) ---

389
390 IP6_EXTHDR_CHECK(m, *offp, sizeof(struct tcphdr), IPPROTO_DONE);
391
392 /*
393 * draft-itojun-ipv6-tcp-to-anycast
394 * better place to put this in?
395 */
396 ia6 = ip6_getdstifaddr(m);
118 "Delay ACK to try and piggyback it onto a data packet");
119
120#ifdef TCP_DROP_SYNFIN
121static int drop_synfin = 0;
122SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW,
123 &drop_synfin, 0, "Drop TCP packets with SYN+FIN set");
124#endif
125

--- 263 unchanged lines hidden (view full) ---

389
390 IP6_EXTHDR_CHECK(m, *offp, sizeof(struct tcphdr), IPPROTO_DONE);
391
392 /*
393 * draft-itojun-ipv6-tcp-to-anycast
394 * better place to put this in?
395 */
396 ia6 = ip6_getdstifaddr(m);
397 if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) {
397 if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) {
398 struct ip6_hdr *ip6;
399
400 ip6 = mtod(m, struct ip6_hdr *);
401 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR,
402 (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
403 return IPPROTO_DONE;
404 }
405

--- 204 unchanged lines hidden (view full) ---

610 */
611 INP_INFO_WLOCK(&tcbinfo);
612 headlocked = 1;
613findpcb:
614 /* IPFIREWALL_FORWARD section */
615 if (next_hop != NULL && isipv6 == 0) { /* IPv6 support is not yet */
616 /*
617 * Transparently forwarded. Pretend to be the destination.
398 struct ip6_hdr *ip6;
399
400 ip6 = mtod(m, struct ip6_hdr *);
401 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR,
402 (caddr_t)&ip6->ip6_dst - (caddr_t)ip6);
403 return IPPROTO_DONE;
404 }
405

--- 204 unchanged lines hidden (view full) ---

610 */
611 INP_INFO_WLOCK(&tcbinfo);
612 headlocked = 1;
613findpcb:
614 /* IPFIREWALL_FORWARD section */
615 if (next_hop != NULL && isipv6 == 0) { /* IPv6 support is not yet */
616 /*
617 * Transparently forwarded. Pretend to be the destination.
618 * already got one like this?
618 * already got one like this?
619 */
620 inp = in_pcblookup_hash(&tcbinfo, ip->ip_src, th->th_sport,
621 ip->ip_dst, th->th_dport,
622 0, m->m_pkthdr.rcvif);
623 if (!inp) {
624 /* It's new. Try find the ambushing socket. */
625 inp = in_pcblookup_hash(&tcbinfo,
626 ip->ip_src, th->th_sport,

--- 11 unchanged lines hidden (view full) ---

638 &ip6->ip6_dst, th->th_dport,
639 1, m->m_pkthdr.rcvif);
640#endif
641 } else
642 inp = in_pcblookup_hash(&tcbinfo,
643 ip->ip_src, th->th_sport,
644 ip->ip_dst, th->th_dport,
645 1, m->m_pkthdr.rcvif);
619 */
620 inp = in_pcblookup_hash(&tcbinfo, ip->ip_src, th->th_sport,
621 ip->ip_dst, th->th_dport,
622 0, m->m_pkthdr.rcvif);
623 if (!inp) {
624 /* It's new. Try find the ambushing socket. */
625 inp = in_pcblookup_hash(&tcbinfo,
626 ip->ip_src, th->th_sport,

--- 11 unchanged lines hidden (view full) ---

638 &ip6->ip6_dst, th->th_dport,
639 1, m->m_pkthdr.rcvif);
640#endif
641 } else
642 inp = in_pcblookup_hash(&tcbinfo,
643 ip->ip_src, th->th_sport,
644 ip->ip_dst, th->th_dport,
645 1, m->m_pkthdr.rcvif);
646 }
646 }
647
648#if defined(IPSEC) || defined(FAST_IPSEC)
649#ifdef INET6
650 if (isipv6) {
651 if (inp != NULL && ipsec6_in_reject(m, inp)) {
652#ifdef IPSEC
653 ipsec6stat.in_polvio++;
654#endif

--- 47 unchanged lines hidden (view full) ---

702 "from %s:%d flags:0x%02x\n",
703 dbuf, ntohs(th->th_dport), sbuf,
704 ntohs(th->th_sport), thflags);
705 break;
706 default:
707 break;
708 }
709 }
647
648#if defined(IPSEC) || defined(FAST_IPSEC)
649#ifdef INET6
650 if (isipv6) {
651 if (inp != NULL && ipsec6_in_reject(m, inp)) {
652#ifdef IPSEC
653 ipsec6stat.in_polvio++;
654#endif

--- 47 unchanged lines hidden (view full) ---

702 "from %s:%d flags:0x%02x\n",
703 dbuf, ntohs(th->th_dport), sbuf,
704 ntohs(th->th_sport), thflags);
705 break;
706 default:
707 break;
708 }
709 }
710 if (blackhole) {
710 if (blackhole) {
711 switch (blackhole) {
712 case 1:
713 if (thflags & TH_SYN)
714 goto drop;
715 break;
716 case 2:
717 goto drop;
718 default:

--- 252 unchanged lines hidden (view full) ---

971 * T/TCP logic:
972 * If there is a FIN or if there is data, then
973 * delay SYN,ACK(SYN) in the hope of piggy-backing
974 * it on a response segment. Otherwise must send
975 * ACK now in case the other side is slow starting.
976 */
977 if (thflags & TH_FIN || tlen != 0)
978 tp->t_flags |= (TF_DELACK | TF_NEEDSYN);
711 switch (blackhole) {
712 case 1:
713 if (thflags & TH_SYN)
714 goto drop;
715 break;
716 case 2:
717 goto drop;
718 default:

--- 252 unchanged lines hidden (view full) ---

971 * T/TCP logic:
972 * If there is a FIN or if there is data, then
973 * delay SYN,ACK(SYN) in the hope of piggy-backing
974 * it on a response segment. Otherwise must send
975 * ACK now in case the other side is slow starting.
976 */
977 if (thflags & TH_FIN || tlen != 0)
978 tp->t_flags |= (TF_DELACK | TF_NEEDSYN);
979 else
979 else
980 tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN);
981 tcpstat.tcps_connects++;
982 soisconnected(so);
983 goto trimthenstep6;
984 }
985 goto drop;
986 }
987after_listen:

--- 150 unchanged lines hidden (view full) ---

1138 }
1139
1140 if (tlen == 0) {
1141 if (SEQ_GT(th->th_ack, tp->snd_una) &&
1142 SEQ_LEQ(th->th_ack, tp->snd_max) &&
1143 tp->snd_cwnd >= tp->snd_wnd &&
1144 ((!tcp_do_newreno && !tp->sack_enable &&
1145 tp->t_dupacks < tcprexmtthresh) ||
980 tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN);
981 tcpstat.tcps_connects++;
982 soisconnected(so);
983 goto trimthenstep6;
984 }
985 goto drop;
986 }
987after_listen:

--- 150 unchanged lines hidden (view full) ---

1138 }
1139
1140 if (tlen == 0) {
1141 if (SEQ_GT(th->th_ack, tp->snd_una) &&
1142 SEQ_LEQ(th->th_ack, tp->snd_max) &&
1143 tp->snd_cwnd >= tp->snd_wnd &&
1144 ((!tcp_do_newreno && !tp->sack_enable &&
1145 tp->t_dupacks < tcprexmtthresh) ||
1146 ((tcp_do_newreno || tp->sack_enable) &&
1146 ((tcp_do_newreno || tp->sack_enable) &&
1147 !IN_FASTRECOVERY(tp)))) {
1148 KASSERT(headlocked, ("headlocked"));
1149 INP_INFO_WUNLOCK(&tcbinfo);
1150 /*
1151 * this is a pure ack for outstanding data.
1152 */
1153 ++tcpstat.tcps_predack;
1154 /*

--- 11 unchanged lines hidden (view full) ---

1166 tp->snd_nxt = tp->snd_max;
1167 tp->t_badrxtwin = 0;
1168 }
1169
1170 /*
1171 * Recalculate the transmit timer / rtt.
1172 *
1173 * Some boxes send broken timestamp replies
1147 !IN_FASTRECOVERY(tp)))) {
1148 KASSERT(headlocked, ("headlocked"));
1149 INP_INFO_WUNLOCK(&tcbinfo);
1150 /*
1151 * this is a pure ack for outstanding data.
1152 */
1153 ++tcpstat.tcps_predack;
1154 /*

--- 11 unchanged lines hidden (view full) ---

1166 tp->snd_nxt = tp->snd_max;
1167 tp->t_badrxtwin = 0;
1168 }
1169
1170 /*
1171 * Recalculate the transmit timer / rtt.
1172 *
1173 * Some boxes send broken timestamp replies
1174 * during the SYN+ACK phase, ignore
1174 * during the SYN+ACK phase, ignore
1175 * timestamps of 0 or we could calculate a
1176 * huge RTT and blow up the retransmit timer.
1177 */
1178 if ((to.to_flags & TOF_TS) != 0 &&
1179 to.to_tsecr) {
1180 tcp_xmit_timer(tp,
1181 ticks - to.to_tsecr + 1);
1182 } else if (tp->t_rtttime &&

--- 33 unchanged lines hidden (view full) ---

1216 tcp_trace(TA_INPUT, ostate, tp,
1217 (void *)tcp_saveipgen,
1218 &tcp_savetcp, 0);
1219#endif
1220 */
1221 if (tp->snd_una == tp->snd_max)
1222 callout_stop(tp->tt_rexmt);
1223 else if (!callout_active(tp->tt_persist))
1175 * timestamps of 0 or we could calculate a
1176 * huge RTT and blow up the retransmit timer.
1177 */
1178 if ((to.to_flags & TOF_TS) != 0 &&
1179 to.to_tsecr) {
1180 tcp_xmit_timer(tp,
1181 ticks - to.to_tsecr + 1);
1182 } else if (tp->t_rtttime &&

--- 33 unchanged lines hidden (view full) ---

1216 tcp_trace(TA_INPUT, ostate, tp,
1217 (void *)tcp_saveipgen,
1218 &tcp_savetcp, 0);
1219#endif
1220 */
1221 if (tp->snd_una == tp->snd_max)
1222 callout_stop(tp->tt_rexmt);
1223 else if (!callout_active(tp->tt_persist))
1224 callout_reset(tp->tt_rexmt,
1224 callout_reset(tp->tt_rexmt,
1225 tp->t_rxtcur,
1226 tcp_timer_rexmt, tp);
1227
1228 sowwakeup(so);
1229 if (so->so_snd.sb_cc)
1230 (void) tcp_output(tp);
1231 goto check_delack;
1232 }

--- 166 unchanged lines hidden (view full) ---

1399
1400 tp->rcv_adv += tp->rcv_wnd;
1401 tp->snd_una++; /* SYN is acked */
1402 /*
1403 * If there's data, delay ACK; if there's also a FIN
1404 * ACKNOW will be turned on later.
1405 */
1406 if (DELAY_ACK(tp) && tlen != 0)
1225 tp->t_rxtcur,
1226 tcp_timer_rexmt, tp);
1227
1228 sowwakeup(so);
1229 if (so->so_snd.sb_cc)
1230 (void) tcp_output(tp);
1231 goto check_delack;
1232 }

--- 166 unchanged lines hidden (view full) ---

1399
1400 tp->rcv_adv += tp->rcv_wnd;
1401 tp->snd_una++; /* SYN is acked */
1402 /*
1403 * If there's data, delay ACK; if there's also a FIN
1404 * ACKNOW will be turned on later.
1405 */
1406 if (DELAY_ACK(tp) && tlen != 0)
1407 callout_reset(tp->tt_delack, tcp_delacktime,
1408 tcp_timer_delack, tp);
1407 callout_reset(tp->tt_delack, tcp_delacktime,
1408 tcp_timer_delack, tp);
1409 else
1410 tp->t_flags |= TF_ACKNOW;
1411 /*
1412 * Received <SYN,ACK> in SYN_SENT[*] state.
1413 * Transitions:
1414 * SYN_SENT --> ESTABLISHED
1415 * SYN_SENT* --> FIN_WAIT_1
1416 */

--- 4 unchanged lines hidden (view full) ---

1421 thflags &= ~TH_SYN;
1422 } else {
1423 tp->t_state = TCPS_ESTABLISHED;
1424 callout_reset(tp->tt_keep, tcp_keepidle,
1425 tcp_timer_keep, tp);
1426 }
1427 } else {
1428 /*
1409 else
1410 tp->t_flags |= TF_ACKNOW;
1411 /*
1412 * Received <SYN,ACK> in SYN_SENT[*] state.
1413 * Transitions:
1414 * SYN_SENT --> ESTABLISHED
1415 * SYN_SENT* --> FIN_WAIT_1
1416 */

--- 4 unchanged lines hidden (view full) ---

1421 thflags &= ~TH_SYN;
1422 } else {
1423 tp->t_state = TCPS_ESTABLISHED;
1424 callout_reset(tp->tt_keep, tcp_keepidle,
1425 tcp_timer_keep, tp);
1426 }
1427 } else {
1428 /*
1429 * Received initial SYN in SYN-SENT[*] state =>
1430 * simultaneous open. If segment contains CC option
1431 * and there is a cached CC, apply TAO test.
1432 * If it succeeds, connection is * half-synchronized.
1433 * Otherwise, do 3-way handshake:
1434 * SYN-SENT -> SYN-RECEIVED
1435 * SYN-SENT* -> SYN-RECEIVED*
1436 * If there was no CC option, clear cached CC value.
1437 */
1429 * Received initial SYN in SYN-SENT[*] state =>
1430 * simultaneous open. If segment contains CC option
1431 * and there is a cached CC, apply TAO test.
1432 * If it succeeds, connection is * half-synchronized.
1433 * Otherwise, do 3-way handshake:
1434 * SYN-SENT -> SYN-RECEIVED
1435 * SYN-SENT* -> SYN-RECEIVED*
1436 * If there was no CC option, clear cached CC value.
1437 */
1438 tp->t_flags |= TF_ACKNOW;
1439 callout_stop(tp->tt_rexmt);
1440 if (to.to_flags & TOF_CC) {
1441 if (tao.tao_cc != 0 &&
1442 CC_GT(to.to_cc, tao.tao_cc)) {
1443 /*
1444 * update cache and make transition:
1445 * SYN-SENT -> ESTABLISHED*

--- 50 unchanged lines hidden (view full) ---

1496 tp->rcv_up = th->th_seq;
1497 /*
1498 * Client side of transaction: already sent SYN and data.
1499 * If the remote host used T/TCP to validate the SYN,
1500 * our data will be ACK'd; if so, enter normal data segment
1501 * processing in the middle of step 5, ack processing.
1502 * Otherwise, goto step 6.
1503 */
1438 tp->t_flags |= TF_ACKNOW;
1439 callout_stop(tp->tt_rexmt);
1440 if (to.to_flags & TOF_CC) {
1441 if (tao.tao_cc != 0 &&
1442 CC_GT(to.to_cc, tao.tao_cc)) {
1443 /*
1444 * update cache and make transition:
1445 * SYN-SENT -> ESTABLISHED*

--- 50 unchanged lines hidden (view full) ---

1496 tp->rcv_up = th->th_seq;
1497 /*
1498 * Client side of transaction: already sent SYN and data.
1499 * If the remote host used T/TCP to validate the SYN,
1500 * our data will be ACK'd; if so, enter normal data segment
1501 * processing in the middle of step 5, ack processing.
1502 * Otherwise, goto step 6.
1503 */
1504 if (thflags & TH_ACK)
1504 if (thflags & TH_ACK)
1505 goto process_ACK;
1506
1507 goto step6;
1508
1509 /*
1510 * If the state is LAST_ACK or CLOSING or TIME_WAIT:
1511 * if segment contains a SYN and CC [not CC.NEW] option:
1512 * if state == TIME_WAIT and connection duration > MSL,

--- 20 unchanged lines hidden (view full) ---

1533 }
1534 if (CC_GT(to.to_cc, tp->cc_recv)) {
1535 tp = tcp_close(tp);
1536 goto findpcb;
1537 }
1538 else
1539 goto drop;
1540 }
1505 goto process_ACK;
1506
1507 goto step6;
1508
1509 /*
1510 * If the state is LAST_ACK or CLOSING or TIME_WAIT:
1511 * if segment contains a SYN and CC [not CC.NEW] option:
1512 * if state == TIME_WAIT and connection duration > MSL,

--- 20 unchanged lines hidden (view full) ---

1533 }
1534 if (CC_GT(to.to_cc, tp->cc_recv)) {
1535 tp = tcp_close(tp);
1536 goto findpcb;
1537 }
1538 else
1539 goto drop;
1540 }
1541 break; /* continue normal processing */
1541 break; /* continue normal processing */
1542 }
1543
1544 /*
1545 * States other than LISTEN or SYN_SENT.
1546 * First check the RST flag and sequence number since reset segments
1547 * are exempt from the timestamp and connection count tests. This
1548 * fixes a bug introduced by the Stevens, vol. 2, p. 960 bugfix
1549 * below which allowed reset segments in half the sequence space

--- 19 unchanged lines hidden (view full) ---

1569 * echo of our outgoing acknowlegement numbers, but some hosts
1570 * send a reset with the sequence number at the rightmost edge
1571 * of our receive window, and we have to handle this case.
1572 * Note 2: Paul Watson's paper "Slipping in the Window" has shown
1573 * that brute force RST attacks are possible. To combat this,
1574 * we use a much stricter check while in the ESTABLISHED state,
1575 * only accepting RSTs where the sequence number is equal to
1576 * last_ack_sent. In all other states (the states in which a
1542 }
1543
1544 /*
1545 * States other than LISTEN or SYN_SENT.
1546 * First check the RST flag and sequence number since reset segments
1547 * are exempt from the timestamp and connection count tests. This
1548 * fixes a bug introduced by the Stevens, vol. 2, p. 960 bugfix
1549 * below which allowed reset segments in half the sequence space

--- 19 unchanged lines hidden (view full) ---

1569 * echo of our outgoing acknowlegement numbers, but some hosts
1570 * send a reset with the sequence number at the rightmost edge
1571 * of our receive window, and we have to handle this case.
1572 * Note 2: Paul Watson's paper "Slipping in the Window" has shown
1573 * that brute force RST attacks are possible. To combat this,
1574 * we use a much stricter check while in the ESTABLISHED state,
1575 * only accepting RSTs where the sequence number is equal to
1576 * last_ack_sent. In all other states (the states in which a
1577 * RST is more likely), the more permissive check is used.
1577 * RST is more likely), the more permissive check is used.
1578 * If we have multiple segments in flight, the intial reset
1579 * segment sequence numbers will be to the left of last_ack_sent,
1580 * but they will eventually catch up.
1581 * In any case, it never made sense to trim reset segments to
1582 * fit the receive window since RFC 1122 says:
1583 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
1584 *
1585 * A TCP SHOULD allow a received RST segment to include data.

--- 89 unchanged lines hidden (view full) ---

1675 /*
1676 * T/TCP mechanism
1677 * If T/TCP was negotiated and the segment doesn't have CC,
1678 * or if its CC is wrong then drop the segment.
1679 * RST segments do not have to comply with this.
1680 */
1681 if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
1682 ((to.to_flags & TOF_CC) == 0 || tp->cc_recv != to.to_cc))
1578 * If we have multiple segments in flight, the intial reset
1579 * segment sequence numbers will be to the left of last_ack_sent,
1580 * but they will eventually catch up.
1581 * In any case, it never made sense to trim reset segments to
1582 * fit the receive window since RFC 1122 says:
1583 * 4.2.2.12 RST Segment: RFC-793 Section 3.4
1584 *
1585 * A TCP SHOULD allow a received RST segment to include data.

--- 89 unchanged lines hidden (view full) ---

1675 /*
1676 * T/TCP mechanism
1677 * If T/TCP was negotiated and the segment doesn't have CC,
1678 * or if its CC is wrong then drop the segment.
1679 * RST segments do not have to comply with this.
1680 */
1681 if ((tp->t_flags & (TF_REQ_CC|TF_RCVD_CC)) == (TF_REQ_CC|TF_RCVD_CC) &&
1682 ((to.to_flags & TOF_CC) == 0 || tp->cc_recv != to.to_cc))
1683 goto dropafterack;
1683 goto dropafterack;
1684
1685 /*
1686 * In the SYN-RECEIVED state, validate that the packet belongs to
1687 * this connection before trimming the data to fit the receive
1688 * window. Check the sequence number versus IRS since we know
1689 * the sequence numbers haven't wrapped. This is a partial fix
1690 * for the "LAND" DoS attack.
1691 */

--- 172 unchanged lines hidden (view full) ---

1864 * SYN-RECEIVED* -> FIN-WAIT-1
1865 */
1866 tp->t_starttime = ticks;
1867 if (tp->t_flags & TF_NEEDFIN) {
1868 tp->t_state = TCPS_FIN_WAIT_1;
1869 tp->t_flags &= ~TF_NEEDFIN;
1870 } else {
1871 tp->t_state = TCPS_ESTABLISHED;
1684
1685 /*
1686 * In the SYN-RECEIVED state, validate that the packet belongs to
1687 * this connection before trimming the data to fit the receive
1688 * window. Check the sequence number versus IRS since we know
1689 * the sequence numbers haven't wrapped. This is a partial fix
1690 * for the "LAND" DoS attack.
1691 */

--- 172 unchanged lines hidden (view full) ---

1864 * SYN-RECEIVED* -> FIN-WAIT-1
1865 */
1866 tp->t_starttime = ticks;
1867 if (tp->t_flags & TF_NEEDFIN) {
1868 tp->t_state = TCPS_FIN_WAIT_1;
1869 tp->t_flags &= ~TF_NEEDFIN;
1870 } else {
1871 tp->t_state = TCPS_ESTABLISHED;
1872 callout_reset(tp->tt_keep, tcp_keepidle,
1872 callout_reset(tp->tt_keep, tcp_keepidle,
1873 tcp_timer_keep, tp);
1874 }
1875 /*
1876 * If segment contains data or ACK, will call tcp_reass()
1877 * later; if not, do so now to pass queued data to user.
1878 */
1879 if (tlen == 0 && (thflags & TH_FIN) == 0)
1880 (void) tcp_reass(tp, (struct tcphdr *)0, 0,

--- 53 unchanged lines hidden (view full) ---

1934 tp->snd_cwnd += tp->t_maxseg;
1935 (void) tcp_output(tp);
1936 goto drop;
1937 } else if (tp->t_dupacks == tcprexmtthresh) {
1938 tcp_seq onxt = tp->snd_nxt;
1939 u_int win;
1940
1941 /*
1873 tcp_timer_keep, tp);
1874 }
1875 /*
1876 * If segment contains data or ACK, will call tcp_reass()
1877 * later; if not, do so now to pass queued data to user.
1878 */
1879 if (tlen == 0 && (thflags & TH_FIN) == 0)
1880 (void) tcp_reass(tp, (struct tcphdr *)0, 0,

--- 53 unchanged lines hidden (view full) ---

1934 tp->snd_cwnd += tp->t_maxseg;
1935 (void) tcp_output(tp);
1936 goto drop;
1937 } else if (tp->t_dupacks == tcprexmtthresh) {
1938 tcp_seq onxt = tp->snd_nxt;
1939 u_int win;
1940
1941 /*
1942 * If we're doing sack, check to
1943 * see if we're already in sack
1942 * If we're doing sack, check to
1943 * see if we're already in sack
1944 * recovery. If we're not doing sack,
1945 * check to see if we're in newreno
1946 * recovery.
1947 */
1948 if (tp->sack_enable) {
1949 if (IN_FASTRECOVERY(tp)) {
1950 tp->t_dupacks = 0;
1951 break;

--- 11 unchanged lines hidden (view full) ---

1963 win = 2;
1964 tp->snd_ssthresh = win * tp->t_maxseg;
1965 ENTER_FASTRECOVERY(tp);
1966 tp->snd_recover = tp->snd_max;
1967 callout_stop(tp->tt_rexmt);
1968 tp->t_rtttime = 0;
1969 if (tp->sack_enable) {
1970 tcpstat.tcps_sack_recovery_episode++;
1944 * recovery. If we're not doing sack,
1945 * check to see if we're in newreno
1946 * recovery.
1947 */
1948 if (tp->sack_enable) {
1949 if (IN_FASTRECOVERY(tp)) {
1950 tp->t_dupacks = 0;
1951 break;

--- 11 unchanged lines hidden (view full) ---

1963 win = 2;
1964 tp->snd_ssthresh = win * tp->t_maxseg;
1965 ENTER_FASTRECOVERY(tp);
1966 tp->snd_recover = tp->snd_max;
1967 callout_stop(tp->tt_rexmt);
1968 tp->t_rtttime = 0;
1969 if (tp->sack_enable) {
1970 tcpstat.tcps_sack_recovery_episode++;
1971 tp->snd_cwnd =
1972 tp->t_maxseg *
1971 tp->snd_cwnd =
1972 tp->t_maxseg *
1973 tp->t_dupacks;
1974 (void) tcp_output(tp);
1973 tp->t_dupacks;
1974 (void) tcp_output(tp);
1975 tp->snd_cwnd +=
1975 tp->snd_cwnd +=
1976 tp->snd_ssthresh;
1977 goto drop;
1978 }
1979
1980 tp->snd_nxt = th->th_ack;
1981 tp->snd_cwnd = tp->t_maxseg;
1982 (void) tcp_output(tp);
1983 KASSERT(tp->snd_limited <= 2,

--- 65 unchanged lines hidden (view full) ---

2049 tp->snd_max))
2050 tp->snd_cwnd = tp->snd_max -
2051 th->th_ack +
2052 tp->t_maxseg;
2053 else
2054 tp->snd_cwnd = tp->snd_ssthresh;
2055 }
2056 }
1976 tp->snd_ssthresh;
1977 goto drop;
1978 }
1979
1980 tp->snd_nxt = th->th_ack;
1981 tp->snd_cwnd = tp->t_maxseg;
1982 (void) tcp_output(tp);
1983 KASSERT(tp->snd_limited <= 2,

--- 65 unchanged lines hidden (view full) ---

2049 tp->snd_max))
2050 tp->snd_cwnd = tp->snd_max -
2051 th->th_ack +
2052 tp->t_maxseg;
2053 else
2054 tp->snd_cwnd = tp->snd_ssthresh;
2055 }
2056 }
2057 } else {
2058 if (tp->t_dupacks >= tcprexmtthresh &&
2059 tp->snd_cwnd > tp->snd_ssthresh)
2057 } else {
2058 if (tp->t_dupacks >= tcprexmtthresh &&
2059 tp->snd_cwnd > tp->snd_ssthresh)
2060 tp->snd_cwnd = tp->snd_ssthresh;
2060 tp->snd_cwnd = tp->snd_ssthresh;
2061 }
2061 }
2062 tp->t_dupacks = 0;
2063 if (SEQ_GT(th->th_ack, tp->snd_max)) {
2064 tcpstat.tcps_rcvacktoomuch++;
2065 goto dropafterack;
2066 }
2067 /*
2068 * If we reach this point, ACK is not a duplicate,
2069 * i.e., it ACKs something we sent.

--- 35 unchanged lines hidden (view full) ---

2105 if (tp->t_rxtshift == 1 && ticks < tp->t_badrxtwin) {
2106 ++tcpstat.tcps_sndrexmitbad;
2107 tp->snd_cwnd = tp->snd_cwnd_prev;
2108 tp->snd_ssthresh = tp->snd_ssthresh_prev;
2109 tp->snd_recover = tp->snd_recover_prev;
2110 if (tp->t_flags & TF_WASFRECOVERY)
2111 ENTER_FASTRECOVERY(tp);
2112 tp->snd_nxt = tp->snd_max;
2062 tp->t_dupacks = 0;
2063 if (SEQ_GT(th->th_ack, tp->snd_max)) {
2064 tcpstat.tcps_rcvacktoomuch++;
2065 goto dropafterack;
2066 }
2067 /*
2068 * If we reach this point, ACK is not a duplicate,
2069 * i.e., it ACKs something we sent.

--- 35 unchanged lines hidden (view full) ---

2105 if (tp->t_rxtshift == 1 && ticks < tp->t_badrxtwin) {
2106 ++tcpstat.tcps_sndrexmitbad;
2107 tp->snd_cwnd = tp->snd_cwnd_prev;
2108 tp->snd_ssthresh = tp->snd_ssthresh_prev;
2109 tp->snd_recover = tp->snd_recover_prev;
2110 if (tp->t_flags & TF_WASFRECOVERY)
2111 ENTER_FASTRECOVERY(tp);
2112 tp->snd_nxt = tp->snd_max;
2113 tp->t_badrxtwin = 0; /* XXX probably not required */
2113 tp->t_badrxtwin = 0; /* XXX probably not required */
2114 }
2115
2116 /*
2117 * If we have a timestamp reply, update smoothed
2118 * round trip time. If no timestamp is present but
2119 * transmit timer is running and timed sequence
2120 * number was acked, update smoothed round trip time.
2121 * Since we now have an rtt measurement, cancel the
2122 * timer backoff (cf., Phil Karn's retransmit alg.).
2123 * Recompute the initial retransmit timer.
2124 *
2125 * Some boxes send broken timestamp replies
2114 }
2115
2116 /*
2117 * If we have a timestamp reply, update smoothed
2118 * round trip time. If no timestamp is present but
2119 * transmit timer is running and timed sequence
2120 * number was acked, update smoothed round trip time.
2121 * Since we now have an rtt measurement, cancel the
2122 * timer backoff (cf., Phil Karn's retransmit alg.).
2123 * Recompute the initial retransmit timer.
2124 *
2125 * Some boxes send broken timestamp replies
2126 * during the SYN+ACK phase, ignore
2126 * during the SYN+ACK phase, ignore
2127 * timestamps of 0 or we could calculate a
2128 * huge RTT and blow up the retransmit timer.
2129 */
2130 if ((to.to_flags & TOF_TS) != 0 &&
2131 to.to_tsecr) {
2132 tcp_xmit_timer(tp, ticks - to.to_tsecr + 1);
2133 } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) {
2134 tcp_xmit_timer(tp, ticks - tp->t_rtttime);

--- 22 unchanged lines hidden (view full) ---

2157
2158 /*
2159 * When new data is acked, open the congestion window.
2160 * If the window gives us less than ssthresh packets
2161 * in flight, open exponentially (maxseg per packet).
2162 * Otherwise open linearly: maxseg per window
2163 * (maxseg^2 / cwnd per packet).
2164 */
2127 * timestamps of 0 or we could calculate a
2128 * huge RTT and blow up the retransmit timer.
2129 */
2130 if ((to.to_flags & TOF_TS) != 0 &&
2131 to.to_tsecr) {
2132 tcp_xmit_timer(tp, ticks - to.to_tsecr + 1);
2133 } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) {
2134 tcp_xmit_timer(tp, ticks - tp->t_rtttime);

--- 22 unchanged lines hidden (view full) ---

2157
2158 /*
2159 * When new data is acked, open the congestion window.
2160 * If the window gives us less than ssthresh packets
2161 * in flight, open exponentially (maxseg per packet).
2162 * Otherwise open linearly: maxseg per window
2163 * (maxseg^2 / cwnd per packet).
2164 */
2165 if ((!tcp_do_newreno && !tp->sack_enable) ||
2165 if ((!tcp_do_newreno && !tp->sack_enable) ||
2166 !IN_FASTRECOVERY(tp)) {
2167 register u_int cw = tp->snd_cwnd;
2168 register u_int incr = tp->t_maxseg;
2169 if (cw > tp->snd_ssthresh)
2170 incr = incr * incr / cw;
2171 tp->snd_cwnd = min(cw+incr, TCP_MAXWIN<<tp->snd_scale);
2172 }
2173 SOCKBUF_LOCK(&so->so_snd);
2174 if (acked > so->so_snd.sb_cc) {
2175 tp->snd_wnd -= so->so_snd.sb_cc;
2176 sbdrop_locked(&so->so_snd, (int)so->so_snd.sb_cc);
2177 ourfinisacked = 1;
2178 } else {
2179 sbdrop_locked(&so->so_snd, acked);
2180 tp->snd_wnd -= acked;
2181 ourfinisacked = 0;
2182 }
2183 sowwakeup_locked(so);
2184 /* detect una wraparound */
2166 !IN_FASTRECOVERY(tp)) {
2167 register u_int cw = tp->snd_cwnd;
2168 register u_int incr = tp->t_maxseg;
2169 if (cw > tp->snd_ssthresh)
2170 incr = incr * incr / cw;
2171 tp->snd_cwnd = min(cw+incr, TCP_MAXWIN<<tp->snd_scale);
2172 }
2173 SOCKBUF_LOCK(&so->so_snd);
2174 if (acked > so->so_snd.sb_cc) {
2175 tp->snd_wnd -= so->so_snd.sb_cc;
2176 sbdrop_locked(&so->so_snd, (int)so->so_snd.sb_cc);
2177 ourfinisacked = 1;
2178 } else {
2179 sbdrop_locked(&so->so_snd, acked);
2180 tp->snd_wnd -= acked;
2181 ourfinisacked = 0;
2182 }
2183 sowwakeup_locked(so);
2184 /* detect una wraparound */
2185 if ((tcp_do_newreno || tp->sack_enable) &&
2185 if ((tcp_do_newreno || tp->sack_enable) &&
2186 !IN_FASTRECOVERY(tp) &&
2187 SEQ_GT(tp->snd_una, tp->snd_recover) &&
2188 SEQ_LEQ(th->th_ack, tp->snd_recover))
2189 tp->snd_recover = th->th_ack - 1;
2186 !IN_FASTRECOVERY(tp) &&
2187 SEQ_GT(tp->snd_una, tp->snd_recover) &&
2188 SEQ_LEQ(th->th_ack, tp->snd_recover))
2189 tp->snd_recover = th->th_ack - 1;
2190 if ((tcp_do_newreno || tp->sack_enable) &&
2190 if ((tcp_do_newreno || tp->sack_enable) &&
2191 IN_FASTRECOVERY(tp) &&
2192 SEQ_GEQ(th->th_ack, tp->snd_recover))
2193 EXIT_FASTRECOVERY(tp);
2194 tp->snd_una = th->th_ack;
2195 if (tp->sack_enable) {
2196 if (SEQ_GT(tp->snd_una, tp->snd_recover))
2197 tp->snd_recover = tp->snd_una;
2191 IN_FASTRECOVERY(tp) &&
2192 SEQ_GEQ(th->th_ack, tp->snd_recover))
2193 EXIT_FASTRECOVERY(tp);
2194 tp->snd_una = th->th_ack;
2195 if (tp->sack_enable) {
2196 if (SEQ_GT(tp->snd_una, tp->snd_recover))
2197 tp->snd_recover = tp->snd_una;
2198 }
2198 }
2199 if (SEQ_LT(tp->snd_nxt, tp->snd_una))
2200 tp->snd_nxt = tp->snd_una;
2201
2202 switch (tp->t_state) {
2203
2204 /*
2205 * In FIN_WAIT_1 STATE in addition to the processing
2206 * for the ESTABLISHED state if our FIN is now acknowledged

--- 16 unchanged lines hidden (view full) ---

2223 soisdisconnected(so);
2224 callout_reset(tp->tt_2msl, tcp_maxidle,
2225 tcp_timer_2msl, tp);
2226 }
2227 tp->t_state = TCPS_FIN_WAIT_2;
2228 }
2229 break;
2230
2199 if (SEQ_LT(tp->snd_nxt, tp->snd_una))
2200 tp->snd_nxt = tp->snd_una;
2201
2202 switch (tp->t_state) {
2203
2204 /*
2205 * In FIN_WAIT_1 STATE in addition to the processing
2206 * for the ESTABLISHED state if our FIN is now acknowledged

--- 16 unchanged lines hidden (view full) ---

2223 soisdisconnected(so);
2224 callout_reset(tp->tt_2msl, tcp_maxidle,
2225 tcp_timer_2msl, tp);
2226 }
2227 tp->t_state = TCPS_FIN_WAIT_2;
2228 }
2229 break;
2230
2231 /*
2231 /*
2232 * In CLOSING STATE in addition to the processing for
2233 * the ESTABLISHED state if the ACK acknowledges our FIN
2234 * then enter the TIME-WAIT state, otherwise ignore
2235 * the segment.
2236 */
2237 case TCPS_CLOSING:
2238 if (ourfinisacked) {
2239 KASSERT(headlocked, ("headlocked"));

--- 195 unchanged lines hidden (view full) ---

2435 if (tp->t_flags & TF_NEEDSYN)
2436 tp->t_flags |= TF_DELACK;
2437 else
2438 tp->t_flags |= TF_ACKNOW;
2439 tp->rcv_nxt++;
2440 }
2441 switch (tp->t_state) {
2442
2232 * In CLOSING STATE in addition to the processing for
2233 * the ESTABLISHED state if the ACK acknowledges our FIN
2234 * then enter the TIME-WAIT state, otherwise ignore
2235 * the segment.
2236 */
2237 case TCPS_CLOSING:
2238 if (ourfinisacked) {
2239 KASSERT(headlocked, ("headlocked"));

--- 195 unchanged lines hidden (view full) ---

2435 if (tp->t_flags & TF_NEEDSYN)
2436 tp->t_flags |= TF_DELACK;
2437 else
2438 tp->t_flags |= TF_ACKNOW;
2439 tp->rcv_nxt++;
2440 }
2441 switch (tp->t_state) {
2442
2443 /*
2443 /*
2444 * In SYN_RECEIVED and ESTABLISHED STATES
2445 * enter the CLOSE_WAIT state.
2446 */
2447 case TCPS_SYN_RECEIVED:
2448 tp->t_starttime = ticks;
2449 /*FALLTHROUGH*/
2450 case TCPS_ESTABLISHED:
2451 tp->t_state = TCPS_CLOSE_WAIT;
2452 break;
2453
2444 * In SYN_RECEIVED and ESTABLISHED STATES
2445 * enter the CLOSE_WAIT state.
2446 */
2447 case TCPS_SYN_RECEIVED:
2448 tp->t_starttime = ticks;
2449 /*FALLTHROUGH*/
2450 case TCPS_ESTABLISHED:
2451 tp->t_state = TCPS_CLOSE_WAIT;
2452 break;
2453
2454 /*
2454 /*
2455 * If still in FIN_WAIT_1 STATE FIN has not been acked so
2456 * enter the CLOSING state.
2457 */
2458 case TCPS_FIN_WAIT_1:
2459 tp->t_state = TCPS_CLOSING;
2460 break;
2461
2455 * If still in FIN_WAIT_1 STATE FIN has not been acked so
2456 * enter the CLOSING state.
2457 */
2458 case TCPS_FIN_WAIT_1:
2459 tp->t_state = TCPS_CLOSING;
2460 break;
2461
2462 /*
2462 /*
2463 * In FIN_WAIT_2 state enter the TIME_WAIT state,
2464 * starting the time-wait timer, turning off the other
2465 * standard timers.
2466 */
2467 case TCPS_FIN_WAIT_2:
2468 KASSERT(headlocked == 1, ("headlocked should be 1"));
2469 tcp_twstart(tp);
2470 INP_INFO_WUNLOCK(&tcbinfo);

--- 21 unchanged lines hidden (view full) ---

2492 */
2493 if (needoutput || (tp->t_flags & TF_ACKNOW))
2494 (void) tcp_output(tp);
2495
2496check_delack:
2497 INP_LOCK_ASSERT(inp);
2498 if (tp->t_flags & TF_DELACK) {
2499 tp->t_flags &= ~TF_DELACK;
2463 * In FIN_WAIT_2 state enter the TIME_WAIT state,
2464 * starting the time-wait timer, turning off the other
2465 * standard timers.
2466 */
2467 case TCPS_FIN_WAIT_2:
2468 KASSERT(headlocked == 1, ("headlocked should be 1"));
2469 tcp_twstart(tp);
2470 INP_INFO_WUNLOCK(&tcbinfo);

--- 21 unchanged lines hidden (view full) ---

2492 */
2493 if (needoutput || (tp->t_flags & TF_ACKNOW))
2494 (void) tcp_output(tp);
2495
2496check_delack:
2497 INP_LOCK_ASSERT(inp);
2498 if (tp->t_flags & TF_DELACK) {
2499 tp->t_flags &= ~TF_DELACK;
2500 callout_reset(tp->tt_delack, tcp_delacktime,
2501 tcp_timer_delack, tp);
2500 callout_reset(tp->tt_delack, tcp_delacktime,
2501 tcp_timer_delack, tp);
2502 }
2503 INP_UNLOCK(inp);
2504 return;
2505
2506dropafterack:
2507 /*
2508 * Generate an ACK dropping incoming segment if it occupies
2509 * sequence space, where the ACK reflects our state.

--- 38 unchanged lines hidden (view full) ---

2548 goto drop;
2549 if (isipv6) {
2550 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
2551 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
2552 goto drop;
2553 } else {
2554 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
2555 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
2502 }
2503 INP_UNLOCK(inp);
2504 return;
2505
2506dropafterack:
2507 /*
2508 * Generate an ACK dropping incoming segment if it occupies
2509 * sequence space, where the ACK reflects our state.

--- 38 unchanged lines hidden (view full) ---

2548 goto drop;
2549 if (isipv6) {
2550 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
2551 IN6_IS_ADDR_MULTICAST(&ip6->ip6_src))
2552 goto drop;
2553 } else {
2554 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
2555 IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
2556 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) ||
2557 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
2556 ip->ip_src.s_addr == htonl(INADDR_BROADCAST) ||
2557 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
2558 goto drop;
2559 }
2560 /* IPv6 anycast check is done at tcp6_input() */
2561
2562 /*
2563 * Perform bandwidth limiting.
2564 */
2565 if (badport_bandlim(rstreason) < 0)
2566 goto drop;
2558 goto drop;
2559 }
2560 /* IPv6 anycast check is done at tcp6_input() */
2561
2562 /*
2563 * Perform bandwidth limiting.
2564 */
2565 if (badport_bandlim(rstreason) < 0)
2566 goto drop;
2567
2567
2568#ifdef TCPDEBUG
2569 if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
2570 tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen,
2571 &tcp_savetcp, 0);
2572#endif
2573
2574 if (thflags & TH_ACK)
2575 /* mtod() below is safe as long as hdr dropping is delayed */

--- 129 unchanged lines hidden (view full) ---

2705 to->to_flags |= (TOF_SIGNATURE | TOF_SIGLEN);
2706 break;
2707#endif
2708 case TCPOPT_SACK_PERMITTED:
2709 if (!tcp_do_sack ||
2710 optlen != TCPOLEN_SACK_PERMITTED)
2711 continue;
2712 if (is_syn) {
2568#ifdef TCPDEBUG
2569 if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
2570 tcp_trace(TA_DROP, ostate, tp, (void *)tcp_saveipgen,
2571 &tcp_savetcp, 0);
2572#endif
2573
2574 if (thflags & TH_ACK)
2575 /* mtod() below is safe as long as hdr dropping is delayed */

--- 129 unchanged lines hidden (view full) ---

2705 to->to_flags |= (TOF_SIGNATURE | TOF_SIGLEN);
2706 break;
2707#endif
2708 case TCPOPT_SACK_PERMITTED:
2709 if (!tcp_do_sack ||
2710 optlen != TCPOLEN_SACK_PERMITTED)
2711 continue;
2712 if (is_syn) {
2713 /* MUST only be set on SYN */
2713 /* MUST only be set on SYN */
2714 to->to_flags |= TOF_SACK;
2715 }
2716 break;
2717
2718 case TCPOPT_SACK:
2719 if (!tp || tcp_sack_option(tp, th, cp, optlen))
2720 continue;
2721 break;

--- 272 unchanged lines hidden (view full) ---

2994 */
2995 tp->t_maxopd = mss;
2996
2997 /*
2998 * In case of T/TCP, origoffer==-1 indicates, that no segments
2999 * were received yet. In this case we just guess, otherwise
3000 * we do the same as before T/TCP.
3001 */
2714 to->to_flags |= TOF_SACK;
2715 }
2716 break;
2717
2718 case TCPOPT_SACK:
2719 if (!tp || tcp_sack_option(tp, th, cp, optlen))
2720 continue;
2721 break;

--- 272 unchanged lines hidden (view full) ---

2994 */
2995 tp->t_maxopd = mss;
2996
2997 /*
2998 * In case of T/TCP, origoffer==-1 indicates, that no segments
2999 * were received yet. In this case we just guess, otherwise
3000 * we do the same as before T/TCP.
3001 */
3002 if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
3002 if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
3003 (origoffer == -1 ||
3004 (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
3005 mss -= TCPOLEN_TSTAMP_APPA;
3003 (origoffer == -1 ||
3004 (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP))
3005 mss -= TCPOLEN_TSTAMP_APPA;
3006 if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
3006 if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC &&
3007 (origoffer == -1 ||
3008 (tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC))
3009 mss -= TCPOLEN_CC_APPA;
3010 tp->t_maxseg = mss;
3011
3012#if (MCLBYTES & (MCLBYTES - 1)) == 0
3013 if (mss > MCLBYTES)
3014 mss &= ~(MCLBYTES-1);

--- 182 unchanged lines hidden (view full) ---

3197 */
3198 tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
3199}
3200
3201/*
3202 * Returns 1 if the TIME_WAIT state was killed and we should start over,
3203 * looking for a pcb in the listen state. Returns 0 otherwise.
3204 */
3007 (origoffer == -1 ||
3008 (tp->t_flags & TF_RCVD_CC) == TF_RCVD_CC))
3009 mss -= TCPOLEN_CC_APPA;
3010 tp->t_maxseg = mss;
3011
3012#if (MCLBYTES & (MCLBYTES - 1)) == 0
3013 if (mss > MCLBYTES)
3014 mss &= ~(MCLBYTES-1);

--- 182 unchanged lines hidden (view full) ---

3197 */
3198 tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
3199}
3200
3201/*
3202 * Returns 1 if the TIME_WAIT state was killed and we should start over,
3203 * looking for a pcb in the listen state. Returns 0 otherwise.
3204 */
3205static int
3205static int
3206tcp_timewait(tw, to, th, m, tlen)
3207 struct tcptw *tw;
3208 struct tcpopt *to;
3209 struct tcphdr *th;
3210 struct mbuf *m;
3211 int tlen;
3212{
3213 int thflags;

--- 16 unchanged lines hidden (view full) ---

3230 * Drop the segment - see Stevens, vol. 2, p. 964 and
3231 * RFC 1337.
3232 */
3233 if (thflags & TH_RST)
3234 goto drop;
3235
3236 /*
3237 * If segment contains a SYN and CC [not CC.NEW] option:
3206tcp_timewait(tw, to, th, m, tlen)
3207 struct tcptw *tw;
3208 struct tcpopt *to;
3209 struct tcphdr *th;
3210 struct mbuf *m;
3211 int tlen;
3212{
3213 int thflags;

--- 16 unchanged lines hidden (view full) ---

3230 * Drop the segment - see Stevens, vol. 2, p. 964 and
3231 * RFC 1337.
3232 */
3233 if (thflags & TH_RST)
3234 goto drop;
3235
3236 /*
3237 * If segment contains a SYN and CC [not CC.NEW] option:
3238 * if connection duration > MSL, drop packet and send RST;
3238 * if connection duration > MSL, drop packet and send RST;
3239 *
3240 * if SEG.CC > CCrecv then is new SYN.
3241 * Complete close and delete TCPCB. Then reprocess
3242 * segment, hoping to find new TCPCB in LISTEN state;
3243 *
3244 * else must be old SYN; drop it.
3245 * else do normal processing.
3246 */

--- 48 unchanged lines hidden (view full) ---

3295 seq = th->th_seq + tlen + (thflags & TH_SYN ? 1 : 0);
3296 if (seq + 1 == tw->rcv_nxt)
3297 tcp_timer_2msl_reset(tw, 2 * tcp_msl);
3298 }
3299
3300 /*
3301 * Acknowledge the segment if it has data or is not a duplicate ACK.
3302 */
3239 *
3240 * if SEG.CC > CCrecv then is new SYN.
3241 * Complete close and delete TCPCB. Then reprocess
3242 * segment, hoping to find new TCPCB in LISTEN state;
3243 *
3244 * else must be old SYN; drop it.
3245 * else do normal processing.
3246 */

--- 48 unchanged lines hidden (view full) ---

3295 seq = th->th_seq + tlen + (thflags & TH_SYN ? 1 : 0);
3296 if (seq + 1 == tw->rcv_nxt)
3297 tcp_timer_2msl_reset(tw, 2 * tcp_msl);
3298 }
3299
3300 /*
3301 * Acknowledge the segment if it has data or is not a duplicate ACK.
3302 */
3303 if (thflags != TH_ACK || tlen != 0 ||
3303 if (thflags != TH_ACK || tlen != 0 ||
3304 th->th_seq != tw->rcv_nxt || th->th_ack != tw->snd_nxt)
3305 tcp_twrespond(tw, TH_ACK);
3306 goto drop;
3307
3308reset:
3309 /*
3310 * Generate a RST, dropping incoming segment.
3311 * Make ACK acceptable to originator of segment.

--- 38 unchanged lines hidden ---
3304 th->th_seq != tw->rcv_nxt || th->th_ack != tw->snd_nxt)
3305 tcp_twrespond(tw, TH_ACK);
3306 goto drop;
3307
3308reset:
3309 /*
3310 * Generate a RST, dropping incoming segment.
3311 * Make ACK acceptable to originator of segment.

--- 38 unchanged lines hidden ---