Author: glebius
Date: Fri Mar 29 14:04:26 2013
New Revision: 248885
URL: http://svnweb.freebsd.org/changeset/base/248885

Log:
  Revamp mbuf handling in ng_ksocket_incoming2():
  
  - Clear code that workarounded a bug in FreeBSD 3,
    and even predated import of netgraph(4).
  - Clear workaround for m_nextpkt pointing into
    next record in buffer (fixed in r248884).
    Assert that m_nextpkt is clear.
  - Do not rely on SOCK_STREAM sockets containing
    M_PKTHDR mbufs. Create a header ourselves and
    attach chain to it. This is correct fix for
    kern/154676.
  
  PR:           kern/154676
  Sponsored by: Nginx, Inc

Modified:
  head/sys/netgraph/ng_ksocket.c

Modified: head/sys/netgraph/ng_ksocket.c
==============================================================================
--- head/sys/netgraph/ng_ksocket.c      Fri Mar 29 13:57:55 2013        
(r248884)
+++ head/sys/netgraph/ng_ksocket.c      Fri Mar 29 14:04:26 2013        
(r248885)
@@ -1042,7 +1042,6 @@ ng_ksocket_incoming2(node_p node, hook_p
 {
        struct socket *so = arg1;
        const priv_p priv = NG_NODE_PRIVATE(node);
-       struct mbuf *m;
        struct ng_mesg *response;
        struct uio auio;
        int flags, error;
@@ -1096,11 +1095,11 @@ ng_ksocket_incoming2(node_p node, hook_p
 
        /* Read and forward available mbuf's */
        auio.uio_td = NULL;
-       auio.uio_resid = 1000000000;
+       auio.uio_resid = MJUMPAGESIZE;  /* XXXGL: sane limit? */
        flags = MSG_DONTWAIT;
        while (1) {
                struct sockaddr *sa = NULL;
-               struct mbuf *n;
+               struct mbuf *m;
 
                /* Try to get next packet from socket */
                if ((error = soreceive(so, (so->so_state & SS_ISCONNECTED) ?
@@ -1114,17 +1113,28 @@ ng_ksocket_incoming2(node_p node, hook_p
                        break;
                }
 
+               KASSERT(m->m_nextpkt == NULL, ("%s: nextpkt", __func__));
+
                /*
-                * Don't trust the various socket layers to get the
-                * packet header and length correct (e.g. kern/15175).
-                *
-                * Also, do not trust that soreceive() will clear m_nextpkt
-                * for us (e.g. kern/84952, kern/82413).
+                * Stream sockets do not have packet boundaries, so
+                * we have to allocate a header mbuf and attach the
+                * stream of data to it.
                 */
-               m->m_pkthdr.csum_flags = 0;
-               for (n = m, m->m_pkthdr.len = 0; n != NULL; n = n->m_next) {
-                       m->m_pkthdr.len += n->m_len;
-                       n->m_nextpkt = NULL;
+               if (so->so_type == SOCK_STREAM) {
+                       struct mbuf *mh;
+
+                       mh = m_gethdr(M_NOWAIT, MT_DATA);
+                       if (mh == NULL) {
+                               m_freem(m);
+                               if (sa != NULL)
+                                       free(sa, M_SONAME);
+                               break;
+                       }
+
+                       mh->m_next = m;
+                       for (; m; m = m->m_next)
+                               mh->m_pkthdr.len += m->m_len;
+                       m = mh;
                }
 
                /* Put peer's socket address (if any) into a tag */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to