Index: sys/netinet/tcp_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v retrieving revision 1.305 diff -u -p -r1.305 tcp_input.c --- sys/netinet/tcp_input.c 26 May 2010 17:38:29 -0000 1.305 +++ sys/netinet/tcp_input.c 24 Nov 2010 12:56:57 -0000 @@ -2277,10 +2277,11 @@ after_listen: */ if (tiflags & TH_SYN) { if (tp->rcv_nxt == th->th_seq) { - tcp_respond(tp, m, m, th, (tcp_seq)0, th->th_ack - 1, - TH_ACK); + tcp_respond(tp, mtod(m, void *), th, + (tcp_seq)0, th->th_ack - 1, TH_ACK); if (tcp_saveti) m_freem(tcp_saveti); + m_freem(m); return; } @@ -2820,15 +2821,17 @@ dropwithreset: } if (tiflags & TH_ACK) - (void)tcp_respond(tp, m, m, th, (tcp_seq)0, th->th_ack, TH_RST); + (void)tcp_respond(tp, mtod(m, void *), th, + (tcp_seq)0, th->th_ack, TH_RST); else { if (tiflags & TH_SYN) tlen++; - (void)tcp_respond(tp, m, m, th, th->th_seq + tlen, (tcp_seq)0, - TH_RST|TH_ACK); + (void)tcp_respond(tp, mtod(m, void *), th, + th->th_seq + tlen, (tcp_seq)0, TH_RST|TH_ACK); } if (tcp_saveti) m_freem(tcp_saveti); + m_freem(m); return; badcsum: @@ -3917,7 +3920,8 @@ syn_cache_get(struct sockaddr *src, stru return (so); resetandabort: - (void)tcp_respond(NULL, m, m, th, (tcp_seq)0, th->th_ack, TH_RST); + (void)tcp_respond(NULL, mtod(m, void *), th, + (tcp_seq)0, th->th_ack, TH_RST); abort: if (so != NULL) { (void) soqremque(so, 1); Index: sys/netinet/tcp_subr.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_subr.c,v retrieving revision 1.238 diff -u -p -r1.238 tcp_subr.c --- sys/netinet/tcp_subr.c 16 Sep 2009 15:23:05 -0000 1.238 +++ sys/netinet/tcp_subr.c 24 Nov 2010 12:56:57 -0000 @@ -600,12 +600,13 @@ tcp_template(struct tcpcb *tp) * segment are as specified by the parameters. */ int -tcp_respond(struct tcpcb *tp, struct mbuf *template, struct mbuf *m, +tcp_respond(struct tcpcb *tp, void *template, struct tcphdr *th0, tcp_seq ack, tcp_seq seq, int flags) { #ifdef INET6 struct rtentry *rt; #endif + struct mbuf *m = NULL; struct route *ro; int error, tlen, win = 0; int hlen; @@ -637,172 +638,64 @@ tcp_respond(struct tcpcb *tp, struct mbu #ifdef INET6 ip6 = NULL; #endif - if (m == 0) { - if (!template) - return EINVAL; - - /* get family information from template */ - switch (mtod(template, struct ip *)->ip_v) { - case 4: - family = AF_INET; - hlen = sizeof(struct ip); - break; -#ifdef INET6 - case 6: - family = AF_INET6; - hlen = sizeof(struct ip6_hdr); - break; -#endif - default: - return EAFNOSUPPORT; - } - - MGETHDR(m, M_DONTWAIT, MT_HEADER); - if (m) { - MCLAIM(m, &tcp_tx_mowner); - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_free(m); - m = NULL; - } - } - if (m == NULL) - return (ENOBUFS); - - if (tcp_compat_42) - tlen = 1; - else - tlen = 0; + if (!template) + return EINVAL; - m->m_data += max_linkhdr; - bcopy(mtod(template, void *), mtod(m, void *), - template->m_len); - switch (family) { - case AF_INET: - ip = mtod(m, struct ip *); - th = (struct tcphdr *)(ip + 1); - break; + /* get family information from template */ + switch (((struct ip *)(template))->ip_v) { + case 4: + family = AF_INET; + hlen = sizeof(struct ip); + break; #ifdef INET6 - case AF_INET6: - ip6 = mtod(m, struct ip6_hdr *); - th = (struct tcphdr *)(ip6 + 1); - break; -#endif -#if 0 - default: - /* noone will visit here */ - m_freem(m); - return EAFNOSUPPORT; -#endif - } - flags = TH_ACK; - } else { - - if ((m->m_flags & M_PKTHDR) == 0) { -#if 0 - printf("non PKTHDR to tcp_respond\n"); -#endif - m_freem(m); - return EINVAL; - } -#ifdef DIAGNOSTIC - if (!th0) - panic("th0 == NULL in tcp_respond"); + case 6: + family = AF_INET6; + hlen = sizeof(struct ip6_hdr); + break; #endif + default: + return EAFNOSUPPORT; + } - /* get family information from m */ - switch (mtod(m, struct ip *)->ip_v) { - case 4: - family = AF_INET; - hlen = sizeof(struct ip); - ip = mtod(m, struct ip *); - break; -#ifdef INET6 - case 6: - family = AF_INET6; - hlen = sizeof(struct ip6_hdr); - ip6 = mtod(m, struct ip6_hdr *); - break; -#endif - default: - m_freem(m); - return EAFNOSUPPORT; + MGETHDR(m, M_DONTWAIT, MT_HEADER); + if (m) { + MCLAIM(m, &tcp_tx_mowner); + MCLGET(m, M_DONTWAIT); + if ((m->m_flags & M_EXT) == 0) { + m_free(m); + m = NULL; } - /* clear h/w csum flags inherited from rx packet */ - m->m_pkthdr.csum_flags = 0; - - if ((flags & TH_SYN) == 0 || sizeof(*th0) > (th0->th_off << 2)) - tlen = sizeof(*th0); - else - tlen = th0->th_off << 2; - - if (m->m_len > hlen + tlen && (m->m_flags & M_EXT) == 0 && - mtod(m, char *) + hlen == (char *)th0) { - m->m_len = hlen + tlen; - m_freem(m->m_next); - m->m_next = NULL; - } else { - struct mbuf *n; - -#ifdef DIAGNOSTIC - if (max_linkhdr + hlen + tlen > MCLBYTES) { - m_freem(m); - return EMSGSIZE; - } -#endif - MGETHDR(n, M_DONTWAIT, MT_HEADER); - if (n && max_linkhdr + hlen + tlen > MHLEN) { - MCLGET(n, M_DONTWAIT); - if ((n->m_flags & M_EXT) == 0) { - m_freem(n); - n = NULL; - } - } - if (!n) { - m_freem(m); - return ENOBUFS; - } + } + if (m == NULL) + return (ENOBUFS); - MCLAIM(n, &tcp_tx_mowner); - n->m_data += max_linkhdr; - n->m_len = hlen + tlen; - m_copyback(n, 0, hlen, mtod(m, void *)); - m_copyback(n, hlen, tlen, (void *)th0); - - m_freem(m); - m = n; - n = NULL; - } + if (tcp_compat_42) + tlen = 1; + else + tlen = 0; -#define xchg(a,b,type) { type t; t=a; a=b; b=t; } - switch (family) { - case AF_INET: - ip = mtod(m, struct ip *); - th = (struct tcphdr *)(ip + 1); - ip->ip_p = IPPROTO_TCP; - xchg(ip->ip_dst, ip->ip_src, struct in_addr); - ip->ip_p = IPPROTO_TCP; - break; + m->m_data += max_linkhdr; + switch (family) { + case AF_INET: + ip = mtod(m, struct ip *); + th = (struct tcphdr *)(ip + 1); + memcpy(ip, template, sizeof(*ip)); + break; #ifdef INET6 - case AF_INET6: - ip6 = mtod(m, struct ip6_hdr *); - th = (struct tcphdr *)(ip6 + 1); - ip6->ip6_nxt = IPPROTO_TCP; - xchg(ip6->ip6_dst, ip6->ip6_src, struct in6_addr); - ip6->ip6_nxt = IPPROTO_TCP; - break; + case AF_INET6: + ip6 = mtod(m, struct ip6_hdr *); + th = (struct tcphdr *)(ip6 + 1); + memcpy(ip6, template, sizeof(*ip6)); + break; #endif #if 0 - default: - /* noone will visit here */ - m_freem(m); - return EAFNOSUPPORT; + default: + /* noone will visit here */ + m_freem(m); + return EAFNOSUPPORT; #endif - } - xchg(th->th_dport, th->th_sport, u_int16_t); -#undef xchg - tlen = 0; /*be friendly with the following code*/ } + flags = TH_ACK; th->th_seq = htonl(seq); th->th_ack = htonl(ack); th->th_x2 = 0; Index: sys/netinet/tcp_timer.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_timer.c,v retrieving revision 1.84 diff -u -p -r1.84 tcp_timer.c --- sys/netinet/tcp_timer.c 10 Nov 2008 01:06:43 -0000 1.84 +++ sys/netinet/tcp_timer.c 24 Nov 2010 12:56:57 -0000 @@ -559,13 +559,11 @@ tcp_timer_keep(void *arg) * The keepalive packet must have nonzero * length to get a 4.2 host to respond. */ - (void)tcp_respond(tp, tp->t_template, - (struct mbuf *)NULL, NULL, tp->rcv_nxt - 1, - tp->snd_una - 1, 0); + (void)tcp_respond(tp, mtod(tp->t_template, void *), + NULL, tp->rcv_nxt - 1, tp->snd_una - 1, 0); } else { - (void)tcp_respond(tp, tp->t_template, - (struct mbuf *)NULL, NULL, tp->rcv_nxt, - tp->snd_una - 1, 0); + (void)tcp_respond(tp, mtod(tp->t_template, void *), + NULL, tp->rcv_nxt, tp->snd_una - 1, 0); } TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepintvl); } else Index: sys/netinet/tcp_var.h =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_var.h,v retrieving revision 1.162 diff -u -p -r1.162 tcp_var.h --- sys/netinet/tcp_var.h 16 Sep 2009 15:23:05 -0000 1.162 +++ sys/netinet/tcp_var.h 24 Nov 2010 12:56:57 -0000 @@ -867,7 +867,7 @@ void tcpipqent_init(void); struct ipqent *tcpipqent_alloc(void); void tcpipqent_free(struct ipqent *); -int tcp_respond(struct tcpcb *, struct mbuf *, struct mbuf *, +int tcp_respond(struct tcpcb *, void *, struct tcphdr *, tcp_seq, tcp_seq, int); void tcp_rmx_rtt(struct tcpcb *); void tcp_setpersist(struct tcpcb *);