[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