|
|
| version 1.20, 2004/03/09 21:21:54 | version 1.21, 2004/03/21 07:15:36 |
|---|---|
| Line 108 SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STAT | Line 108 SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STAT |
| &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); | &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); |
| static int log_in_vain = 0; | static int log_in_vain = 0; |
| SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, |
| &log_in_vain, 0, "Log all incoming TCP connections"); | &log_in_vain, 0, "Log all incoming TCP connections"); |
| static int blackhole = 0; | static int blackhole = 0; |
| Line 116 SYSCTL_INT(_net_inet_tcp, OID_AUTO, blac | Line 116 SYSCTL_INT(_net_inet_tcp, OID_AUTO, blac |
| &blackhole, 0, "Do not send RST when dropping refused connections"); | &blackhole, 0, "Do not send RST when dropping refused connections"); |
| int tcp_delack_enabled = 1; | int tcp_delack_enabled = 1; |
| SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, | SYSCTL_INT(_net_inet_tcp, OID_AUTO, delayed_ack, CTLFLAG_RW, |
| &tcp_delack_enabled, 0, | &tcp_delack_enabled, 0, |
| "Delay ACK to try and piggyback it onto a data packet"); | "Delay ACK to try and piggyback it onto a data packet"); |
| #ifdef TCP_DROP_SYNFIN | #ifdef TCP_DROP_SYNFIN |
| Line 364 tcp6_input(mp, offp, proto) | Line 364 tcp6_input(mp, offp, proto) |
| * better place to put this in? | * better place to put this in? |
| */ | */ |
| ia6 = ip6_getdstifaddr(m); | ia6 = ip6_getdstifaddr(m); |
| if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) { | if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) { |
| struct ip6_hdr *ip6; | struct ip6_hdr *ip6; |
| ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); |
| icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, | icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, |
| (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); | (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); |
| return IPPROTO_DONE; | return (IPPROTO_DONE); |
| } | } |
| tcp_input(m, *offp, proto); | tcp_input(m, *offp, proto); |
| return IPPROTO_DONE; | return (IPPROTO_DONE); |
| } | } |
| #endif | #endif |
| Line 404 tcp_input(m, off0, proto) | Line 404 tcp_input(m, off0, proto) |
| int cpu; | int cpu; |
| struct ip6_hdr *ip6 = NULL; | struct ip6_hdr *ip6 = NULL; |
| #ifdef INET6 | #ifdef INET6 |
| int isipv6; | boolean_t isipv6; |
| #else | #else |
| const int isipv6 = 0; | const boolean_t isipv6 = FALSE; |
| #endif | #endif |
| #ifdef TCPDEBUG | #ifdef TCPDEBUG |
| short ostate = 0; | short ostate = 0; |
| #endif | #endif |
| /* Grab info from MT_TAG mbufs prepended to the chain. */ | tcpstat.tcps_rcvtotal++; |
| for (;m && m->m_type == MT_TAG; m = m->m_next) { | |
| /* Grab info from and strip MT_TAG mbufs prepended to the chain. */ | |
| while (m->m_type == MT_TAG) { | |
| if (m->_m_tag_id == PACKET_TAG_IPFORWARD) | if (m->_m_tag_id == PACKET_TAG_IPFORWARD) |
| next_hop = (struct sockaddr_in *)m->m_hdr.mh_data; | next_hop = (struct sockaddr_in *)m->m_hdr.mh_data; |
| m = m->m_next; | |
| } | } |
| #ifdef INET6 | #ifdef INET6 |
| isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; | isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? TRUE : FALSE; |
| #endif | #endif |
| bzero((char *)&to, sizeof(to)); | |
| tcpstat.tcps_rcvtotal++; | |
| if (isipv6) { | if (isipv6) { |
| /* IP6_EXTHDR_CHECK() is already done at tcp6_input() */ | /* IP6_EXTHDR_CHECK() is already done at tcp6_input() */ |
| Line 549 tcp_input(m, off0, proto) | Line 550 tcp_input(m, off0, proto) |
| th->th_urp = ntohs(th->th_urp); | th->th_urp = ntohs(th->th_urp); |
| /* | /* |
| * Delay droping TCP, IP headers, IPv6 ext headers, and TCP options, | * Delay dropping TCP, IP headers, IPv6 ext headers, and TCP options, |
| * until after ip6_savecontrol() is called and before other functions | * until after ip6_savecontrol() is called and before other functions |
| * which don't want those proto headers. | * which don't want those proto headers. |
| * Because ip6_savecontrol() is going to parse the mbuf to | * Because ip6_savecontrol() is going to parse the mbuf to |
| Line 565 tcp_input(m, off0, proto) | Line 566 tcp_input(m, off0, proto) |
| */ | */ |
| findpcb: | findpcb: |
| /* IPFIREWALL_FORWARD section */ | /* IPFIREWALL_FORWARD section */ |
| if (next_hop != NULL && isipv6 == 0) { /* IPv6 support is not yet */ | if (next_hop != NULL && !isipv6) { /* IPv6 support is not there yet */ |
| /* | /* |
| * Transparently forwarded. Pretend to be the destination. | * Transparently forwarded. Pretend to be the destination. |
| * already got one like this? | * already got one like this? |
| */ | */ |
| inp = in_pcblookup_hash(&tcbinfo[mycpu->gd_cpuid], | inp = in_pcblookup_hash(&tcbinfo[mycpu->gd_cpuid], |
| ip->ip_src, th->th_sport, | ip->ip_src, th->th_sport, |
| Line 644 findpcb: | Line 645 findpcb: |
| #ifdef INET6 | #ifdef INET6 |
| char dbuf[INET6_ADDRSTRLEN+2], sbuf[INET6_ADDRSTRLEN+2]; | char dbuf[INET6_ADDRSTRLEN+2], sbuf[INET6_ADDRSTRLEN+2]; |
| #else | #else |
| char dbuf[4*sizeof "123"], sbuf[4*sizeof "123"]; | char dbuf[4 * sizeof "123"], sbuf[4 * sizeof "123"]; |
| #endif | #endif |
| if (isipv6) { | if (isipv6) { |
| strcpy(dbuf, "["); | strcpy(dbuf, "["); |
| Line 672 findpcb: | Line 673 findpcb: |
| break; | break; |
| } | } |
| } | } |
| if (blackhole) { | if (blackhole) { |
| switch (blackhole) { | switch (blackhole) { |
| case 1: | case 1: |
| if (thflags & TH_SYN) | if (thflags & TH_SYN) |
| Line 714 findpcb: | Line 715 findpcb: |
| } | } |
| #endif | #endif |
| bzero((char *)&to, sizeof(to)); | |
| if (so->so_options & SO_ACCEPTCONN) { | if (so->so_options & SO_ACCEPTCONN) { |
| struct in_conninfo inc; | struct in_conninfo inc; |
| #ifdef INET6 | #ifdef INET6 |
| inc.inc_isipv6 = isipv6; | inc.inc_isipv6 = (isipv6 == TRUE); |
| #endif | #endif |
| if (isipv6) { | if (isipv6) { |
| inc.inc6_faddr = ip6->ip6_src; | inc.inc6_faddr = ip6->ip6_src; |
| Line 780 findpcb: | Line 783 findpcb: |
| * rcv SYN (set wscale opts) --> send SYN/ACK, set snd_wnd = window. | * rcv SYN (set wscale opts) --> send SYN/ACK, set snd_wnd = window. |
| * rcv ACK, calculate tiwin --> process SYN_RECEIVED, determine wscale, | * rcv ACK, calculate tiwin --> process SYN_RECEIVED, determine wscale, |
| * move to ESTAB, set snd_wnd to tiwin. | * move to ESTAB, set snd_wnd to tiwin. |
| */ | */ |
| tp->snd_wnd = tiwin; /* unscaled */ | tp->snd_wnd = tiwin; /* unscaled */ |
| goto after_listen; | goto after_listen; |
| } | } |
| Line 911 findpcb: | Line 914 findpcb: |
| (tlen != 0 && | (tlen != 0 && |
| ((isipv6 && in6_localaddr(&inp->in6p_faddr)) || | ((isipv6 && in6_localaddr(&inp->in6p_faddr)) || |
| (!isipv6 && in_localaddr(inp->inp_faddr)))))) { | (!isipv6 && in_localaddr(inp->inp_faddr)))))) { |
| callout_reset(tp->tt_delack, tcp_delacktime, | callout_reset(tp->tt_delack, tcp_delacktime, |
| tcp_timer_delack, tp); | tcp_timer_delack, tp); |
| tp->t_flags |= TF_NEEDSYN; | tp->t_flags |= TF_NEEDSYN; |
| } else | } else |
| tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN); | tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN); |
| tcpstat.tcps_connects++; | tcpstat.tcps_connects++; |
| Line 1041 after_listen: | Line 1044 after_listen: |
| /* | /* |
| * Recalculate the retransmit timer / rtt. | * Recalculate the retransmit timer / rtt. |
| * | * |
| * Some machines (certain windows boxes) | * Some machines (certain windows boxes) |
| * send broken timestamp replies during the | * send broken timestamp replies during the |
| * SYN+ACK phase, ignore timestamps of 0. | * SYN+ACK phase, ignore timestamps of 0. |
| */ | */ |
| Line 1079 after_listen: | Line 1082 after_listen: |
| if (tp->snd_una == tp->snd_max) | if (tp->snd_una == tp->snd_max) |
| callout_stop(tp->tt_rexmt); | callout_stop(tp->tt_rexmt); |
| else if (!callout_active(tp->tt_persist)) | else if (!callout_active(tp->tt_persist)) |
| callout_reset(tp->tt_rexmt, | callout_reset(tp->tt_rexmt, |
| tp->t_rxtcur, | tp->t_rxtcur, |
| tcp_timer_rexmt, tp); | tcp_timer_rexmt, tp); |
| Line 1238 after_listen: | Line 1241 after_listen: |
| * ACKNOW will be turned on later. | * ACKNOW will be turned on later. |
| */ | */ |
| if (DELAY_ACK(tp) && tlen != 0) | if (DELAY_ACK(tp) && tlen != 0) |
| callout_reset(tp->tt_delack, tcp_delacktime, | callout_reset(tp->tt_delack, tcp_delacktime, |
| tcp_timer_delack, tp); | tcp_timer_delack, tp); |
| else | else |
| tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; |
| /* | /* |
| Line 1678 trimthenstep6: | Line 1681 trimthenstep6: |
| tp->t_flags &= ~TF_NEEDFIN; | tp->t_flags &= ~TF_NEEDFIN; |
| } else { | } else { |
| tp->t_state = TCPS_ESTABLISHED; | tp->t_state = TCPS_ESTABLISHED; |
| callout_reset(tp->tt_keep, tcp_keepidle, | callout_reset(tp->tt_keep, tcp_keepidle, |
| tcp_timer_keep, tp); | tcp_timer_keep, tp); |
| } | } |
| /* | /* |
| Line 1932 process_ACK: | Line 1935 process_ACK: |
| * Recompute the initial retransmit timer. | * Recompute the initial retransmit timer. |
| * | * |
| * Some machines (certain windows boxes) send broken | * Some machines (certain windows boxes) send broken |
| * timestamp replies during the SYN+ACK phase, ignore | * timestamp replies during the SYN+ACK phase, ignore |
| * timestamps of 0. | * timestamps of 0. |
| */ | */ |
| if ((to.to_flags & TOF_TS) != 0 && | if ((to.to_flags & TOF_TS) != 0 && |
| Line 2232 dodata: /* XXX */ | Line 2235 dodata: /* XXX */ |
| * more input can be expected, send ACK now. | * more input can be expected, send ACK now. |
| */ | */ |
| if (DELAY_ACK(tp) && (tp->t_flags & TF_NEEDSYN)) | if (DELAY_ACK(tp) && (tp->t_flags & TF_NEEDSYN)) |
| callout_reset(tp->tt_delack, tcp_delacktime, | callout_reset(tp->tt_delack, tcp_delacktime, |
| tcp_timer_delack, tp); | tcp_timer_delack, tp); |
| else | else |
| tp->t_flags |= TF_ACKNOW; | tp->t_flags |= TF_ACKNOW; |
| tp->rcv_nxt++; | tp->rcv_nxt++; |
| Line 2644 tcp_mss(tp, offer) | Line 2647 tcp_mss(tp, offer) |
| struct rmxp_tao *taop; | struct rmxp_tao *taop; |
| int origoffer = offer; | int origoffer = offer; |
| #ifdef INET6 | #ifdef INET6 |
| int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; | boolean_t isipv6 = ((inp->inp_vflag & INP_IPV6) ? TRUE : FALSE); |
| size_t min_protoh = isipv6 ? | size_t min_protoh = isipv6 ? |
| sizeof(struct ip6_hdr) + sizeof(struct tcphdr) : | sizeof(struct ip6_hdr) + sizeof(struct tcphdr) : |
| sizeof(struct tcpiphdr); | sizeof(struct tcpiphdr); |
| #else | #else |
| const int isipv6 = 0; | const boolean_t isipv6 = FALSE; |
| const size_t min_protoh = sizeof(struct tcpiphdr); | const size_t min_protoh = sizeof(struct tcpiphdr); |
| #endif | #endif |
| Line 2659 tcp_mss(tp, offer) | Line 2662 tcp_mss(tp, offer) |
| rt = tcp_rtlookup(&inp->inp_inc); | rt = tcp_rtlookup(&inp->inp_inc); |
| if (rt == NULL) { | if (rt == NULL) { |
| tp->t_maxopd = tp->t_maxseg = | tp->t_maxopd = tp->t_maxseg = |
| isipv6 ? tcp_v6mssdflt : tcp_mssdflt; | (isipv6 ? tcp_v6mssdflt : tcp_mssdflt); |
| return; | return; |
| } | } |
| ifp = rt->rt_ifp; | ifp = rt->rt_ifp; |
| Line 2677 tcp_mss(tp, offer) | Line 2680 tcp_mss(tp, offer) |
| * in this case we use tcp_mssdflt. | * in this case we use tcp_mssdflt. |
| */ | */ |
| if (offer == 0) | if (offer == 0) |
| offer = isipv6 ? tcp_v6mssdflt : tcp_mssdflt; | offer = (isipv6 ? tcp_v6mssdflt : tcp_mssdflt); |
| else | else |
| /* | /* |
| * Sanity check: make sure that maxopd will be large | * Sanity check: make sure that maxopd will be large |
| Line 2831 tcp_mssopt(tp) | Line 2834 tcp_mssopt(tp) |
| { | { |
| struct rtentry *rt; | struct rtentry *rt; |
| #ifdef INET6 | #ifdef INET6 |
| int isipv6 = ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) ? 1 : 0; | boolean_t isipv6 = |
| ((tp->t_inpcb->inp_vflag & INP_IPV6) ? TRUE : FALSE); | |
| int min_protoh = isipv6 ? | int min_protoh = isipv6 ? |
| sizeof(struct ip6_hdr) + sizeof(struct tcphdr) : | sizeof(struct ip6_hdr) + sizeof(struct tcphdr) : |
| sizeof(struct tcpiphdr); | sizeof(struct tcpiphdr); |
| #else | #else |
| const int isipv6 = 0; | const boolean_t isipv6 = FALSE; |
| const size_t min_protoh = sizeof(struct tcpiphdr); | const size_t min_protoh = sizeof(struct tcpiphdr); |
| #endif | #endif |