summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2015-08-05 15:02:49 +0200
committerAndreas Schneider <asn@samba.org>2015-08-11 13:58:30 +0200
commit85b7f564bd397e82cf847607f0bcee4e35f489ac (patch)
tree3e6156d7ba11f1d2da91fcb4e82ee62a57dee097
parent055eb78f3690008021e17da8714da9db5247308c (diff)
downloadsocket_wrapper-85b7f564bd397e82cf847607f0bcee4e35f489ac.tar.gz
socket_wrapper-85b7f564bd397e82cf847607f0bcee4e35f489ac.tar.xz
socket_wrapper-85b7f564bd397e82cf847607f0bcee4e35f489ac.zip
swrap: Correctly update the msg_name in recvmsg()
This has been found while debugging nsupdate. Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r--src/socket_wrapper.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 1188c4e..bd2798b 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -4051,6 +4051,19 @@ static int swrap_recvmsg_after(int fd,
avail += msg->msg_iov[i].iov_len;
}
+ /* Convert the socket address before we leave */
+ if (si->type == SOCK_DGRAM && un_addr != NULL) {
+ rc = sockaddr_convert_from_un(si,
+ un_addr,
+ un_addrlen,
+ si->family,
+ msg->msg_name,
+ &msg->msg_namelen);
+ if (rc == -1) {
+ goto done;
+ }
+ }
+
if (avail == 0) {
rc = 0;
goto done;
@@ -4096,16 +4109,6 @@ static int swrap_recvmsg_after(int fd,
}
if (un_addr != NULL) {
- rc = sockaddr_convert_from_un(si,
- un_addr,
- un_addrlen,
- si->family,
- msg->msg_name,
- &msg->msg_namelen);
- if (rc == -1) {
- goto done;
- }
-
swrap_pcap_dump_packet(si,
msg->msg_name,
SWRAP_RECVFROM,
@@ -4549,9 +4552,6 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
ret = libc_recvmsg(s, &msg, flags);
- 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;
@@ -4593,6 +4593,23 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
#endif
omsg->msg_iovlen = msg.msg_iovlen;
+ /*
+ * From the manpage:
+ *
+ * The msg_name field points to a caller-allocated buffer that is
+ * used to return the source address if the socket is unconnected. The
+ * caller should set msg_namelen to the size of this buffer before this
+ * call; upon return from a successful call, msg_name will contain the
+ * length of the returned address. If the application does not need
+ * to know the source address, msg_name can be specified as NULL.
+ */
+ if (omsg->msg_name != NULL &&
+ omsg->msg_namelen != 0 &&
+ omsg->msg_namelen >= msg.msg_namelen) {
+ memcpy(omsg->msg_name, msg.msg_name, msg.msg_namelen);
+ omsg->msg_namelen = msg.msg_namelen;
+ }
+
return ret;
}