diff options
author | Andreas Schneider <asn@samba.org> | 2014-06-03 14:57:35 +0200 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2014-06-05 23:57:10 +0200 |
commit | 1df081058326afb655f2860439b7b8c23403423b (patch) | |
tree | a93188cef3c2420776a44d33804526bcccd127f1 /lib | |
parent | fb308daaa038d966cf0385313a9b58ab24164773 (diff) | |
download | samba-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.c | 41 |
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; } |