[SCM] Socket Wrapper Repository - branch master updated
Andreas Schneider
asn at samba.org
Mon May 26 08:52:34 MDT 2014
The branch, master has been updated
via 096c9a7 tests: Add more tests for socket options.
via e7f7bec swrap: Support more socket options in getsockopt().
via c9b06b3 echo_srv: Add support for IP_SENDSRCADDR.
via 27be91d swrap: Call swrap_msghdr_filter_cmsghdr in swrap_sendmsg_before().
via 4849b2e swrap: Add swrap_msghdr_filter_cmsg_pktinfo().
via 69f22c9 swrap: Add swrap_sendmsg_filter_cmsg_socket().
via 63c59be swrap: Add swrap_sendmsg_copy_cmsg().
via c9332d4 swrap: Add swrap_sendmsg_filter_cmsghdr().
via 3c55e35 echo_srv: Implement support for IP_RECVDSTADDR on BSD.
via 29f24e5 swrap: Implement support for IP_RECVDSTADDR on BSD.
via 75271e6 echo_srv: Fix building on OpenIndiana.
via 13ea22c swrap: Check if the in_pktinfo structure is available.
via f81b6e8 swrap: Silence a warning on OpenIndiana.
via d977b0e tests: Fix assert_sockaddr_equal() file and line output.
via f60415a cmake: Add some warnings were we should error out.
via 54d74cb swrap: Properly cache the handle also in LIBC_SO case.
from b9404d4 cmake: Fix a typo in socket_wrapper-config.cmake.in.
http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 096c9a7545ab5a406859a67374ca8a1c9d046f28
Author: Andreas Schneider <asn at samba.org>
Date: Thu May 22 11:32:22 2014 +0200
tests: Add more tests for socket options.
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit e7f7bec0b56acd7b9744af53f7d96a53abd46ad3
Author: Andreas Schneider <asn at samba.org>
Date: Thu May 22 11:18:08 2014 +0200
swrap: Support more socket options in getsockopt().
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit c9b06b39df767539e47da8b6ce2208a5463a5314
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 14:36:23 2014 +0200
echo_srv: Add support for IP_SENDSRCADDR.
Pair-Programmed-With: Michael Adam <obnox at samba.org>
Signed-off-by: Andreas Schneider <asn at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
commit 27be91da8fbb56826c361abd67ebb1e081540bfe
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 14:35:59 2014 +0200
swrap: Call swrap_msghdr_filter_cmsghdr in swrap_sendmsg_before().
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 4849b2ebbfca6176e685ac9c6c933aad8470295f
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 14:35:34 2014 +0200
swrap: Add swrap_msghdr_filter_cmsg_pktinfo().
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 69f22c94b4ad061263c40c8c271a86f444cee72d
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 15:44:23 2014 +0200
swrap: Add swrap_sendmsg_filter_cmsg_socket().
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 63c59be9ace8282ed19b15fa9d66c7448c1bdd97
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 15:48:33 2014 +0200
swrap: Add swrap_sendmsg_copy_cmsg().
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit c9332d48d55925c585641bbd7069f3a4c774e3c1
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 15:42:14 2014 +0200
swrap: Add swrap_sendmsg_filter_cmsghdr().
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 3c55e35cad90ef3c1126b390cf53b860c99fdd6e
Author: Andreas Schneider <asn at samba.org>
Date: Mon May 26 11:07:45 2014 +0200
echo_srv: Implement support for IP_RECVDSTADDR on BSD.
Pair-Programmed-With: Michael Adam <obnox at samba.org>
Signed-off-by: Andreas Schneider <asn at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
commit 29f24e5cc059ed37117126838045f85b494fc288
Author: Andreas Schneider <asn at samba.org>
Date: Mon May 26 11:00:09 2014 +0200
swrap: Implement support for IP_RECVDSTADDR on BSD.
Pair-Programmed-With: Michael Adam <obnox at samba.org>
Signed-off-by: Andreas Schneider <asn at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
commit 75271e62121ba207076add1378d716adcf3ee47f
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 09:26:13 2014 +0200
echo_srv: Fix building on OpenIndiana.
Solaris doesn't have support for auxillary messages.
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 13ea22cdaac3b5855232f1f59d910b628847ffe2
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 10:01:21 2014 +0200
swrap: Check if the in_pktinfo structure is available.
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit f81b6e84d57a6d40dce96b49cf18d924ab282872
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 09:20:31 2014 +0200
swrap: Silence a warning on OpenIndiana.
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit d977b0ee9570757cb15014c18787d366956d7901
Author: Andreas Schneider <asn at samba.org>
Date: Wed May 21 14:52:21 2014 +0200
tests: Fix assert_sockaddr_equal() file and line output.
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit f60415a3ae411454551adc494e65fff7412e270e
Author: Andreas Schneider <asn at samba.org>
Date: Fri May 23 08:50:47 2014 +0200
cmake: Add some warnings were we should error out.
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 54d74cb22eb17107bdc8c36c24c43a1f2d16914e
Author: Pino Toscano <toscano.pino at tiscali.it>
Date: Thu May 8 16:26:43 2014 +0200
swrap: Properly cache the handle also in LIBC_SO case.
Small regression introduced by me in commit
0fa56909442c3cfea6a697681ea0e89ba5a0aa0f.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=10572
Reviewed-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
-----------------------------------------------------------------------
Summary of changes:
ConfigureChecks.cmake | 1 +
cmake/Modules/DefineCompilerFlags.cmake | 6 +
config.h.cmake | 1 +
src/socket_wrapper.c | 231 ++++++++++++++++++++++++++++-
tests/echo_srv.c | 102 +++++++++++--
tests/test_echo_tcp_get_peer_sock_name.c | 3 +-
tests/test_echo_tcp_socket_options.c | 147 +++++++++++++++++++
7 files changed, 466 insertions(+), 25 deletions(-)
Changeset truncated at 500 lines:
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 2d4c409..3a31f50 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -82,6 +82,7 @@ endif (UNIX)
set(SWRAP_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CACHE INTERNAL "socket_wrapper required system libraries")
# STRUCTS
+check_struct_has_member("struct in_pktinfo" ipi_addr "sys/types.h;sys/socket.h;netinet/in.h" HAVE_STRUCT_IN_PKTINFO)
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)
diff --git a/cmake/Modules/DefineCompilerFlags.cmake b/cmake/Modules/DefineCompilerFlags.cmake
index e522a6a..e6fab88 100644
--- a/cmake/Modules/DefineCompilerFlags.cmake
+++ b/cmake/Modules/DefineCompilerFlags.cmake
@@ -11,10 +11,14 @@ if (UNIX AND NOT WIN32)
# add -Wconversion ?
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")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=pointer-arith -Werror=declaration-after-statement")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
+
# with -fPIC
check_c_compiler_flag("-fPIC" WITH_FPIC)
if (WITH_FPIC)
@@ -33,6 +37,8 @@ if (UNIX AND NOT WIN32)
if (WITH_FORTIFY_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-D_FORTIFY_SOURCE=2")
endif (WITH_FORTIFY_SOURCE)
+
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=uninitialized")
endif()
endif()
endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
diff --git a/config.h.cmake b/config.h.cmake
index 57a2f12..02c016e 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -22,6 +22,7 @@
/**************************** STRUCTS ****************************/
+#cmakedefine HAVE_STRUCT_IN_PKTINFO 1
#cmakedefine HAVE_STRUCT_IN6_PKTINFO 1
/************************ STRUCT MEMBERS *************************/
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 01a498f..19ac184 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -125,6 +125,18 @@ enum swrap_dbglvl_e {
# endif /* IPV6_RECVPKTINFO */
#endif /* IPV6_PKTINFO */
+/*
+ * On BSD IP_PKTINFO has a different name because during
+ * the time when they implemented it, there was no RFC.
+ * The name for IPv6 is the same as on Linux.
+ */
+#ifndef IP_PKTINFO
+# ifdef IP_RECVDSTADDR
+# define IP_PKTINFO IP_RECVDSTADDR
+# endif
+#endif
+
+
#define SWRAP_DLIST_ADD(list,item) do { \
if (!(list)) { \
(item)->prev = NULL; \
@@ -434,6 +446,8 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
#ifdef LIBC_SO
if (handle == NULL) {
handle = dlopen(LIBC_SO, flags);
+
+ swrap.libc_handle = handle;
}
#endif
if (handle == NULL) {
@@ -2830,6 +2844,12 @@ int getsockname(int s, struct sockaddr *name, socklen_t *addrlen)
* GETSOCKOPT
***************************************************************************/
+#ifndef SO_PROTOCOL
+# ifdef SO_PROTOTYPE /* The Solaris name */
+# define SO_PROTOCOL SO_PROTOTYPE
+# endif /* SO_PROTOTYPE */
+#endif /* SO_PROTOCOL */
+
static int swrap_getsockopt(int s, int level, int optname,
void *optval, socklen_t *optlen)
{
@@ -2844,11 +2864,46 @@ static int swrap_getsockopt(int s, int level, int optname,
}
if (level == SOL_SOCKET) {
- return libc_getsockopt(s,
- level,
- optname,
- optval,
- optlen);
+ switch (optname) {
+#ifdef SO_DOMAIN
+ case SO_DOMAIN:
+ if (optval == NULL || optlen == NULL ||
+ *optlen < (socklen_t)sizeof(int)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *optlen = sizeof(int);
+ *(int *)optval = si->family;
+ return 0;
+#endif /* SO_DOMAIN */
+ case SO_PROTOCOL:
+ if (optval == NULL || optlen == NULL ||
+ *optlen < (socklen_t)sizeof(int)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *optlen = sizeof(int);
+ *(int *)optval = si->protocol;
+ return 0;
+ case SO_TYPE:
+ if (optval == NULL || optlen == NULL ||
+ *optlen < (socklen_t)sizeof(int)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *optlen = sizeof(int);
+ *(int *)optval = si->type;
+ return 0;
+ default:
+ return libc_getsockopt(s,
+ level,
+ optname,
+ optval,
+ optlen);
+ }
}
errno = ENOPROTOOPT;
@@ -2981,6 +3036,15 @@ int ioctl(int s, unsigned long int r, ...)
*****************/
#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+
+#ifndef CMSG_ALIGN
+# ifdef _ALIGN /* BSD */
+#define CMSG_ALIGN _ALIGN
+# else
+#error NO_CMSG_ALIGN
+# endif /* _ALIGN */
+#endif /* CMSG_ALIGN */
+
/**
* @brief Add a cmsghdr to a msghdr.
*
@@ -3051,10 +3115,15 @@ static int swrap_msghdr_add_pktinfo(struct socket_info *si,
{
/* Add packet info */
switch (si->pktinfo) {
-#ifdef IP_PKTINFO
+#if defined(IP_PKTINFO)
+/* && (defined(HAVE_STRUCT_IN_PKTINFO) || defined(IP_RECVDSTADDR)) */
case AF_INET: {
struct sockaddr_in *sin;
+#if defined(HAVE_STRUCT_IN_PKTINFO)
struct in_pktinfo pkt;
+#elif defined(IP_RECVDSTADDR)
+ struct in_addr pkt;
+#endif
if (si->bindname_len == sizeof(struct sockaddr_in)) {
sin = (struct sockaddr_in*)si->bindname;
@@ -3067,8 +3136,12 @@ static int swrap_msghdr_add_pktinfo(struct socket_info *si,
ZERO_STRUCT(pkt);
+#if defined(HAVE_STRUCT_IN_PKTINFO)
pkt.ipi_ifindex = socket_wrapper_default_iface();
pkt.ipi_addr.s_addr = sin->sin_addr.s_addr;
+#elif defined(IP_RECVDSTADDR)
+ pkt = sin->sin_addr;
+#endif
swrap_msghdr_add_cmsghdr(msg, IPPROTO_IP, IP_PKTINFO,
&pkt, sizeof(pkt));
@@ -3121,6 +3194,117 @@ static int swrap_msghdr_add_socket_info(struct socket_info *si,
return rc;
}
+
+static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
+ uint8_t *cm_data,
+ size_t *cm_data_space);
+static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
+ uint8_t *cm_data,
+ size_t *cm_data_space);
+
+static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
+ uint8_t *cm_data,
+ size_t *cm_data_space) {
+ struct cmsghdr *cmsg;
+ int rc = -1;
+
+ /* Nothing to do */
+ if (msg->msg_controllen == 0 || msg->msg_control == NULL) {
+ return 0;
+ }
+
+ for (cmsg = CMSG_FIRSTHDR(msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ switch (cmsg->cmsg_level) {
+ case IPPROTO_IP:
+ rc = swrap_sendmsg_filter_cmsg_socket(cmsg,
+ cm_data,
+ cm_data_space);
+ break;
+ default:
+ rc = swrap_sendmsg_copy_cmsg(cmsg,
+ cm_data,
+ cm_data_space);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
+ uint8_t *cm_data,
+ size_t *cm_data_space)
+{
+ size_t cmspace;
+ uint8_t *p;
+
+ cmspace =
+ (*cm_data_space) +
+ CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)));
+
+ p = realloc(cm_data, cmspace);
+ if (p == NULL) {
+ return -1;
+ }
+ cm_data = p;
+
+ p = cm_data + (*cm_data_space);
+ *cm_data_space = cmspace;
+
+ memcpy(p, cmsg, cmsg->cmsg_len);
+
+ return 0;
+}
+
+static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
+ uint8_t *cm_data,
+ size_t *cm_data_space);
+
+
+static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
+ uint8_t *cm_data,
+ size_t *cm_data_space)
+{
+ int rc = -1;
+
+ switch(cmsg->cmsg_type) {
+#ifdef IP_PKTINFO
+ case IP_PKTINFO:
+ rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
+ cm_data,
+ cm_data_space);
+ break;
+#endif
+#ifdef IPV6_PKTINFO
+ case IPV6_PKTINFO:
+ rc = swrap_sendmsg_filter_cmsg_pktinfo(cmsg,
+ cm_data,
+ cm_data_space);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
+ uint8_t *cm_data,
+ size_t *cm_data_space)
+{
+ (void)cmsg; /* unused */
+ (void)cm_data; /* unused */
+ (void)cm_data_space; /* unused */
+
+ /*
+ * Passing a IP pktinfo to a unix socket might be rejected by the
+ * Kernel, at least on FreeBSD. So skip this cmsg.
+ */
+ return 0;
+}
#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
static ssize_t swrap_sendmsg_before(int fd,
@@ -3243,6 +3427,28 @@ static ssize_t swrap_sendmsg_before(int fd,
return -1;
}
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
+ uint8_t *cmbuf = NULL;
+ size_t cmlen = 0;
+
+ ret = swrap_sendmsg_filter_cmsghdr(msg, cmbuf, &cmlen);
+ if (ret < 0) {
+ free(cmbuf);
+ return -1;
+ }
+
+ if (cmlen == 0) {
+ msg->msg_controllen = 0;
+ msg->msg_control = NULL;
+ } else if (cmlen < msg->msg_controllen) {
+ memcpy(msg->msg_control, cmbuf, cmlen);
+ msg->msg_controllen = cmlen;
+ }
+ free(cmbuf);
+ }
+#endif
+
return 0;
}
@@ -3875,8 +4081,10 @@ static ssize_t swrap_recvmsg(int s, struct msghdr *omsg, int flags)
struct socket_info *si;
struct msghdr msg;
struct iovec tmp;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
size_t msg_ctrllen_filled;
size_t msg_ctrllen_left;
+#endif
ssize_t ret;
int rc;
@@ -3988,8 +4196,15 @@ static ssize_t swrap_sendmsg(int s, const 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.msg_control = omsg->msg_control; /* ancillary data, see below */
- msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
+ if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
+ /* omsg is a const so use a local buffer for modifications */
+ uint8_t cmbuf[omsg->msg_controllen];
+
+ memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
+
+ msg.msg_control = cmbuf; /* ancillary data, see below */
+ msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
+ }
msg.msg_flags = omsg->msg_flags; /* flags on received message */
#endif
diff --git a/tests/echo_srv.c b/tests/echo_srv.c
index 33f2ebd..88d8170 100644
--- a/tests/echo_srv.c
+++ b/tests/echo_srv.c
@@ -55,14 +55,24 @@ struct echo_srv_opts {
const char *pidfile;
};
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+
+#if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_PKTINFO)
union pktinfo {
#ifdef HAVE_STRUCT_IN6_PKTINFO
struct in6_pktinfo pkt6;
#endif
+#ifdef HAVE_STRUCT_IN_PKTINFO
struct in_pktinfo pkt4;
+#elif defined(IP_RECVDSTADDR)
+ struct in_addr pkt4;
+#endif
char c;
};
+#define HAVE_UNION_PKTINFO 1
+#endif /* IP_PKTINFO || IP_RECVDSTADDR || IPV6_PKTINFO */
+
static const char *echo_server_address(int family)
{
switch (family) {
@@ -90,6 +100,7 @@ static const char *echo_server_address(int family)
return NULL;
}
+#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
static void _assert_return_code(int rc,
int err,
@@ -216,12 +227,24 @@ static void set_sock_pktinfo(int sock, int family)
switch(family) {
case AF_INET:
proto = IPPROTO_IP;
+#ifdef IP_PKTINFO
option = IP_PKTINFO;
+#elif IP_RECVDSTADDR
+ option = IP_RECVDSTADDR;
+#else
+ return;
+#endif /* IP_PKTINFO */
break;
+#ifdef HAVE_IPV6
+#ifdef IPV6_RECVPKTINFO
case AF_INET6:
proto = IPPROTO_IPV6;
option = IPV6_RECVPKTINFO;
break;
+#endif /* IPV6_RECVPKTINFO */
+#endif /* HAVE_IPV6 */
+ default:
+ return;
}
rc = setsockopt(sock, proto, option, &sockopt, sizeof(sockopt));
@@ -541,11 +564,15 @@ static ssize_t echo_udp_recv_from_to(int sock,
{
struct msghdr rmsg;
struct iovec riov;
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ ssize_t ret;
+
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO)
size_t cmlen = CMSG_LEN(sizeof(union pktinfo));
char cmsg[cmlen];
-#endif
- ssize_t ret;
+#else
+ (void)to; /* unused */
+ (void)tolen; /* unused */
+#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
riov.iov_base = buf;
riov.iov_len = buflen;
@@ -558,7 +585,7 @@ static ssize_t echo_udp_recv_from_to(int sock,
rmsg.msg_iov = &riov;
rmsg.msg_iovlen = 1;
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO)
memset(cmsg, 0, cmlen);
rmsg.msg_control = cmsg;
@@ -571,6 +598,7 @@ static ssize_t echo_udp_recv_from_to(int sock,
}
*fromlen = rmsg.msg_namelen;
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && defined(HAVE_UNION_PKTINFO)
if (rmsg.msg_controllen > 0) {
struct cmsghdr *cmsgptr;
@@ -578,11 +606,12 @@ static ssize_t echo_udp_recv_from_to(int sock,
while (cmsgptr != NULL) {
const char *p;
+#if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO)
if (cmsgptr->cmsg_level == IPPROTO_IP &&
cmsgptr->cmsg_type == IP_PKTINFO) {
char ip[INET_ADDRSTRLEN] = { 0 };
- struct in_pktinfo *pkt;
struct sockaddr_in *sinp = (struct sockaddr_in *)to;
+ struct in_pktinfo *pkt;
pkt = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
@@ -601,7 +630,33 @@ static ssize_t echo_udp_recv_from_to(int sock,
abort();
}
}
-#ifdef IPV6_PKTINFO
+#endif /* IP_PKTINFO */
+#ifdef IP_RECVDSTADDR
+ if (cmsgptr->cmsg_level == IPPROTO_IP &&
+ cmsgptr->cmsg_type == IP_RECVDSTADDR) {
+ char ip[INET_ADDRSTRLEN] = { 0 };
+ struct sockaddr_in *sinp = (struct sockaddr_in *)to;
+ struct in_addr *addr;
+
+ addr = (struct in_addr *)CMSG_DATA(cmsgptr);
+
+ sinp->sin_family = AF_INET;
+ sinp->sin_addr = *addr;
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list