[SCM] Socket Wrapper Repository - branch master updated

Andreas Schneider asn at samba.org
Thu May 22 07:14:24 MDT 2014


The branch, master has been updated
       via  b9404d4 cmake: Fix a typo in socket_wrapper-config.cmake.in.
       via  71cc17a cmake: Require cmocka versin 0.4.1.
       via  916a02d tests: Add test for different length passed to get(sock|peer)name.
       via  9b45102 swrap: Truncate the address if the buffer is to small.
       via  b02ecdf tests: Add support to sending IP_PKTINFO in echo_srv.
       via  6f96c9d tests: Add support to receive IP_PKTINFO in echo_srv.
       via  d71c5d6 swrap: Process control messages in recvmsg().
       via  efb1249 swrap: Call swrap_msghdr_socket_info in swrap_recvmsg_after().
       via  1a3eac1 swrap: Add swrap_msghdr_socket_info().
       via  37dfa9b swrap: Add swrap_msghdr_add_pktinfo().
       via  c609a8a swrap: Add swrap_msghdr_add_cmsghdr().
       via  54d987e swrap: Add IP_PKTINFO support in setsockopt.
       via  ae3c84b cmake: Add check for HAVE_STRUCT_IN6_PKTINFO.
       via  0911cab cmake: Build swrap with _GNU_SOURCE.
      from  b37783b tests: Add test to verify that the binded iface address is correct.

http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit b9404d4a5f8d6295cc08514e57cc281efdcab6c6
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 22 14:56:09 2014 +0200

    cmake: Fix a typo in socket_wrapper-config.cmake.in.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 71cc17ad79e186717c5e565369b860c0cc2f2d77
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 22 08:49:07 2014 +0200

    cmake: Require cmocka versin 0.4.1.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 916a02d1f155c98f689e5ebb545331dc0f48ac2a
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Wed May 14 18:08:38 2014 +0200

    tests: Add test for different length passed to get(sock|peer)name.
    
    Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 9b45102df0bf3dc817533d6e478fdf56852d2db5
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Wed May 14 17:44:07 2014 +0200

    swrap: Truncate the address if the buffer is to small.
    
    Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit b02ecdf338ce6bcefaa91ec0a8fe3dce5b8925a8
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Wed May 14 11:28:33 2014 +0200

    tests: Add support to sending IP_PKTINFO in echo_srv.
    
    Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 6f96c9df7cdc2e4b80bad9cd782a9256e1f03625
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Wed May 14 10:11:37 2014 +0200

    tests: Add support to receive IP_PKTINFO in echo_srv.
    
    Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit d71c5d60d54048fe649be332b4267d93ae19d7ce
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Tue May 13 16:06:13 2014 +0200

    swrap: Process control messages in recvmsg().
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit efb124918850c340df711ed643a04fef1424c203
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Tue May 13 16:05:44 2014 +0200

    swrap: Call swrap_msghdr_socket_info in swrap_recvmsg_after().
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 1a3eac1c6c8f739a1da0b40f683b651475808eae
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Tue May 13 16:02:26 2014 +0200

    swrap: Add swrap_msghdr_socket_info().
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    Pair-Programmed-With: Michael Adam <obnox at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 37dfa9ba9484488995b4338b6e955b54ea1912aa
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Tue May 13 16:01:25 2014 +0200

    swrap: Add swrap_msghdr_add_pktinfo().
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    Pair-Programmed-With: Michael Adam <obnox at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

commit c609a8a5547d0d1edc17069bcaf22bbb63802c3b
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jan 22 18:45:51 2014 +0100

    swrap: Add swrap_msghdr_add_cmsghdr().
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
    Pair-Programmed-With: Michael Adam <obnox at samba.org>
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 54d987e1316e058dea7a01853782677eaccef641
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jan 22 19:09:51 2014 +0100

    swrap: Add IP_PKTINFO support in setsockopt.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit ae3c84b07bc57be52c3f5d706bfeb62a7fa9ebbc
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jan 22 20:06:59 2014 +0100

    cmake: Add check for HAVE_STRUCT_IN6_PKTINFO.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 0911cab2c0e18ee9e0c130ec7ddbbf457345d4f0
Author: Andreas Schneider <asn at cryptomilk.org>
Date:   Tue May 13 01:56:17 2014 +0200

    cmake: Build swrap with _GNU_SOURCE.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 CMakeLists.txt                           |    7 +-
 ConfigureChecks.cmake                    |    5 +
 cmake/Modules/DefineCompilerFlags.cmake  |    2 +-
 cmake/Modules/FindCMocka.cmake           |   49 -----
 config.h.cmake                           |    4 +
 socket_wrapper-config.cmake.in           |    2 +-
 src/CMakeLists.txt                       |    6 +
 src/socket_wrapper.c                     |  247 +++++++++++++++++++++++++-
 tests/CMakeLists.txt                     |    1 +
 tests/echo_srv.c                         |  288 +++++++++++++++++++++++++++++-
 tests/test_echo_tcp_get_peer_sock_name.c |   58 ++++++
 11 files changed, 600 insertions(+), 69 deletions(-)
 delete mode 100644 cmake/Modules/FindCMocka.cmake


Changeset truncated at 500 lines:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33c2245..8e346e6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,9 +51,10 @@ configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
 add_subdirectory(src)
 
 if (UNIT_TESTING)
-  find_package(CMocka REQUIRED)
-  include(AddCMockaTest)
-  add_subdirectory(tests)
+    find_package(cmocka 0.4.1 REQUIRED)
+
+    include(AddCMockaTest)
+    add_subdirectory(tests)
 endif (UNIT_TESTING)
 
 # pkg-config file
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 8db5162..2d4c409 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -81,6 +81,11 @@ endif (UNIX)
 
 set(SWRAP_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "socket_wrapper required system libraries")
 
+# STRUCTS
+set(CMAKE_REQUIRED_FLAGS -D_GNU_SOURCE)
+check_struct_has_member("struct in6_pktinfo" ipi6_addr "sys/types.h;sys/socket.h;netinet/in.h" HAVE_STRUCT_IN6_PKTINFO)
+set(CMAKE_REQUIRED_FLAGS)
+
 # STRUCT MEMBERS
 check_struct_has_member("struct sockaddr" sa_len "sys/types.h;sys/socket.h;netinet/in.h" HAVE_STRUCT_SOCKADDR_SA_LEN)
 check_struct_has_member("struct msghdr" msg_control "sys/types.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_CONTROL)
diff --git a/cmake/Modules/DefineCompilerFlags.cmake b/cmake/Modules/DefineCompilerFlags.cmake
index 0ab8802..e522a6a 100644
--- a/cmake/Modules/DefineCompilerFlags.cmake
+++ b/cmake/Modules/DefineCompilerFlags.cmake
@@ -10,7 +10,7 @@ if (UNIX AND NOT WIN32)
     if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
 
         # add -Wconversion ?
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute")
diff --git a/cmake/Modules/FindCMocka.cmake b/cmake/Modules/FindCMocka.cmake
deleted file mode 100644
index 2dd9fc5..0000000
--- a/cmake/Modules/FindCMocka.cmake
+++ /dev/null
@@ -1,49 +0,0 @@
-# - Try to find CMocka
-# Once done this will define
-#
-#  CMOCKA_ROOT_DIR - Set this variable to the root installation of CMocka
-#
-# Read-Only variables:
-#  CMOCKA_FOUND - system has CMocka
-#  CMOCKA_INCLUDE_DIR - the CMocka include directory
-#  CMOCKA_LIBRARIES - Link these to use CMocka
-#  CMOCKA_DEFINITIONS - Compiler switches required for using CMocka
-#
-#=============================================================================
-#  Copyright (c) 2011-2012 Andreas Schneider <asn at cryptomilk.org>
-#
-#  Distributed under the OSI-approved BSD License (the "License");
-#  see accompanying file Copyright.txt for details.
-#
-#  This software is distributed WITHOUT ANY WARRANTY; without even the
-#  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#  See the License for more information.
-#=============================================================================
-#
-
-find_path(CMOCKA_INCLUDE_DIR
-    NAMES
-        cmocka.h
-    PATHS
-        ${CMOCKA_ROOT_DIR}/include
-)
-
-find_library(CMOCKA_LIBRARY
-    NAMES
-        cmocka
-    PATHS
-        ${CMOCKA_ROOT_DIR}/include
-)
-
-if (CMOCKA_LIBRARY)
-  set(CMOCKA_LIBRARIES
-      ${CMOCKA_LIBRARIES}
-      ${CMOCKA_LIBRARY}
-  )
-endif (CMOCKA_LIBRARY)
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(CMocka DEFAULT_MSG CMOCKA_LIBRARIES CMOCKA_INCLUDE_DIR)
-
-# show the CMOCKA_INCLUDE_DIR and CMOCKA_LIBRARIES variables only in the advanced view
-mark_as_advanced(CMOCKA_INCLUDE_DIR CMOCKA_LIBRARIES)
diff --git a/config.h.cmake b/config.h.cmake
index efa519b..57a2f12 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -20,6 +20,10 @@
 #cmakedefine HAVE_SYS_TIMERFD_H 1
 #cmakedefine HAVE_GNU_LIB_NAMES_H 1
 
+/**************************** STRUCTS ****************************/
+
+#cmakedefine HAVE_STRUCT_IN6_PKTINFO 1
+
 /************************ STRUCT MEMBERS *************************/
 
 #cmakedefine HAVE_STRUCT_SOCKADDR_SA_LEN 1
diff --git a/socket_wrapper-config.cmake.in b/socket_wrapper-config.cmake.in
index 732d784..7bedd79 100644
--- a/socket_wrapper-config.cmake.in
+++ b/socket_wrapper-config.cmake.in
@@ -1 +1 @@
-set(SOCKET_WRAPPER_LIRBARY @LIB_INSTALL_DIR@/@SOCKET_WRAPPER_LIB@)
+set(SOCKET_WRAPPER_LIBRARY @LIB_INSTALL_DIR@/@SOCKET_WRAPPER_LIB@)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 95a691f..b1ab95f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,12 @@
 project(libsocket_wrapper C)
 
 include_directories(${CMAKE_BINARY_DIR})
+
+set_source_files_properties(socket_wrapper.c
+    PROPERTIES
+        COMPILE_DEFINITIONS
+            _GNU_SOURCE)
+
 add_library(socket_wrapper SHARED socket_wrapper.c)
 
 target_link_libraries(socket_wrapper ${SWRAP_REQUIRED_LIBRARIES})
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 4bca746..01a498f 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -119,6 +119,12 @@ enum swrap_dbglvl_e {
 #define discard_const_p(type, ptr) ((type *)discard_const(ptr))
 #endif
 
+#ifdef IPV6_PKTINFO
+# ifndef IPV6_RECVPKTINFO
+#  define IPV6_RECVPKTINFO IPV6_PKTINFO
+# endif /* IPV6_RECVPKTINFO */
+#endif /* IPV6_PKTINFO */
+
 #define SWRAP_DLIST_ADD(list,item) do { \
 	if (!(list)) { \
 		(item)->prev	= NULL; \
@@ -199,6 +205,7 @@ struct socket_info
 	int is_server;
 	int connected;
 	int defer_connect;
+	int pktinfo;
 
 	char *tmp_path;
 
@@ -2754,6 +2761,7 @@ int open(const char *pathname, int flags, ...)
 static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
 {
 	struct socket_info *si = find_socket_info(s);
+	socklen_t len;
 
 	if (!si) {
 		return libc_getpeername(s, name, addrlen);
@@ -2765,7 +2773,12 @@ static int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
 		return -1;
 	}
 
-	memcpy(name, si->peername, si->peername_len);
+	len = MIN(*addrlen, si->peername_len);
+	if (len == 0) {
+		return 0;
+	}
+
+	memcpy(name, si->peername, len);
 	*addrlen = si->peername_len;
 
 	return 0;
@@ -2787,12 +2800,18 @@ int getpeername(int s, struct sockaddr *name, socklen_t *addrlen)
 static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
 {
 	struct socket_info *si = find_socket_info(s);
+	socklen_t len;
 
 	if (!si) {
 		return libc_getsockname(s, name, addrlen);
 	}
 
-	memcpy(name, si->myname, si->myname_len);
+	len = MIN(*addrlen, si->myname_len);
+	if (len == 0) {
+		return 0;
+	}
+
+	memcpy(name, si->myname, len);
 	*addrlen = si->myname_len;
 
 	return 0;
@@ -2872,9 +2891,23 @@ static int swrap_setsockopt(int s, int level, int optname,
 
 	switch (si->family) {
 	case AF_INET:
+		if (level == IPPROTO_IP) {
+#ifdef IP_PKTINFO
+			if (optname == IP_PKTINFO) {
+				si->pktinfo = AF_INET;
+			}
+#endif /* IP_PKTINFO */
+		}
 		return 0;
 #ifdef HAVE_IPV6
 	case AF_INET6:
+		if (level == IPPROTO_IPV6) {
+#ifdef IPV6_RECVPKTINFO
+			if (optname == IPV6_RECVPKTINFO) {
+				si->pktinfo = AF_INET6;
+			}
+#endif /* IPV6_PKTINFO */
+		}
 		return 0;
 #endif
 	default:
@@ -2943,6 +2976,153 @@ int ioctl(int s, unsigned long int r, ...)
 	return rc;
 }
 
+/*****************
+ * CMSG
+ *****************/
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+/**
+ * @brief Add a cmsghdr to a msghdr.
+ *
+ * This is an function to add any type of cmsghdr. It will operate on the
+ * msg->msg_control and msg->msg_controllen you pass in by adapting them to
+ * the buffer position after the added cmsg element. Hence, this function is
+ * intended to be used with an intermediate msghdr and not on the original
+ * one handed in by the client.
+ *
+ * @param[in]  msg      The msghdr to which to add the cmsg.
+ *
+ * @param[in]  level    The cmsg level to set.
+ *
+ * @param[in]  type     The cmsg type to set.
+ *
+ * @param[in]  data     The cmsg data to set.
+ *
+ * @param[in]  len      the length of the data to set.
+ */
+static void swrap_msghdr_add_cmsghdr(struct msghdr *msg,
+				     int level,
+				     int type,
+				     const void *data,
+				     size_t len)
+{
+	size_t cmlen = CMSG_LEN(len);
+	size_t cmspace = CMSG_SPACE(len);
+	uint8_t cmbuf[cmspace];
+	struct cmsghdr *cm = (struct cmsghdr *)cmbuf;
+	uint8_t *p;
+
+	memset(cmbuf, 0, cmspace);
+
+	if (msg->msg_controllen < cmlen) {
+		cmlen = msg->msg_controllen;
+		msg->msg_flags |= MSG_CTRUNC;
+	}
+
+	if (msg->msg_controllen < cmspace) {
+		cmspace = msg->msg_controllen;
+	}
+
+	/*
+	 * We copy the full input data into an intermediate cmsghdr first
+	 * in order to more easily cope with truncation.
+	 */
+	cm->cmsg_len = cmlen;
+	cm->cmsg_level = level;
+	cm->cmsg_type = type;
+	memcpy(CMSG_DATA(cm), data, len);
+
+	/*
+	 * We now copy the possibly truncated buffer.
+	 * We copy cmlen bytes, but consume cmspace bytes,
+	 * leaving the possible padding uninitialiazed.
+	 */
+	p = (uint8_t *)msg->msg_control;
+	memcpy(p, cm, cmlen);
+	p += cmspace;
+	msg->msg_control = p;
+	msg->msg_controllen -= cmspace;
+
+	return;
+}
+
+static int swrap_msghdr_add_pktinfo(struct socket_info *si,
+				    struct msghdr *msg)
+{
+	/* Add packet info */
+	switch (si->pktinfo) {
+#ifdef IP_PKTINFO
+	case AF_INET: {
+		struct sockaddr_in *sin;
+		struct in_pktinfo pkt;
+
+		if (si->bindname_len == sizeof(struct sockaddr_in)) {
+			sin = (struct sockaddr_in*)si->bindname;
+		} else {
+			if (si->myname_len != sizeof(struct sockaddr_in)) {
+				return 0;
+			}
+			sin = (struct sockaddr_in*)si->myname;
+		}
+
+		ZERO_STRUCT(pkt);
+
+		pkt.ipi_ifindex = socket_wrapper_default_iface();
+		pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
+
+		swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
+					 &pkt, sizeof(pkt));
+
+		break;
+	}
+#endif /* IP_PKTINFO */
+#if defined(HAVE_IPV6)
+	case AF_INET6: {
+#if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO)
+		struct sockaddr_in6 *sin6;
+		struct in6_pktinfo pkt6;
+
+		if (si->bindname_len == sizeof(struct sockaddr_in6)) {
+			sin6 = (struct sockaddr_in6*)si->bindname;
+		} else {
+			if (si->myname_len != sizeof(struct sockaddr_in6)) {
+				return 0;
+			}
+			sin6 = (struct sockaddr_in6*)si->myname;
+		}
+
+		ZERO_STRUCT(pkt6);
+
+		pkt6.ipi6_ifindex = socket_wrapper_default_iface();
+		pkt6.ipi6_addr = sin6->sin6_addr;
+
+		swrap_msghdr_add_cmsghdr(msg, IPPROTO_IPV6, IPV6_PKTINFO,
+					&pkt6, sizeof(pkt6));
+#endif /* HAVE_STRUCT_IN6_PKTINFO */
+
+		break;
+	}
+#endif /* IPV6_PKTINFO */
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static int swrap_msghdr_add_socket_info(struct socket_info *si,
+					struct msghdr *omsg)
+{
+	int rc = 0;
+
+	if (si->pktinfo > 0) {
+		rc = swrap_msghdr_add_pktinfo(si, omsg);
+	}
+
+	return rc;
+}
+#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
+
 static ssize_t swrap_sendmsg_before(int fd,
 				    struct socket_info *si,
 				    struct msghdr *msg,
@@ -3232,6 +3412,7 @@ static int swrap_recvmsg_after(int fd,
 	off_t ofs = 0;
 	size_t avail = 0;
 	size_t remain;
+	int rc;
 
 	/* to give better errors */
 	if (ret == -1) {
@@ -3248,8 +3429,8 @@ static int swrap_recvmsg_after(int fd,
 	}
 
 	if (avail == 0) {
-		errno = saved_errno;
-		return 0;
+		rc = 0;
+		goto done;
 	}
 
 	if (ret == -1) {
@@ -3292,8 +3473,6 @@ static int swrap_recvmsg_after(int fd,
 		}
 
 		if (un_addr != NULL) {
-			int rc;
-
 			rc = sockaddr_convert_from_un(si,
 						      un_addr,
 						      un_addrlen,
@@ -3320,10 +3499,23 @@ static int swrap_recvmsg_after(int fd,
 		break;
 	}
 
+	rc = 0;
 done:
 	free(buf);
 	errno = saved_errno;
-	return 0;
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+	if (rc == 0 &&
+	    msg->msg_controllen > 0 &&
+	    msg->msg_control != NULL) {
+		rc = swrap_msghdr_add_socket_info(si, msg);
+		if (rc < 0) {
+			return -1;
+		}
+	}
+#endif
+
+	return rc;
 }
 
 /****************************************************************************
@@ -3683,6 +3875,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;
@@ -3701,6 +3895,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 */
@@ -3713,11 +3910,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


-- 
Socket Wrapper Repository


More information about the samba-cvs mailing list