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
This commit is contained in:
parent
1bccb6e916
commit
ffd07149de
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user