summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2013-03-29 14:04:26 +0000
committerglebius <glebius@FreeBSD.org>2013-03-29 14:04:26 +0000
commitffd07149de77f40048fd2d96196afdc7c7c13799 (patch)
tree9ba8680bcceda1eb5f38174472a04fb098ba9f66
parent1bccb6e916995784daf0c896715abbe3b4111b37 (diff)
downloadFreeBSD-src-ffd07149de77f40048fd2d96196afdc7c7c13799.zip
FreeBSD-src-ffd07149de77f40048fd2d96196afdc7c7c13799.tar.gz
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
-rw-r--r--sys/netgraph/ng_ksocket.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
index e6377dd..de22773 100644
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -1042,7 +1042,6 @@ ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int arg2)
{
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 hook, void *arg1, int arg2)
/* 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 hook, void *arg1, int arg2)
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 */
OpenPOWER on IntegriCloud