diff options
Diffstat (limited to 'freebsd/sys/netinet/tcp_timewait.c')
-rw-r--r-- | freebsd/sys/netinet/tcp_timewait.c | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/freebsd/sys/netinet/tcp_timewait.c b/freebsd/sys/netinet/tcp_timewait.c index f9b613a7..9034fab4 100644 --- a/freebsd/sys/netinet/tcp_timewait.c +++ b/freebsd/sys/netinet/tcp_timewait.c @@ -59,23 +59,19 @@ __FBSDID("$FreeBSD$"); #include <net/vnet.h> #include <netinet/in.h> +#include <netinet/in_pcb.h> #include <netinet/in_systm.h> +#include <netinet/in_var.h> #include <netinet/ip.h> +#include <netinet/ip_icmp.h> +#include <netinet/ip_var.h> #ifdef INET6 #include <netinet/ip6.h> -#endif -#include <netinet/in_pcb.h> -#ifdef INET6 #include <netinet6/in6_pcb.h> -#endif -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#ifdef INET6 #include <netinet6/ip6_var.h> #include <netinet6/scope6_var.h> #include <netinet6/nd6.h> #endif -#include <netinet/ip_icmp.h> #include <netinet/tcp.h> #include <netinet/tcp_fsm.h> #include <netinet/tcp_seq.h> @@ -88,7 +84,9 @@ __FBSDID("$FreeBSD$"); #ifdef TCPDEBUG #include <netinet/tcp_debug.h> #endif +#ifdef INET6 #include <netinet6/ip6protosw.h> +#endif #include <machine/in_cksum.h> @@ -204,15 +202,31 @@ tcp_twstart(struct tcpcb *tp) struct inpcb *inp = tp->t_inpcb; int acknow; struct socket *so; +#ifdef INET6 + int isipv6 = inp->inp_inc.inc_flags & INC_ISIPV6; +#endif INP_INFO_WLOCK_ASSERT(&V_tcbinfo); /* tcp_tw_2msl_reset(). */ INP_WLOCK_ASSERT(inp); - if (V_nolocaltimewait && in_localip(inp->inp_faddr)) { - tp = tcp_close(tp); - if (tp != NULL) - INP_WUNLOCK(inp); - return; + if (V_nolocaltimewait) { + int error = 0; +#ifdef INET6 + if (isipv6) + error = in6_localaddr(&inp->in6p_faddr); +#endif +#if defined(INET6) && defined(INET) + else +#endif +#ifdef INET + error = in_localip(inp->inp_faddr); +#endif + if (error) { + tp = tcp_close(tp); + if (tp != NULL) + INP_WUNLOCK(inp); + return; + } } tw = uma_zalloc(V_tcptw_zone, M_NOWAIT); @@ -493,16 +507,21 @@ int tcp_twrespond(struct tcptw *tw, int flags) { struct inpcb *inp = tw->tw_inpcb; - struct tcphdr *th; +#if defined(INET6) || defined(INET) + struct tcphdr *th = NULL; +#endif struct mbuf *m; +#ifdef INET struct ip *ip = NULL; +#endif u_int hdrlen, optlen; - int error; + int error = 0; /* Keep compiler happy */ struct tcpopt to; #ifdef INET6 struct ip6_hdr *ip6 = NULL; int isipv6 = inp->inp_inc.inc_flags & INC_ISIPV6; #endif + hdrlen = 0; /* Keep compiler happy */ INP_WLOCK_ASSERT(inp); @@ -521,14 +540,19 @@ tcp_twrespond(struct tcptw *tw, int flags) ip6 = mtod(m, struct ip6_hdr *); th = (struct tcphdr *)(ip6 + 1); tcpip_fillheaders(inp, ip6, th); - } else + } #endif +#if defined(INET6) && defined(INET) + else +#endif +#ifdef INET { hdrlen = sizeof(struct tcpiphdr); ip = mtod(m, struct ip *); th = (struct tcphdr *)(ip + 1); tcpip_fillheaders(inp, ip, th); } +#endif to.to_flags = 0; /* @@ -553,20 +577,25 @@ tcp_twrespond(struct tcptw *tw, int flags) th->th_flags = flags; th->th_win = htons(tw->last_win); + m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); #ifdef INET6 if (isipv6) { - th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(struct ip6_hdr), - sizeof(struct tcphdr) + optlen); + m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; + th->th_sum = in6_cksum_pseudo(ip6, + sizeof(struct tcphdr) + optlen, IPPROTO_TCP, 0); ip6->ip6_hlim = in6_selecthlim(inp, NULL); error = ip6_output(m, inp->in6p_outputopts, NULL, (tw->tw_so_options & SO_DONTROUTE), NULL, NULL, inp); - } else + } #endif +#if defined(INET6) && defined(INET) + else +#endif +#ifdef INET { + m->m_pkthdr.csum_flags = CSUM_TCP; th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(sizeof(struct tcphdr) + optlen + IPPROTO_TCP)); - m->m_pkthdr.csum_flags = CSUM_TCP; - m->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); ip->ip_len = m->m_pkthdr.len; if (V_path_mtu_discovery) ip->ip_off |= IP_DF; @@ -574,6 +603,7 @@ tcp_twrespond(struct tcptw *tw, int flags) ((tw->tw_so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), NULL, inp); } +#endif if (flags & TH_ACK) TCPSTAT_INC(tcps_sndacks); else |