summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordwmalone <dwmalone@FreeBSD.org>2004-07-18 19:10:36 +0000
committerdwmalone <dwmalone@FreeBSD.org>2004-07-18 19:10:36 +0000
commitb862fe68f09527177a4f7c4c3deaa6a0ff5e1a4e (patch)
treefc61d2eb8e7eb7e2a9514f24f96636b4dea181e1 /sys
parentb538ed4a41336f13b8603f34760265da04296d9c (diff)
downloadFreeBSD-src-b862fe68f09527177a4f7c4c3deaa6a0ff5e1a4e.zip
FreeBSD-src-b862fe68f09527177a4f7c4c3deaa6a0ff5e1a4e.tar.gz
The recent changes to control message passing broke some things
that get certain types of control messages (ping6 and rtsol are examples). This gets the new code closer to working: 1) Collect control mbufs for processing in the controlp == NULL case, so that they can be freed by externalize. 2) Loop over the list of control mbufs, as the externalize function may not know how to deal with chains. 3) In the case where there is no externalize function, remember to add the control mbuf to the controlp list so that it will be returned. 4) After adding stuff to the controlp list, walk to the end of the list of stuff that was added, incase we added a chain. This code can be further improved, but this is enough to get most things working again. Reviewed by: rwatson
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_socket.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 7f38b90..7b5793e 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1090,10 +1090,10 @@ dontblock:
* Process one or more MT_CONTROL mbufs present before any data mbufs
* in the first mbuf chain on the socket buffer. If MSG_PEEK, we
* just copy the data; if !MSG_PEEK, we call into the protocol to
- * perform externalization.
+ * perform externalization (or freeing if controlp == NULL).
*/
if (m != NULL && m->m_type == MT_CONTROL) {
- struct mbuf *cm = NULL;
+ struct mbuf *cm = NULL, *cmn;
struct mbuf **cme = &cm;
do {
@@ -1107,27 +1107,31 @@ dontblock:
sbfree(&so->so_rcv, m);
so->so_rcv.sb_mb = m->m_next;
m->m_next = NULL;
- if (controlp) {
- /*
- * Collect mbufs for processing below.
- */
- *cme = m;
- cme = &(*cme)->m_next;
- } else
- m_free(m);
+ *cme = m;
+ cme = &(*cme)->m_next;
m = so->so_rcv.sb_mb;
}
} while (m != NULL && m->m_type == MT_CONTROL);
if ((flags & MSG_PEEK) == 0)
sockbuf_pushsync(&so->so_rcv, nextrecord);
- if (cm != NULL) {
+ while (cm != NULL) {
+ cmn = cm->m_next;
+ cm->m_next = NULL;
if (pr->pr_domain->dom_externalize != NULL) {
SOCKBUF_UNLOCK(&so->so_rcv);
error = (*pr->pr_domain->dom_externalize)
(cm, controlp);
SOCKBUF_LOCK(&so->so_rcv);
- } else
+ } else if (controlp != NULL)
+ *controlp = cm;
+ else
m_freem(cm);
+ if (controlp != NULL) {
+ orig_resid = 0;
+ while (*controlp != NULL)
+ controlp = &(*controlp)->m_next;
+ }
+ cm = cmn;
}
nextrecord = so->so_rcv.sb_mb->m_nextpkt;
orig_resid = 0;
OpenPOWER on IntegriCloud