summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2014-06-03 14:57:35 +0200
committerMichael Adam <obnox@samba.org>2014-06-05 23:57:10 +0200
commit1df081058326afb655f2860439b7b8c23403423b (patch)
treea93188cef3c2420776a44d33804526bcccd127f1 /lib
parentfb308daaa038d966cf0385313a9b58ab24164773 (diff)
downloadsamba-1df081058326afb655f2860439b7b8c23403423b.tar.gz
samba-1df081058326afb655f2860439b7b8c23403423b.tar.xz
samba-1df081058326afb655f2860439b7b8c23403423b.zip
swrap: Process control messages in recvmsg().
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/socket_wrapper/socket_wrapper.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index e77ef85e7c9..52fabf4eec4 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -3863,6 +3863,8 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
struct socket_info *si;
struct msghdr msg;
struct iovec tmp;
+ size_t msg_ctrllen_filled;
+ size_t msg_ctrllen_left;
ssize_t ret;
int rc;
@@ -3881,6 +3883,9 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
msg.msg_iov = omsg->msg_iov; /* scatter/gather array */
msg.msg_iovlen = omsg->msg_iovlen; /* # elements in msg_iov */
#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ msg_ctrllen_filled = 0;
+ msg_ctrllen_left = omsg->msg_controllen;
+
msg.msg_control = omsg->msg_control; /* ancillary data, see below */
msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
msg.msg_flags = omsg->msg_flags; /* flags on received message */
@@ -3893,11 +3898,45 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
ret = libc_recvmsg(s, &msg, flags);
- rc = swrap_recvmsg_after(s, si, omsg, &from_addr, from_addrlen, ret);
+ msg.msg_name = omsg->msg_name;
+ msg.msg_namelen = omsg->msg_namelen;
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ msg_ctrllen_filled += msg.msg_controllen;
+ msg_ctrllen_left -= msg.msg_controllen;
+
+ if (omsg->msg_control != NULL) {
+ uint8_t *p;
+
+ p = omsg->msg_control;
+ p += msg_ctrllen_filled;
+
+ msg.msg_control = p;
+ msg.msg_controllen = msg_ctrllen_left;
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+#endif
+
+ rc = swrap_recvmsg_after(s, si, &msg, &from_addr, from_addrlen, ret);
if (rc != 0) {
return rc;
}
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ if (omsg->msg_control != NULL) {
+ /* msg.msg_controllen = space left */
+ msg_ctrllen_left = msg.msg_controllen;
+ msg_ctrllen_filled = omsg->msg_controllen - msg_ctrllen_left;
+ }
+
+ /* Update the original message length */
+ omsg->msg_controllen = msg_ctrllen_filled;
+ omsg->msg_flags = msg.msg_flags;
+#endif
+ omsg->msg_iovlen = msg.msg_iovlen;
+
return ret;
}