[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