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 --- |