[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Thu Jun 5 18:26:04 MDT 2014


The branch, master has been updated
       via  7091755 selftest: Add support for tmate.
       via  fae59b4 lib: Bump socket_wrapper version to 1.1.1.
       via  064592d swrap: Disable incomplete bind checks (and tests) for EADDRINUSE.
       via  f6023bb lib: Bump socket_wrapper version to 1.1.0.
       via  b9d6ad8 swrap: check whether an address:port is already in use in swrap_bind()
       via  05c1e2d swrap: implement check_addr_port_in_use()
       via  f9ddd20 swrap: fix AF_UNSPEC special case in swrap_bind()
       via  8f28674 swrap: extend input checks in swrap_bind()
       via  3700a46 swrap: add check for rpc/rpc.h - needed on freebsd for bindresvport
       via  6e6c817 swrap: Add support for bindresvport().
       via  1b949b5 swrap: Add missing family check in bind().
       via  5ee936d swrap: Setup myname in swrap_socket() for getsockname().
       via  1f03de01 swrap: Make sure cmbuf is not NULL.
       via  74ade40 swrap: We need to pass a pointer-pointer to not leak memory.
       via  353709b swrap: Support more socket options in getsockopt().
       via  3689add swrap: Call swrap_msghdr_filter_cmsghdr in swrap_sendmsg_before().
       via  efe4eb2 swrap: Add swrap_msghdr_filter_cmsg_pktinfo().
       via  6a35c67 swrap: Add swrap_sendmsg_filter_cmsg_socket().
       via  2fe9612 swrap: Add swrap_sendmsg_copy_cmsg().
       via  c704966 swrap: Add swrap_sendmsg_filter_cmsghdr().
       via  0247bdb swrap: Implement support for IP_RECVDSTADDR on BSD.
       via  aa1e24e swrap: Check if the in_pktinfo structure is available.
       via  7556e13 swrap: Silence a warning on OpenIndiana.
       via  7a386b3 swrap: Properly cache the handle also in LIBC_SO case.
       via  f288efc swrap: Truncate the address if the buffer is to small.
       via  1df0810 swrap: Process control messages in recvmsg().
       via  fb308da swrap: Call swrap_msghdr_socket_info in swrap_recvmsg_after().
       via  b534c45 swrap: Add swrap_msghdr_socket_info().
       via  d5b204c swrap: Add swrap_msghdr_add_pktinfo().
       via  56d5bf9 swrap: Add swrap_msghdr_add_cmsghdr().
       via  ed3c219 swrap: Add IP_PKTINFO support in setsockopt.
       via  1921da4 waf: Add check for HAVE_STRUCT_IN6_PKTINFO.
       via  d652e06 swrap: Correctly set the bind iface address on connect().
       via  b5cd098 swrap: use LIBC_SO from GNU libc, if available
      from  7f36828 librpc: Fix a "ignoring asprintf return" warning

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


- Log -----------------------------------------------------------------
commit 7091755c5834f74170b26a6f1e59c98a9051260d
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Jun 5 15:07:07 2014 +0200

    selftest: Add support for tmate.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Fri Jun  6 02:25:52 CEST 2014 on sn-devel-104

commit fae59b494bd223fe11ba91a2ca62fc0f4fc396ff
Author: Michael Adam <obnox at samba.org>
Date:   Thu Jun 5 23:50:30 2014 +0200

    lib: Bump socket_wrapper version to 1.1.1.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 064592d9cb6349e625b881cfcfab37b19d141ebe
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Jun 5 23:38:59 2014 +0200

    swrap: Disable incomplete bind checks (and tests) for EADDRINUSE.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit f6023bbd67f52907c79a2ab792b461582b0e482d
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:15:34 2014 +0200

    lib: Bump socket_wrapper version to 1.1.0.

commit b9d6ad85a8711a86a7955e8c7ca17f0838b61008
Author: Michael Adam <obnox at samba.org>
Date:   Tue Jun 3 15:14:44 2014 +0200

    swrap: check whether an address:port is already in use in swrap_bind()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 05c1e2db225be256da604d241da08ee0dc5ce0be
Author: Michael Adam <obnox at samba.org>
Date:   Tue Jun 3 15:13:59 2014 +0200

    swrap: implement check_addr_port_in_use()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f9ddd20c2d51475f82e563f26232b9944ebba799
Author: Michael Adam <obnox at samba.org>
Date:   Tue Jun 3 15:13:02 2014 +0200

    swrap: fix AF_UNSPEC special case in swrap_bind()
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 8f28674b50e68e4f7815cd843088f54be3d074a4
Author: Michael Adam <obnox at samba.org>
Date:   Tue Jun 3 15:12:34 2014 +0200

    swrap: extend input checks in swrap_bind()
    
    Not only check family, but depending on family, also check the length.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 3700a4625cdf9b5fa6a665157ddb13b60ed61869
Author: Michael Adam <obnox at samba.org>
Date:   Tue Jun 3 15:11:46 2014 +0200

    swrap: add check for rpc/rpc.h - needed on freebsd for bindresvport
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 6e6c817fd01112fdb137df666b3046757d0276d3
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:10:19 2014 +0200

    swrap: Add support for bindresvport().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 1b949b5d6ce6ca24f61c8b327f3234c0a864740c
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:08:57 2014 +0200

    swrap: Add missing family check in bind().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 5ee936d7e2afd5c570fcf848d2f1009949ca4e64
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:08:07 2014 +0200

    swrap: Setup myname in swrap_socket() for getsockname().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 1f03de017bdf16619a7e8785d1c6042995312a87
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:07:07 2014 +0200

    swrap: Make sure cmbuf is not NULL.
    
    CID 63532
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 74ade40e3efe1cc779c636e5b6a8ea96ae349c52
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:06:33 2014 +0200

    swrap: We need to pass a pointer-pointer to not leak memory.
    
    CID 63533
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

commit 353709b3f35cffa8a8003dc2e7f4371f8fe90c0a
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:05:56 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 3689addffbcd351e2ac0b62834b976a01c6200e0
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:05:12 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 efe4eb2385b4fbbc6f38e62082336bf39820b416
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:04:45 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 6a35c6777d65cedaac51ac96cc47223807b15592
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:04:18 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 2fe96124369fa51e18d83f7b90a8735047fa7012
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:03:41 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 c704966f7980a9de333045fec8f5418abda57a5b
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:03:03 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 0247bdbbc8a3b0ee5d0186a6a9f0d58e03469618
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:02:17 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 aa1e24ead4712728cdc3bdd46c5171b1ac12bd23
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:01:34 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 7556e1388f3eb84ea5c12940e578076b2438f78c
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 15:00:18 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 7a386b33086c6afba587443f1eeb4645399a965e
Author: Pino Toscano <toscano.pino at tiscali.it>
Date:   Tue Jun 3 14:59:21 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>

commit f288efcd78d45ac8fe0ead7c7960cfe60a909ed2
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:58:24 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 1df081058326afb655f2860439b7b8c23403423b
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:57:35 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 fb308daaa038d966cf0385313a9b58ab24164773
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:57:08 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 b534c45a2a0689d4ff781772ebf75d2fa3d2a110
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:56:28 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 d5b204cefd8f9981d20adfb9578636008daabc38
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:55:49 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 56d5bf9af86dfac5431ec9c12096a4a28d337c05
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:55:13 2014 +0200

    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 ed3c219ec5cfd2c491296c753202275d46e488d4
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:54:28 2014 +0200

    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 1921da49c29724df3a51bb8039e99749466bd0de
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:53:19 2014 +0200

    waf: Add check for HAVE_STRUCT_IN6_PKTINFO.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>

commit d652e0613e140665ebd83c5bd42ed5ab91bcb2d6
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 3 14:50:53 2014 +0200

    swrap: Correctly set the bind iface address on connect().
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit b5cd09805445bbaee1a8a8198611244281e62861
Author: Pino Toscano <toscano.pino at tiscali.it>
Date:   Tue Jun 3 14:50:05 2014 +0200

    swrap: use LIBC_SO from GNU libc, if available
    
    Look for gnu/lib-names.h and use the LIBC_SO define to dlopen libc, so
    the right library is loaded without manually searching for libc.so.N.
    
    Signed-off-by: Pino Toscano <toscano.pino at tiscali.it>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 lib/socket_wrapper/socket_wrapper.c |  833 ++++++++++++++++++++++++++++++++++-
 lib/socket_wrapper/wscript          |   15 +-
 selftest/in_screen                  |    8 +-
 3 files changed, 839 insertions(+), 17 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 95643aa..afd9343 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -73,6 +73,12 @@
 #include <stdarg.h>
 #include <stdbool.h>
 #include <unistd.h>
+#ifdef HAVE_GNU_LIB_NAMES_H
+#include <gnu/lib-names.h>
+#endif
+#ifdef HAVE_RPC_RPC_H
+#include <rpc/rpc.h>
+#endif
 
 enum swrap_dbglvl_e {
 	SWRAP_LOG_ERROR = 0,
@@ -108,6 +114,13 @@ enum swrap_dbglvl_e {
 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
 #endif
 
+#ifndef ZERO_STRUCTP
+#define ZERO_STRUCTP(x) do { \
+		if ((x) != NULL) \
+			memset((char *)(x), 0, sizeof(*(x))); \
+	} while(0)
+#endif
+
 #ifndef discard_const
 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
 #endif
@@ -116,6 +129,24 @@ 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 */
+
+/*
+ * 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; \
@@ -196,9 +227,13 @@ struct socket_info
 	int is_server;
 	int connected;
 	int defer_connect;
+	int pktinfo;
 
 	char *tmp_path;
 
+	struct sockaddr *bindname;
+	socklen_t bindname_len;
+
 	struct sockaddr *myname;
 	socklen_t myname_len;
 
@@ -418,6 +453,13 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
 		/* FALL TROUGH */
 	case SWRAP_LIBC:
 		handle = swrap.libc_handle;
+#ifdef LIBC_SO
+		if (handle == NULL) {
+			handle = dlopen(LIBC_SO, flags);
+
+			swrap.libc_handle = handle;
+		}
+#endif
 		if (handle == NULL) {
 			for (handle = NULL, i = 10; handle == NULL && i >= 0; i--) {
 				char soname[256] = {0};
@@ -811,6 +853,7 @@ static const char *socket_wrapper_dir(void)
 	if (s == NULL) {
 		return NULL;
 	}
+	/* TODO use realpath(3) here, when we add support for threads */
 	if (strncmp(s, "./", 2) == 0) {
 		s += 2;
 	}
@@ -1099,6 +1142,21 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 			errno = EADDRNOTAVAIL;
 			return -1;
 		}
+
+		/* Store the bind address for connect() */
+		if (si->bindname == NULL) {
+			struct sockaddr_in bind_in;
+			socklen_t blen = sizeof(struct sockaddr_in);
+
+			ZERO_STRUCT(bind_in);
+			bind_in.sin_family = in->sin_family;
+			bind_in.sin_port = in->sin_port;
+			bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface);
+
+			si->bindname = sockaddr_dup(&bind_in, blen);
+			si->bindname_len = blen;
+		}
+
 		break;
 	}
 #ifdef HAVE_IPV6
@@ -1136,6 +1194,22 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 			return -1;
 		}
 
+		/* Store the bind address for connect() */
+		if (si->bindname == NULL) {
+			struct sockaddr_in6 bind_in;
+			socklen_t blen = sizeof(struct sockaddr_in6);
+
+			ZERO_STRUCT(bind_in);
+			bind_in.sin6_family = in->sin6_family;
+			bind_in.sin6_port = in->sin6_port;
+
+			bind_in.sin6_addr = *swrap_ipv6();
+			bind_in.sin6_addr.s6_addr[15] = iface;
+
+			si->bindname = sockaddr_dup(&bind_in, blen);
+			si->bindname_len = blen;
+		}
+
 		break;
 	}
 #endif
@@ -1161,6 +1235,8 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
 			if (stat(un->sun_path, &st) == 0) continue;
 
 			set_port(si->family, prt, si->myname);
+			set_port(si->family, prt, si->bindname);
+
 			break;
 		}
 		if (prt == 10000) {
@@ -1191,6 +1267,90 @@ static struct socket_info *find_socket_info(int fd)
 	return NULL;
 }
 
+#if 0 /* FIXME */
+static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
+{
+	struct socket_info *s;
+
+	/* first catch invalid input */
+	switch (sa->sa_family) {
+	case AF_INET:
+		if (len < sizeof(struct sockaddr_in)) {
+			return false;
+		}
+		break;
+#if HAVE_IPV6
+	case AF_INET6:
+		if (len < sizeof(struct sockaddr_in6)) {
+			return false;
+		}
+		break;
+#endif
+	default:
+		return false;
+		break;
+	}
+
+	for (s = sockets; s != NULL; s = s->next) {
+		if (s->myname == NULL) {
+			continue;
+		}
+		if (s->myname->sa_family != sa->sa_family) {
+			continue;
+		}
+		switch (s->myname->sa_family) {
+		case AF_INET: {
+			struct sockaddr_in *sin1, *sin2;
+
+			sin1 = (struct sockaddr_in *)s->myname;
+			sin2 = (struct sockaddr_in *)sa;
+
+			if (sin1->sin_addr.s_addr == htonl(INADDR_ANY)) {
+				continue;
+			}
+			if (sin1->sin_port != sin2->sin_port) {
+				continue;
+			}
+			if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
+				continue;
+			}
+
+			/* found */
+			return true;
+			break;
+		}
+#if HAVE_IPV6
+		case AF_INET6: {
+			struct sockaddr_in6 *sin1, *sin2;
+
+			sin1 = (struct sockaddr_in6 *)s->myname;
+			sin2 = (struct sockaddr_in6 *)sa;
+
+			if (sin1->sin6_port != sin2->sin6_port) {
+				continue;
+			}
+			if (!IN6_ARE_ADDR_EQUAL(&sin1->sin6_addr,
+						&sin2->sin6_addr))
+			{
+				continue;
+			}
+
+			/* found */
+			return true;
+			break;
+		}
+#endif
+		default:
+			continue;
+			break;
+
+		}
+	}
+
+	return false;
+}
+#endif
+
 static void swrap_remove_stale(int fd)
 {
 	struct socket_info *si = find_socket_info(fd);
@@ -1233,6 +1393,26 @@ static int sockaddr_convert_to_un(struct socket_info *si,
 #endif
 
 	switch (in_addr->sa_family) {
+	case AF_UNSPEC: {
+		struct sockaddr_in *sin;
+		if (si->family != AF_INET) {
+			break;
+		}
+		if (in_len < sizeof(struct sockaddr_in)) {
+			break;
+		}
+		sin = (struct sockaddr_in *)in_addr;
+		if(sin->sin_addr.s_addr != htonl(INADDR_ANY)) {
+			break;
+		}
+
+		/*
+		 * Note: in the special case of AF_UNSPEC and INADDR_ANY,
+		 * AF_UNSPEC is mapped to AF_INET and must be treated here.
+		 */
+
+		/* FALL THROUGH */
+	}
 	case AF_INET:
 #ifdef HAVE_IPV6
 	case AF_INET6:
@@ -2158,8 +2338,40 @@ static int swrap_socket(int family, int type, int protocol)
 	si->type = real_type;
 	si->protocol = protocol;
 
+	/*
+	 * Setup myname so getsockname() can succeed to find out the socket
+	 * type.
+	 */
+	switch(si->family) {
+	case AF_INET: {
+		struct sockaddr_in sin = {
+			.sin_family = AF_INET,
+		};
+
+		si->myname_len = sizeof(struct sockaddr_in);
+		si->myname = sockaddr_dup(&sin, si->myname_len);
+		break;
+	}
+	case AF_INET6: {
+		struct sockaddr_in6 sin6 = {
+			.sin6_family = AF_INET6,
+		};
+
+		si->myname_len = sizeof(struct sockaddr_in6);
+		si->myname = sockaddr_dup(&sin6, si->myname_len);
+		break;
+	}
+	default:
+		free(si);
+		errno = EINVAL;
+		return -1;
+	}
+
 	fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
 	if (fi == NULL) {
+		if (si->myname != NULL) {
+			free (si->myname);
+		}
 		free(si);
 		errno = ENOMEM;
 		return -1;
@@ -2438,6 +2650,7 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 		in.sin_addr.s_addr = htonl(127<<24 | 
 					   socket_wrapper_default_iface());
 
+		free(si->myname);
 		si->myname_len = sizeof(in);
 		si->myname = sockaddr_dup(&in, si->myname_len);
 		break;
@@ -2467,6 +2680,7 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family)
 		in6.sin6_family = AF_INET6;
 		in6.sin6_addr = *swrap_ipv6();
 		in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
+		free(si->myname);
 		si->myname_len = sizeof(in6);
 		si->myname = sockaddr_dup(&in6, si->myname_len);
 		break;
@@ -2575,6 +2789,23 @@ static int swrap_connect(int s, const struct sockaddr *serv_addr,
 		si->peername = sockaddr_dup(serv_addr, addrlen);
 		si->connected = 1;
 
+		/*
+		 * When we connect() on a socket than we have to bind the
+		 * outgoing connection on the interface we use for the
+		 * transport. We already bound it on the right interface
+		 * but here we have to update the name so getsockname()
+		 * returns correct information.
+		 */
+		if (si->bindname != NULL) {
+			free(si->myname);
+
+			si->myname = si->bindname;
+			si->myname_len = si->bindname_len;
+
+			si->bindname = NULL;
+			si->bindname_len = 0;
+		}
+
 		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
 		swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
 	} else {
@@ -2598,11 +2829,74 @@ static int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
 	int ret;
 	struct sockaddr_un un_addr;
 	struct socket_info *si = find_socket_info(s);
+	int bind_error = 0;
+#if 0 /* FIXME */
+	bool in_use;
+#endif
 
 	if (!si) {
 		return libc_bind(s, myaddr, addrlen);
 	}
 
+	switch (si->family) {
+	case AF_INET: {
+		const struct sockaddr_in *sin;
+		if (addrlen < sizeof(struct sockaddr_in)) {
+			bind_error = EINVAL;
+			break;
+		}
+
+		sin = (struct sockaddr_in *)myaddr;
+
+		if (sin->sin_family != AF_INET) {
+			bind_error = EAFNOSUPPORT;
+		}
+
+		/* special case for AF_UNSPEC */
+		if (sin->sin_family == AF_UNSPEC &&
+		    (sin->sin_addr.s_addr == htonl(INADDR_ANY)))
+		{
+			bind_error = 0;
+		}
+
+		break;
+	}
+#ifdef HAVE_IPV6
+	case AF_INET6: {
+		const struct sockaddr_in6 *sin6;
+		if (addrlen < sizeof(struct sockaddr_in6)) {
+			bind_error = EINVAL;
+			break;
+		}
+
+		sin6 = (struct sockaddr_in6 *)myaddr;
+
+		if (sin6->sin6_family != AF_INET6) {
+			bind_error = EAFNOSUPPORT;
+		}
+
+		break;
+	}
+#endif
+	default:
+		bind_error = EINVAL;
+		break;
+	}
+
+	if (bind_error != 0) {
+		errno = bind_error;
+		return -1;
+	}
+
+#if 0 /* FIXME */
+	in_use = check_addr_port_in_use(myaddr, addrlen);
+	if (in_use) {
+		errno = EADDRINUSE;
+		return -1;
+	}
+#endif
+
+	free(si->myname);
 	si->myname_len = addrlen;
 	si->myname = sockaddr_dup(myaddr, addrlen);
 
@@ -2631,6 +2925,86 @@ int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
 }
 
 /****************************************************************************
+ *   BINDRESVPORT
+ ***************************************************************************/
+
+#ifdef HAVE_BINDRESVPORT
+static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen);
+
+static int swrap_bindresvport_sa(int sd, struct sockaddr *sa)
+{
+	struct sockaddr_storage myaddr;
+	socklen_t salen;
+	static uint16_t port;
+	uint16_t i;
+	int rc = -1;
+	int af;
+
+#define SWRAP_STARTPORT 600
+#define SWRAP_ENDPORT (IPPORT_RESERVED - 1)
+#define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1)
+
+	if (port == 0) {
+		port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT;
+	}
+
+	if (sa == NULL) {
+		salen = sizeof(struct sockaddr);
+		sa = (struct sockaddr *)&myaddr;
+
+		rc = swrap_getsockname(sd, (struct sockaddr *)&myaddr, &salen);
+		if (rc < 0) {
+			return -1;
+		}
+
+		af = sa->sa_family;
+		memset(&myaddr, 0, salen);
+	} else {
+		af = sa->sa_family;
+	}
+
+	for (i = 0; i < SWRAP_NPORTS; i++, port++) {
+		switch(af) {
+		case AF_INET: {
+			struct sockaddr_in *sinp = (struct sockaddr_in *)sa;
+
+			salen = sizeof(struct sockaddr_in);
+			sinp->sin_port = htons(port);
+			break;
+		}
+		case AF_INET6: {
+			struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)sa;
+
+			salen = sizeof(struct sockaddr_in6);
+			sin6p->sin6_port = htons(port);
+			break;
+		}
+		default:
+			errno = EAFNOSUPPORT;
+			return -1;
+		}
+		sa->sa_family = af;
+
+		if (port > SWRAP_ENDPORT) {
+			port = SWRAP_STARTPORT;
+		}
+
+		rc = swrap_bind(sd, (struct sockaddr *)sa, salen);
+		if (rc == 0 || errno != EADDRINUSE) {
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int bindresvport(int sockfd, struct sockaddr_in *sinp)
+{
+	return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list