[SCM] Socket Wrapper Repository - branch master updated
Michael Adam
obnox at samba.org
Thu Oct 20 09:22:56 UTC 2016
The branch, master has been updated
via d8cf3b0 swrap: Handle threads that fork
via c989bbc cmake: Check for constructor attribute
via f5cddcd swrap: Make symbol loading thread-safe
via 201811d cmake: Link pthread library headers
via 3507e18 swrap: Fix strict-aliasing issues while loading symbols
from b61f5df tests: Add a test for max_sockets
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit d8cf3b0ca8ce24aaf19e4692882dadffa921f763
Author: Andreas Schneider <asn at samba.org>
Date: Thu Oct 20 10:37:18 2016 +0200
swrap: Handle threads that fork
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit c989bbc9f6afaad9e4b26501d57d7acb1297d1cb
Author: Andreas Schneider <asn at samba.org>
Date: Thu Oct 20 10:35:50 2016 +0200
cmake: Check for constructor attribute
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit f5cddcd300b779131662519d56ae90fcebe459e1
Author: Andreas Schneider <asn at samba.org>
Date: Thu Oct 20 10:22:40 2016 +0200
swrap: Make symbol loading thread-safe
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
commit 201811dc614a4787482c3bb2fa14f47112a05a34
Author: Michael Adam <obnox at samba.org>
Date: Sun Sep 18 20:28:06 2016 +0200
cmake: Link pthread library headers
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 3507e186d08fa8170a3499c9e69a49aa60ff9dcd
Author: Andreas Schneider <asn at samba.org>
Date: Thu Oct 20 10:56:35 2016 +0200
swrap: Fix strict-aliasing issues while loading symbols
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Michael Adam <obnox at samba.org>
-----------------------------------------------------------------------
Summary of changes:
ConfigureChecks.cmake | 12 ++
config.h.cmake | 1 +
src/CMakeLists.txt | 2 +-
src/socket_wrapper.c | 434 +++++++++++++++++++++++++++++++++-----------------
tests/CMakeLists.txt | 3 +-
5 files changed, 306 insertions(+), 146 deletions(-)
Changeset truncated at 500 lines:
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 48455ef..71b34ce 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -172,6 +172,18 @@ int main(void) {
}" HAVE_SOCKADDR_STORAGE)
check_c_source_compiles("
+void test_constructor_attribute(void) __attribute__ ((constructor));
+
+void test_constructor_attribute(void)
+{
+ return;
+}
+
+int main(void) {
+ return 0;
+}" HAVE_CONSTRUCTOR_ATTRIBUTE)
+
+check_c_source_compiles("
void test_destructor_attribute(void) __attribute__ ((destructor));
void test_destructor_attribute(void)
diff --git a/config.h.cmake b/config.h.cmake
index a9b8ce8..6786b8a 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -58,6 +58,7 @@
/**************************** OPTIONS ****************************/
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
+#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
#cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
#cmakedefine HAVE_ADDRESS_SANITIZER_ATTRIBUTE 1
#cmakedefine HAVE_SOCKADDR_STORAGE 1
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4b22d77..3b4d7d0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,7 +4,7 @@ include_directories(${CMAKE_BINARY_DIR})
add_library(socket_wrapper SHARED socket_wrapper.c)
-target_link_libraries(socket_wrapper ${SWRAP_REQUIRED_LIBRARIES})
+target_link_libraries(socket_wrapper ${SWRAP_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
install(
TARGETS
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 84dfc07..6679d5c 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -79,6 +79,7 @@
#ifdef HAVE_RPC_RPC_H
#include <rpc/rpc.h>
#endif
+#include <pthread.h>
enum swrap_dbglvl_e {
SWRAP_LOG_ERROR = 0,
@@ -94,6 +95,12 @@ enum swrap_dbglvl_e {
#define PRINTF_ATTRIBUTE(a,b)
#endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
+#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
+#define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
+#else
+#define CONSTRUCTOR_ATTRIBUTE
+#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
+
#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
#define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
#else
@@ -152,6 +159,22 @@ enum swrap_dbglvl_e {
# endif
#endif
+/* Macros for accessing mutexes */
+# define SWRAP_LOCK(m) do { \
+ pthread_mutex_lock(&(m ## _mutex)); \
+} while(0)
+
+# define SWRAP_UNLOCK(m) do { \
+ pthread_mutex_unlock(&(m ## _mutex)); \
+} while(0)
+
+/* Add new global locks here please */
+# define SWRAP_LOCK_ALL \
+ SWRAP_LOCK(libc_symbol_binding); \
+
+# define SWRAP_UNLOCK_ALL \
+ SWRAP_UNLOCK(libc_symbol_binding); \
+
#define SWRAP_DLIST_ADD(list,item) do { \
if (!(list)) { \
@@ -305,9 +328,14 @@ static size_t max_sockets = 0;
*/
static struct socket_info_fd *socket_fds;
+/* The mutex for accessing the global libc.symbols */
+static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
+
/* Function prototypes */
bool socket_wrapper_enabled(void);
+
+void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
#ifdef NDEBUG
@@ -368,86 +396,133 @@ static void swrap_log(enum swrap_dbglvl_e dbglvl,
#include <dlfcn.h>
-struct swrap_libc_fns {
#ifdef HAVE_ACCEPT4
- int (*libc_accept4)(int sockfd,
- struct sockaddr *addr,
- socklen_t *addrlen,
- int flags);
+typedef int (*__libc_accept4)(int sockfd,
+ struct sockaddr *addr,
+ socklen_t *addrlen,
+ int flags);
#else
- int (*libc_accept)(int sockfd,
- struct sockaddr *addr,
- socklen_t *addrlen);
+typedef int (*__libc_accept)(int sockfd,
+ struct sockaddr *addr,
+ socklen_t *addrlen);
#endif
- int (*libc_bind)(int sockfd,
- const struct sockaddr *addr,
- socklen_t addrlen);
- int (*libc_close)(int fd);
- int (*libc_connect)(int sockfd,
- const struct sockaddr *addr,
- socklen_t addrlen);
- int (*libc_dup)(int fd);
- int (*libc_dup2)(int oldfd, int newfd);
- int (*libc_fcntl)(int fd, int cmd, ...);
- FILE *(*libc_fopen)(const char *name, const char *mode);
+typedef int (*__libc_bind)(int sockfd,
+ const struct sockaddr *addr,
+ socklen_t addrlen);
+typedef int (*__libc_close)(int fd);
+typedef int (*__libc_connect)(int sockfd,
+ const struct sockaddr *addr,
+ socklen_t addrlen);
+typedef int (*__libc_dup)(int fd);
+typedef int (*__libc_dup2)(int oldfd, int newfd);
+typedef int (*__libc_fcntl)(int fd, int cmd, ...);
+typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
#ifdef HAVE_EVENTFD
- int (*libc_eventfd)(int count, int flags);
+typedef int (*__libc_eventfd)(int count, int flags);
#endif
- int (*libc_getpeername)(int sockfd,
- struct sockaddr *addr,
- socklen_t *addrlen);
- int (*libc_getsockname)(int sockfd,
- struct sockaddr *addr,
- socklen_t *addrlen);
- int (*libc_getsockopt)(int sockfd,
+typedef int (*__libc_getpeername)(int sockfd,
+ struct sockaddr *addr,
+ socklen_t *addrlen);
+typedef int (*__libc_getsockname)(int sockfd,
+ struct sockaddr *addr,
+ socklen_t *addrlen);
+typedef int (*__libc_getsockopt)(int sockfd,
int level,
int optname,
void *optval,
socklen_t *optlen);
- int (*libc_ioctl)(int d, unsigned long int request, ...);
- int (*libc_listen)(int sockfd, int backlog);
- int (*libc_open)(const char *pathname, int flags, mode_t mode);
- int (*libc_pipe)(int pipefd[2]);
- int (*libc_read)(int fd, void *buf, size_t count);
- ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
- int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
- int (*libc_recvfrom)(int sockfd,
+typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
+typedef int (*__libc_listen)(int sockfd, int backlog);
+typedef int (*__libc_open)(const char *pathname, int flags, mode_t mode);
+typedef int (*__libc_pipe)(int pipefd[2]);
+typedef int (*__libc_read)(int fd, void *buf, size_t count);
+typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
+typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
+typedef int (*__libc_recvfrom)(int sockfd,
void *buf,
size_t len,
int flags,
struct sockaddr *src_addr,
socklen_t *addrlen);
- int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
- int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
- int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
- int (*libc_sendto)(int sockfd,
+typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
+typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags);
+typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
+typedef int (*__libc_sendto)(int sockfd,
const void *buf,
size_t len,
int flags,
const struct sockaddr *dst_addr,
socklen_t addrlen);
- int (*libc_setsockopt)(int sockfd,
+typedef int (*__libc_setsockopt)(int sockfd,
int level,
int optname,
const void *optval,
socklen_t optlen);
#ifdef HAVE_SIGNALFD
- int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
+typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
#endif
- int (*libc_socket)(int domain, int type, int protocol);
- int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
+typedef int (*__libc_socket)(int domain, int type, int protocol);
+typedef int (*__libc_socketpair)(int domain, int type, int protocol, int sv[2]);
#ifdef HAVE_TIMERFD_CREATE
- int (*libc_timerfd_create)(int clockid, int flags);
+typedef int (*__libc_timerfd_create)(int clockid, int flags);
#endif
- ssize_t (*libc_write)(int fd, const void *buf, size_t count);
- ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
+typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count);
+typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt);
+
+#define SWRAP_SYMBOL_ENTRY(i) \
+ union { \
+ __libc_##i f; \
+ void *obj; \
+ } _libc_##i
+
+struct swrap_libc_symbols {
+#ifdef HAVE_ACCEPT4
+ SWRAP_SYMBOL_ENTRY(accept4);
+#else
+ SWRAP_SYMBOL_ENTRY(accept);
+#endif
+ SWRAP_SYMBOL_ENTRY(bind);
+ SWRAP_SYMBOL_ENTRY(close);
+ SWRAP_SYMBOL_ENTRY(connect);
+ SWRAP_SYMBOL_ENTRY(dup);
+ SWRAP_SYMBOL_ENTRY(dup2);
+ SWRAP_SYMBOL_ENTRY(fcntl);
+ SWRAP_SYMBOL_ENTRY(fopen);
+#ifdef HAVE_EVENTFD
+ SWRAP_SYMBOL_ENTRY(eventfd);
+#endif
+ SWRAP_SYMBOL_ENTRY(getpeername);
+ SWRAP_SYMBOL_ENTRY(getsockname);
+ SWRAP_SYMBOL_ENTRY(getsockopt);
+ SWRAP_SYMBOL_ENTRY(ioctl);
+ SWRAP_SYMBOL_ENTRY(listen);
+ SWRAP_SYMBOL_ENTRY(open);
+ SWRAP_SYMBOL_ENTRY(pipe);
+ SWRAP_SYMBOL_ENTRY(read);
+ SWRAP_SYMBOL_ENTRY(readv);
+ SWRAP_SYMBOL_ENTRY(recv);
+ SWRAP_SYMBOL_ENTRY(recvfrom);
+ SWRAP_SYMBOL_ENTRY(recvmsg);
+ SWRAP_SYMBOL_ENTRY(send);
+ SWRAP_SYMBOL_ENTRY(sendmsg);
+ SWRAP_SYMBOL_ENTRY(sendto);
+ SWRAP_SYMBOL_ENTRY(setsockopt);
+#ifdef HAVE_SIGNALFD
+ SWRAP_SYMBOL_ENTRY(signalfd);
+#endif
+ SWRAP_SYMBOL_ENTRY(socket);
+ SWRAP_SYMBOL_ENTRY(socketpair);
+ SWRAP_SYMBOL_ENTRY(timerfd_create);
+ SWRAP_SYMBOL_ENTRY(write);
+ SWRAP_SYMBOL_ENTRY(writev);
};
struct swrap {
- void *libc_handle;
- void *libsocket_handle;
-
- struct swrap_libc_fns fns;
+ struct {
+ void *handle;
+ void *socket_handle;
+ struct swrap_libc_symbols symbols;
+ } libc;
};
static struct swrap swrap;
@@ -507,18 +582,18 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
}
}
- swrap.libsocket_handle = handle;
+ swrap.libc.socket_handle = handle;
}
break;
#endif
/* FALL TROUGH */
case SWRAP_LIBC:
- handle = swrap.libc_handle;
+ handle = swrap.libc.handle;
#ifdef LIBC_SO
if (handle == NULL) {
handle = dlopen(LIBC_SO, flags);
- swrap.libc_handle = handle;
+ swrap.libc.handle = handle;
}
#endif
if (handle == NULL) {
@@ -532,14 +607,14 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
}
}
- swrap.libc_handle = handle;
+ swrap.libc.handle = handle;
}
break;
}
if (handle == NULL) {
#ifdef RTLD_NEXT
- handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
+ handle = swrap.libc.handle = swrap.libc.socket_handle = RTLD_NEXT;
#else
SWRAP_LOG(SWRAP_LOG_ERROR,
"Failed to dlopen library: %s\n",
@@ -551,7 +626,7 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
return handle;
}
-static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
+static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
{
void *handle;
void *func;
@@ -561,24 +636,43 @@ static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
func = dlsym(handle, fn_name);
if (func == NULL) {
SWRAP_LOG(SWRAP_LOG_ERROR,
- "Failed to find %s: %s\n",
- fn_name, dlerror());
+ "Failed to find %s: %s\n",
+ fn_name,
+ dlerror());
exit(-1);
}
SWRAP_LOG(SWRAP_LOG_TRACE,
- "Loaded %s from %s",
- fn_name, swrap_str_lib(lib));
+ "Loaded %s from %s",
+ fn_name,
+ swrap_str_lib(lib));
+
return func;
}
-#define swrap_load_lib_function(lib, fn_name) \
- if (swrap.fns.libc_##fn_name == NULL) { \
- void *swrap_cast_ptr = _swrap_load_lib_function(lib, #fn_name); \
- *(void **) (&swrap.fns.libc_##fn_name) = \
- swrap_cast_ptr; \
- }
+#define swrap_bind_symbol_libc(sym_name) \
+ SWRAP_LOCK(libc_symbol_binding); \
+ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+ swrap.libc.symbols._libc_##sym_name.obj = \
+ _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
+ } \
+ SWRAP_UNLOCK(libc_symbol_binding)
+
+#define swrap_bind_symbol_libsocket(sym_name) \
+ SWRAP_LOCK(libc_symbol_binding); \
+ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+ swrap.libc.symbols._libc_##sym_name.obj = \
+ _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \
+ } \
+ SWRAP_UNLOCK(libc_symbol_binding)
+#define swrap_bind_symbol_libnsl(sym_name) \
+ SWRAP_LOCK(libc_symbol_binding); \
+ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+ swrap.libc.symbols._libc_##sym_name.obj = \
+ _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \
+ } \
+ SWRAP_UNLOCK(libc_symbol_binding)
/*
* IMPORTANT
@@ -594,18 +688,18 @@ static int libc_accept4(int sockfd,
socklen_t *addrlen,
int flags)
{
- swrap_load_lib_function(SWRAP_LIBSOCKET, accept4);
+ swrap_bind_symbol_libsocket(accept4);
- return swrap.fns.libc_accept4(sockfd, addr, addrlen, flags);
+ return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
}
#else /* HAVE_ACCEPT4 */
static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
- swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
+ swrap_bind_symbol_libsocket(accept);
- return swrap.fns.libc_accept(sockfd, addr, addrlen);
+ return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
}
#endif /* HAVE_ACCEPT4 */
@@ -613,47 +707,47 @@ static int libc_bind(int sockfd,
const struct sockaddr *addr,
socklen_t addrlen)
{
- swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
+ swrap_bind_symbol_libsocket(bind);
- return swrap.fns.libc_bind(sockfd, addr, addrlen);
+ return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
}
static int libc_close(int fd)
{
- swrap_load_lib_function(SWRAP_LIBC, close);
+ swrap_bind_symbol_libc(close);
- return swrap.fns.libc_close(fd);
+ return swrap.libc.symbols._libc_close.f(fd);
}
static int libc_connect(int sockfd,
const struct sockaddr *addr,
socklen_t addrlen)
{
- swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
+ swrap_bind_symbol_libsocket(connect);
- return swrap.fns.libc_connect(sockfd, addr, addrlen);
+ return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
}
static int libc_dup(int fd)
{
- swrap_load_lib_function(SWRAP_LIBC, dup);
+ swrap_bind_symbol_libc(dup);
- return swrap.fns.libc_dup(fd);
+ return swrap.libc.symbols._libc_dup.f(fd);
}
static int libc_dup2(int oldfd, int newfd)
{
- swrap_load_lib_function(SWRAP_LIBC, dup2);
+ swrap_bind_symbol_libc(dup2);
- return swrap.fns.libc_dup2(oldfd, newfd);
+ return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
}
#ifdef HAVE_EVENTFD
static int libc_eventfd(int count, int flags)
{
- swrap_load_lib_function(SWRAP_LIBC, eventfd);
+ swrap_bind_symbol_libc(eventfd);
- return swrap.fns.libc_eventfd(count, flags);
+ return swrap.libc.symbols._libc_eventfd.f(count, flags);
}
#endif
@@ -664,18 +758,18 @@ static int libc_vfcntl(int fd, int cmd, va_list ap)
int rc;
int i;
- swrap_load_lib_function(SWRAP_LIBC, fcntl);
+ swrap_bind_symbol_libc(fcntl);
for (i = 0; i < 4; i++) {
args[i] = va_arg(ap, long int);
}
- rc = swrap.fns.libc_fcntl(fd,
- cmd,
- args[0],
- args[1],
- args[2],
- args[3]);
+ rc = swrap.libc.symbols._libc_fcntl.f(fd,
+ cmd,
+ args[0],
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list