Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet remove old mbuf assumption (ip header and tcp he...



details:   https://anonhg.NetBSD.org/src/rev/1b1549a8bac4
branches:  trunk
changeset: 494061:1b1549a8bac4
user:      itojun <itojun%NetBSD.org@localhost>
date:      Fri Jun 30 16:44:33 2000 +0000

description:
remove old mbuf assumption (ip header and tcp header are on the same mbuf).
this is for m_pulldown use. (sync with kame)

diffstat:

 sys/netinet/tcp_input.c  |  47 +++++++++++++++++++++--------
 sys/netinet/tcp_output.c |   4 +-
 sys/netinet/tcp_subr.c   |  75 ++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 100 insertions(+), 26 deletions(-)

diffs (243 lines):

diff -r 032298cd45b5 -r 1b1549a8bac4 sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c   Fri Jun 30 16:40:31 2000 +0000
+++ b/sys/netinet/tcp_input.c   Fri Jun 30 16:44:33 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_input.c,v 1.108 2000/05/05 15:05:29 matt Exp $     */
+/*     $NetBSD: tcp_input.c,v 1.109 2000/06/30 16:44:33 itojun Exp $   */
 
 /*
 %%% portions-copyright-nrl-95
@@ -1026,14 +1026,31 @@
 
                if (so->so_options & SO_DEBUG) {
                        ostate = tp->t_state;
-                       tcp_saveti = m_copym(m, 0, iphlen, M_DONTWAIT);
+
+                       tcp_saveti = NULL;
+                       if (iphlen + sizeof(struct tcphdr) > MHLEN)
+                               goto nosave;
+
+                       if (m->m_len > iphlen && (m->m_flags & M_EXT) == 0) {
+                               tcp_saveti = m_copym(m, 0, iphlen, M_DONTWAIT);
+                               if (!tcp_saveti)
+                                       goto nosave;
+                       } else {
+                               MGETHDR(tcp_saveti, M_DONTWAIT, MT_HEADER);
+                               if (!tcp_saveti)
+                                       goto nosave;
+                               tcp_saveti->m_len = iphlen;
+                               m_copydata(m, 0, iphlen,
+                                   mtod(tcp_saveti, caddr_t));
+                       }
+
                        if (M_TRAILINGSPACE(tcp_saveti) < sizeof(struct tcphdr)) {
                                m_freem(tcp_saveti);
                                tcp_saveti = NULL;
                        } else {
                                tcp_saveti->m_len += sizeof(struct tcphdr);
                                bcopy(th, mtod(tcp_saveti, caddr_t) + iphlen,
-                                       sizeof(struct tcphdr));
+                                   sizeof(struct tcphdr));
                        }
                        if (tcp_saveti) {
                                /*
@@ -1053,6 +1070,7 @@
 #endif
                                }
                        }
+       nosave:;
                }
                if (so->so_options & SO_ACCEPTCONN) {
                        if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
@@ -3346,18 +3364,20 @@
        tlen = hlen + sizeof(struct tcphdr) + optlen;
 
        /*
-        * Create the IP+TCP header from scratch.  Reuse the received mbuf
-        * if possible.
+        * Create the IP+TCP header from scratch.
         */
-       if (m != NULL) {
-               m_freem(m->m_next);
-               m->m_next = NULL;
-               MRESETDATA(m);
-       } else {
-               MGETHDR(m, M_DONTWAIT, MT_DATA);
-               if (m == NULL)
-                       return (ENOBUFS);
+       if (m)
+               m_freem(m);
+       MGETHDR(m, M_DONTWAIT, MT_DATA);
+       if (m && tlen > MHLEN) {
+               MCLGET(m, M_DONTWAIT);
+               if ((m->m_flags & M_EXT) == NULL) {
+                       m_freem(m);
+                       m = NULL;
+               }
        }
+       if (m == NULL)
+               return (ENOBUFS);
 
        /* Fixup the mbuf. */
        m->m_data += max_linkhdr;
@@ -3380,6 +3400,7 @@
                ipsec_setsocket(m, so);
        }
 #endif
+       m->m_pkthdr.rcvif = NULL;
        memset(mtod(m, u_char *), 0, tlen);
 
        switch (sc->sc_src.sa.sa_family) {
diff -r 032298cd45b5 -r 1b1549a8bac4 sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c  Fri Jun 30 16:40:31 2000 +0000
+++ b/sys/netinet/tcp_output.c  Fri Jun 30 16:44:33 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_output.c,v 1.56 2000/03/30 13:25:06 augustss Exp $ */
+/*     $NetBSD: tcp_output.c,v 1.57 2000/06/30 16:44:33 itojun Exp $   */
 
 /*
 %%% portions-copyright-nrl-95
@@ -703,7 +703,7 @@
                        m->m_len += len;
                } else {
                        m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
-                       if (m->m_next == 0) {
+                       if (m->m_next == NULL) {
                                m_freem(m);
                                error = ENOBUFS;
                                goto out;
diff -r 032298cd45b5 -r 1b1549a8bac4 sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c    Fri Jun 30 16:40:31 2000 +0000
+++ b/sys/netinet/tcp_subr.c    Fri Jun 30 16:44:33 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_subr.c,v 1.91 2000/03/30 13:25:07 augustss Exp $   */
+/*     $NetBSD: tcp_subr.c,v 1.92 2000/06/30 16:44:34 itojun Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -449,39 +449,85 @@
                }
                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");
+#endif
+
                /* 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;
                }
+               if ((flags & TH_SYN) == 0 || sizeof(*th0) > (th0->th_off << 2))
+                       tlen = sizeof(*th0);
+               else
+                       tlen = th0->th_off << 2;
 
-               /* template pointer almost has no meaning */
-               m_freem(m->m_next);
-               m->m_next = 0;
-               m->m_len = hlen + sizeof(struct tcphdr);
-               if ((m->m_flags & M_PKTHDR) == 0) {
-                       printf("non PKTHDR to tcp_respond\n");
+               if (m->m_len > hlen + tlen && (m->m_flags & M_EXT) == 0 &&
+                   mtod(m, caddr_t) + hlen == (caddr_t)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;
+                       }
+
+                       n->m_data += max_linkhdr;
+                       n->m_len = hlen + tlen;
+                       m_copyback(n, 0, hlen, mtod(m, caddr_t));
+                       m_copyback(n, hlen, tlen, (caddr_t)th0);
+
                        m_freem(m);
-                       return EINVAL;
+                       m = n;
+                       n = NULL;
                }
 
-               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;
@@ -489,14 +535,21 @@
                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;
 #endif
+#if 0
+               default:
+                       /* noone will visit here */
+                       m_freem(m);
+                       return EAFNOSUPPORT;
+#endif
                }
-               *th = *th0;
                xchg(th->th_dport, th->th_sport, u_int16_t);
 #undef xchg
+               tlen = 0;       /*be friendly with the following code*/
        }
        th->th_seq = htonl(seq);
        th->th_ack = htonl(ack);
@@ -508,7 +561,7 @@
                        win = TCP_MAXWIN;
                th->th_win = htons((u_int16_t)win);
                th->th_off = sizeof (struct tcphdr) >> 2;
-               tlen += sizeof (struct tcphdr);
+               tlen += sizeof(*th);
        } else
                tlen += th->th_off << 2;
        m->m_len = hlen + tlen;



Home | Main Index | Thread Index | Old Index