Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Mar 2013 14:04:26 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r248885 - head/sys/netgraph
Message-ID:  <201303291404.r2TE4QsO009391@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303291404.r2TE4QsO009391>