[SCM] Socket Wrapper Repository - branch master updated
Andreas Schneider
asn at samba.org
Thu May 3 11:16:14 UTC 2018
The branch, master has been updated
via 7b01e29 cmake: Run threaded tests with helgrind
via 1ff35b6 tests: Add test case to validate free-list indexes
via da1fe44 swrap: Update free-list only when refcount is zero
via 7299ab3 swrap: Move metadata into socket_info_meta structure
via 01ceb51 tests: New threaded test cases
via c48282b tests: Modify echo server to accept multiple connections
via a5c0851 tests: Add new test to check mutex lock contention
via b6909fc swrap: Implement thread safety using pthread mutexes
via 501b5f3 swrap: Rearrange swrap_remove_stale
via 64c8487 swrap: Rearrange swrap_close
via 548f4d0 swrap: Remove swrap_first_free_index
via d0b13ef swrap: Use swrap_create_socket within swrap_accept
via e30b080 swrap: Use swrap_create_socket within swrap_socket
via 9702a15 swrap: Add new routines to handle socket creation
via 327cb50 swrap: Internal reorganization of core socket_info structures
via b1728e6 swrap: Reorder code inside swrap_socket
via 203a279 swrap: Use swrap_get_socket_info inside socket_wrapper_first_free_index
via 6661997 swrap: set errno to ENFILE if there is no more free socket_info
via aec1e12 swrap: New helper functions to treat next_free
via 10b6cc0 swrap: Use helper functions to manage refcount
via f55c1be swrap: Use helper function swrap_get_socket_info
via a685112 swrap: Make early-libc-out more obvious by removing else
from f152f98 tests: Increase wait time for setup and teardown to 5ms
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 7b01e29d2c95216c842b56b89c88e900cfb4991b
Author: Andreas Schneider <asn at samba.org>
Date: Wed May 2 17:05:21 2018 +0200
cmake: Run threaded tests with helgrind
Signed-off-by: Andreas Schneider <asn at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 1ff35b6bb9a2702c4b0785281f22018b05e549c8
Author: Anoop C S <anoopcs at redhat.com>
Date: Wed Jan 31 22:43:21 2018 +0530
tests: Add test case to validate free-list indexes
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit da1fe44b27ce2dc66d795637c13bc13b2a657b79
Author: Anoop C S <anoopcs at redhat.com>
Date: Wed Jan 31 22:46:23 2018 +0530
swrap: Update free-list only when refcount is zero
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 7299ab3541c94f38ee62a9d39348bbeb438bfc1a
Author: Michael Adam <obnox at samba.org>
Date: Thu Jul 13 01:25:19 2017 +0200
swrap: Move metadata into socket_info_meta structure
Separating out the metadata related information to another
sub-structure to make it more clean and structured.
Pair-Programmed-With: Anoop C S <anoopcs at redhat.com>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 01ceb512ccfb60431754fb40704c9fcfb46fc4ac
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Mar 2 07:26:20 2017 +0000
tests: New threaded test cases
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit c48282b7920b6b0037d08b181403042731585d21
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Mar 2 07:12:50 2017 +0000
tests: Modify echo server to accept multiple connections
In context of multiple threads, echo server must be capable of
accepting connections in a loop rather than be satisfied with
one incoming connection.
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit a5c08518e985bd3f0cb274c274c034be37fa5629
Author: Michael Adam <obnox at samba.org>
Date: Thu Sep 22 03:53:27 2016 +0200
tests: Add new test to check mutex lock contention
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit b6909fc91d5d16ced108700cbd5cd8a13481a6c4
Author: Anoop C S <anoopcs at redhat.com>
Date: Tue Mar 28 07:13:47 2017 +0000
swrap: Implement thread safety using pthread mutexes
Added a new mutex variable to socket_info structure along with
new macros for locking and unlocking mutex corresponding to
each socket_info entry. Apart from individual mutex defined in
socket_info structure, 4 new mutexes are added to protect the
concurrent access of globally used swrap parameters from different
threads.
All other individual wrappers and helper routines are also made
capable of acquiring relevant mutex locks before operating on such
global parameters.
Pair-Programmed-With: Michael Adam <obnox at samba.org>
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 501b5f3e6444117dab213f8a3dfdda0a860ecde9
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Jul 13 15:13:07 2017 +0530
swrap: Rearrange swrap_remove_stale
In preparation to implement thread safety, re-ordering lines
of code to properly align to lockign calls
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 64c848748077f31a95b5338d8d6e92050b43e0fc
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Jul 13 15:20:15 2017 +0530
swrap: Rearrange swrap_close
In preparation to implement thread safety, re-ordering lines
of code to properly align to locking calls.
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 548f4d062b06e2cff7fadb0d1ee7de34c1223a8a
Author: Anoop C S <anoopcs at redhat.com>
Date: Tue Aug 29 14:29:16 2017 +0530
swrap: Remove swrap_first_free_index
swrap_first_free_index is no longer used as the whole logic now
implemented within swrap_create_socket.
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit d0b13efcd590722784baaca85bb5c9b0d5ee2d92
Author: Anoop C S <anoopcs at redhat.com>
Date: Tue Aug 29 14:34:58 2017 +0530
swrap: Use swrap_create_socket within swrap_accept
Replace the current logic of socket creation within swrap_accept
with more cleaner version using swrap_create_socket.
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit e30b080e3188c4498af322c8464569489365d0c3
Author: Anoop C S <anoopcs at redhat.com>
Date: Tue Aug 29 14:34:28 2017 +0530
swrap: Use swrap_create_socket within swrap_socket
Replace the current logic of socket creation within swrap_socket
with more cleaner version using swrap_create_socket.
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 9702a15c2560988fe87119aa45787f935bef66fd
Author: Anoop C S <anoopcs at redhat.com>
Date: Tue Aug 29 12:40:35 2017 +0530
swrap: Add new routines to handle socket creation
A new function named swrap_create_socket is introduced which
cleanly performs all stuff related to creation of new socket
file descriptors and updation of relevant metadata including
the free-list and reference counter.
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 327cb50d8370833bad9d260b9dc8f5c70fb5e2ce
Author: Michael Adam <obnox at samba.org>
Date: Sat Jul 15 14:40:07 2017 +0530
swrap: Internal reorganization of core socket_info structures
The change basically splits socket_info structure into
two structures, namely,
- socket_info: to store the core information
corresponding to a socket entry.
- socket_info_container: wrapping structure to hold
the socket_info data as well as metadata(currently
refcount and next_free).
Pair-Programmed-With: Anoop C S <anoopcs at redhat.com>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit b1728e6754a0b864f70653fea8d91aa8f57ada6e
Author: Michael Adam <obnox at samba.org>
Date: Wed Aug 2 13:56:09 2017 +0200
swrap: Reorder code inside swrap_socket
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 203a2793dd67461e01cd4267a35bbdc0cb8a162d
Author: Michael Adam <obnox at samba.org>
Date: Tue Jul 18 12:53:03 2017 +0200
swrap: Use swrap_get_socket_info inside socket_wrapper_first_free_index
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 6661997701aef9f609465b3a1863cf03402bc06a
Author: Michael Adam <obnox at samba.org>
Date: Tue Jul 18 12:50:15 2017 +0200
swrap: set errno to ENFILE if there is no more free socket_info
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit aec1e1207d70f1b2a12a3cb3641691bb99ba7581
Author: Michael Adam <obnox at samba.org>
Date: Thu Jul 13 01:01:57 2017 +0200
swrap: New helper functions to treat next_free
- swrap_get_next_free
- swrap_set_next_free
to avoid accessing socket_info.next_free directly
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 10b6cc0ff0891b345d7f71dac44be963792ca32d
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Mar 1 10:39:20 2018 +0530
swrap: Use helper functions to manage refcount
- swrap_get_refcount
- swrap_alter_refcount
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit f55c1be920a989f4ec7f946eb7c17960fc3cf489
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Mar 1 10:34:54 2018 +0530
swrap: Use helper function swrap_get_socket_info
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Reviewed-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit a68511296862f48158a7f3623bb94e883b936b2a
Author: Michael Adam <obnox at samba.org>
Date: Thu Jul 13 02:40:11 2017 +0200
swrap: Make early-libc-out more obvious by removing else
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
-----------------------------------------------------------------------
Summary of changes:
DefineOptions.cmake | 1 +
src/socket_wrapper.c | 508 +++++++++++++++------
tests/CMakeLists.txt | 37 +-
tests/echo_srv.c | 58 ++-
tests/test_max_sockets.c | 4 +-
tests/test_tcp_socket_overwrite.c | 74 +++
...cp_connect.c => test_thread_echo_tcp_connect.c} | 59 ++-
...sg.c => test_thread_echo_tcp_sendmsg_recvmsg.c} | 150 +++---
...te_read.c => test_thread_echo_tcp_write_read.c} | 79 +---
...end_recv.c => test_thread_echo_udp_send_recv.c} | 78 +---
tests/test_thread_sockets.c | 72 +++
11 files changed, 730 insertions(+), 390 deletions(-)
create mode 100644 tests/test_tcp_socket_overwrite.c
copy tests/{test_echo_tcp_connect.c => test_thread_echo_tcp_connect.c} (59%)
copy tests/{test_echo_tcp_sendmsg_recvmsg.c => test_thread_echo_tcp_sendmsg_recvmsg.c} (68%)
copy tests/{test_echo_tcp_write_read.c => test_thread_echo_tcp_write_read.c} (56%)
copy tests/{test_echo_udp_send_recv.c => test_thread_echo_udp_send_recv.c} (58%)
create mode 100644 tests/test_thread_sockets.c
Changeset truncated at 500 lines:
diff --git a/DefineOptions.cmake b/DefineOptions.cmake
index 6030e79..54e65e1 100644
--- a/DefineOptions.cmake
+++ b/DefineOptions.cmake
@@ -1 +1,2 @@
option(UNIT_TESTING "Build with unit tests" OFF)
+option(HELGRIND_TESTING "Run threaded unit tests with helgrind" OFF)
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 02fe970..6c9ec51 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -185,8 +185,20 @@ enum swrap_dbglvl_e {
# define SWRAP_UNLOCK_ALL \
SWRAP_UNLOCK(libc_symbol_binding); \
+#define SOCKET_INFO_CONTAINER(si) \
+ (struct socket_info_container *)(si)
-#define SWRAP_DLIST_ADD(list,item) do { \
+#define SWRAP_LOCK_SI(si) do { \
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
+ pthread_mutex_lock(&sic->meta.mutex); \
+} while(0)
+
+#define SWRAP_UNLOCK_SI(si) do { \
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \
+ pthread_mutex_unlock(&sic->meta.mutex); \
+} while(0)
+
+#define DLIST_ADD(list, item) do { \
if (!(list)) { \
(item)->prev = NULL; \
(item)->next = NULL; \
@@ -199,7 +211,13 @@ enum swrap_dbglvl_e {
} \
} while (0)
-#define SWRAP_DLIST_REMOVE(list,item) do { \
+#define SWRAP_DLIST_ADD(list, item) do { \
+ SWRAP_LOCK(list); \
+ DLIST_ADD(list, item); \
+ SWRAP_UNLOCK(list); \
+} while (0)
+
+#define DLIST_REMOVE(list, item) do { \
if ((list) == (item)) { \
(list) = (item)->next; \
if (list) { \
@@ -217,10 +235,15 @@ enum swrap_dbglvl_e {
(item)->next = NULL; \
} while (0)
-#define SWRAP_DLIST_ADD_AFTER(list, item, el) \
-do { \
+#define SWRAP_DLIST_REMOVE(list,item) do { \
+ SWRAP_LOCK(list); \
+ DLIST_REMOVE(list, item); \
+ SWRAP_UNLOCK(list); \
+} while (0)
+
+#define DLIST_ADD_AFTER(list, item, el) do { \
if ((list) == NULL || (el) == NULL) { \
- SWRAP_DLIST_ADD(list, item); \
+ DLIST_ADD(list, item); \
} else { \
(item)->prev = (el); \
(item)->next = (el)->next; \
@@ -231,6 +254,12 @@ do { \
} \
} while (0)
+#define SWRAP_DLIST_ADD_AFTER(list, item, el) do { \
+ SWRAP_LOCK(list); \
+ DLIST_ADD_AFTER(list, item, el); \
+ SWRAP_UNLOCK(list); \
+} while (0)
+
#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
#else
@@ -302,10 +331,6 @@ int first_free;
struct socket_info
{
- unsigned int refcount;
-
- int next_free;
-
int family;
int type;
int protocol;
@@ -330,7 +355,20 @@ struct socket_info
} io;
};
-static struct socket_info *sockets;
+struct socket_info_meta
+{
+ unsigned int refcount;
+ int next_free;
+ pthread_mutex_t mutex;
+};
+
+struct socket_info_container
+{
+ struct socket_info info;
+ struct socket_info_meta meta;
+};
+
+static struct socket_info_container *sockets;
static size_t max_sockets = 0;
/*
@@ -343,6 +381,26 @@ 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;
+/* The mutex for syncronizing the port selection during swrap_auto_bind() */
+static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * Global mutex to guard the initialization of array of socket_info structures.
+ */
+static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * Global mutex to protect modification of the socket_fds linked
+ * list structure by different threads within a process.
+ */
+static pthread_mutex_t socket_fds_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * Global mutex to synchronize the query for first free index in array of
+ * socket_info structures by different threads within a process.
+ */
+static pthread_mutex_t first_free_mutex = PTHREAD_MUTEX_INITIALIZER;
+
/* Function prototypes */
bool socket_wrapper_enabled(void);
@@ -1194,6 +1252,45 @@ static size_t socket_length(int family)
return 0;
}
+static struct socket_info *swrap_get_socket_info(int si_index)
+{
+ return (struct socket_info *)(&(sockets[si_index].info));
+}
+
+static int swrap_get_refcount(struct socket_info *si)
+{
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
+ return sic->meta.refcount;
+}
+
+static void swrap_inc_refcount(struct socket_info *si)
+{
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
+
+ sic->meta.refcount += 1;
+}
+
+static void swrap_dec_refcount(struct socket_info *si)
+{
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
+
+ sic->meta.refcount -= 1;
+}
+
+static int swrap_get_next_free(struct socket_info *si)
+{
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
+
+ return sic->meta.next_free;
+}
+
+static void swrap_set_next_free(struct socket_info *si, int next_free)
+{
+ struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si);
+
+ sic->meta.next_free = next_free;
+}
+
static const char *socket_wrapper_dir(void)
{
const char *s = getenv("SOCKET_WRAPPER_DIR");
@@ -1278,28 +1375,39 @@ static void socket_wrapper_init_sockets(void)
{
size_t i;
+ SWRAP_LOCK(sockets);
+
if (sockets != NULL) {
+ SWRAP_UNLOCK(sockets);
return;
}
max_sockets = socket_wrapper_max_sockets();
- sockets = (struct socket_info *)calloc(max_sockets,
- sizeof(struct socket_info));
+ sockets = (struct socket_info_container *)calloc(max_sockets,
+ sizeof(struct socket_info_container));
if (sockets == NULL) {
SWRAP_LOG(SWRAP_LOG_ERROR,
"Failed to allocate sockets array.\n");
+ SWRAP_UNLOCK(sockets);
exit(-1);
}
+ SWRAP_LOCK(first_free);
+
first_free = 0;
for (i = 0; i < max_sockets; i++) {
- sockets[i].next_free = i+1;
+ swrap_set_next_free(&sockets[i].info, i+1);
+ sockets[i].meta.mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
}
- sockets[max_sockets-1].next_free = -1;
+ /* mark the end of the free list */
+ swrap_set_next_free(&sockets[max_sockets-1].info, -1);
+
+ SWRAP_UNLOCK(first_free);
+ SWRAP_UNLOCK(sockets);
}
bool socket_wrapper_enabled(void)
@@ -1330,23 +1438,62 @@ static unsigned int socket_wrapper_default_iface(void)
return 1;/* 127.0.0.1 */
}
-/*
- * Return the first free entry (if any) and make
- * it re-usable again (by nulling it out)
- */
-static int socket_wrapper_first_free_index(void)
+static int swrap_add_socket_info(struct socket_info *si_input)
{
- int next_free;
+ struct socket_info *si = NULL;
+ int si_index = -1;
+
+ if (si_input == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ SWRAP_LOCK(first_free);
if (first_free == -1) {
+ errno = ENFILE;
+ goto out;
+ }
+
+ si_index = first_free;
+ si = swrap_get_socket_info(si_index);
+
+ SWRAP_LOCK_SI(si);
+
+ first_free = swrap_get_next_free(si);
+ *si = *si_input;
+ swrap_inc_refcount(si);
+
+ SWRAP_UNLOCK_SI(si);
+
+out:
+ SWRAP_UNLOCK(first_free);
+
+ return si_index;
+}
+
+static int swrap_create_socket(struct socket_info *si, int fd)
+{
+ struct socket_info_fd *fi = NULL;
+ int idx;
+
+ fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
+ if (fi == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ idx = swrap_add_socket_info(si);
+ if (idx == -1) {
+ free(fi);
return -1;
}
- next_free = sockets[first_free].next_free;
- ZERO_STRUCT(sockets[first_free]);
- sockets[first_free].next_free = next_free;
+ fi->fd = fd;
+ fi->si_index = idx;
+
+ SWRAP_DLIST_ADD(socket_fds, fi);
- return first_free;
+ return idx;
}
static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
@@ -1720,13 +1867,17 @@ static struct socket_info_fd *find_socket_info_fd(int fd)
{
struct socket_info_fd *f;
+ SWRAP_LOCK(socket_fds);
+
for (f = socket_fds; f; f = f->next) {
if (f->fd == fd) {
- return f;
+ break;
}
}
- return NULL;
+ SWRAP_UNLOCK(socket_fds);
+
+ return f;
}
static int find_socket_info_index(int fd)
@@ -1748,7 +1899,7 @@ static struct socket_info *find_socket_info(int fd)
return NULL;
}
- return &sockets[idx];
+ return swrap_get_socket_info(idx);
}
#if 0 /* FIXME */
@@ -1777,7 +1928,7 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
}
for (f = socket_fds; f; f = f->next) {
- struct socket_info *s = &sockets[f->si_index];
+ struct socket_info *s = swrap_get_socket_info(f->si_index);
if (s == last_s) {
continue;
@@ -1853,25 +2004,35 @@ static void swrap_remove_stale(int fd)
return;
}
+ SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
+
si_index = fi->si_index;
- SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
+ si = swrap_get_socket_info(si_index);
+
+ SWRAP_LOCK(first_free);
+ SWRAP_LOCK_SI(si);
+
SWRAP_DLIST_REMOVE(socket_fds, fi);
- free(fi);
- si = &sockets[si_index];
- si->refcount--;
+ swrap_dec_refcount(si);
- if (si->refcount > 0) {
- return;
+ free(fi);
+
+ if (swrap_get_refcount(si) > 0) {
+ goto out;
}
if (si->un_addr.sun_path[0] != '\0') {
unlink(si->un_addr.sun_path);
}
- si->next_free = first_free;
+ swrap_set_next_free(si, first_free);
first_free = si_index;
+
+out:
+ SWRAP_UNLOCK_SI(si);
+ SWRAP_UNLOCK(first_free);
}
static int sockaddr_convert_to_un(struct socket_info *si,
@@ -2784,10 +2945,10 @@ int signalfd(int fd, const sigset_t *mask, int flags)
static int swrap_socket(int family, int type, int protocol)
{
- struct socket_info *si;
- struct socket_info_fd *fi;
+ struct socket_info *si = NULL;
+ struct socket_info _si = { 0 };
int fd;
- int idx;
+ int ret;
int real_type = type;
/*
@@ -2866,14 +3027,7 @@ static int swrap_socket(int family, int type, int protocol)
/* Check if we have a stale fd and remove it */
swrap_remove_stale(fd);
- idx = socket_wrapper_first_free_index();
- if (idx == -1) {
- errno = ENOMEM;
- return -1;
- }
-
- si = &sockets[idx];
-
+ si = &_si;
si->family = family;
/* however, the rest of the socket_wrapper code expects just
@@ -2909,25 +3063,15 @@ static int swrap_socket(int family, int type, int protocol)
return -1;
}
- fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
- if (fi == NULL) {
- errno = ENOMEM;
+ ret = swrap_create_socket(si, fd);
+ if (ret == -1) {
return -1;
}
- si->refcount = 1;
- first_free = si->next_free;
- si->next_free = 0;
-
- fi->fd = fd;
- fi->si_index = idx;
-
- SWRAP_DLIST_ADD(socket_fds, fi);
-
SWRAP_LOG(SWRAP_LOG_TRACE,
"Created %s socket for protocol %s",
- si->family == AF_INET ? "IPv4" : "IPv6",
- si->type == SOCK_DGRAM ? "UDP" : "TCP");
+ family == AF_INET ? "IPv4" : "IPv6",
+ real_type == SOCK_DGRAM ? "UDP" : "TCP");
return fd;
}
@@ -3014,7 +3158,7 @@ static int swrap_accept(int s,
int flags)
{
struct socket_info *parent_si, *child_si;
- struct socket_info_fd *child_fi;
+ struct socket_info new_si = { 0 };
int fd;
int idx;
struct swrap_address un_addr = {
@@ -3041,16 +3185,26 @@ static int swrap_accept(int s,
#endif
}
+
+ /*
+ * prevent parent_si from being altered / closed
+ * while we read it
+ */
+ SWRAP_LOCK_SI(parent_si);
+
/*
* assume out sockaddr have the same size as the in parent
* socket family
*/
in_addr.sa_socklen = socket_length(parent_si->family);
if (in_addr.sa_socklen <= 0) {
+ SWRAP_UNLOCK_SI(parent_si);
errno = EINVAL;
return -1;
}
+ SWRAP_UNLOCK_SI(parent_si);
+
#ifdef HAVE_ACCEPT4
ret = libc_accept4(s, &un_addr.sa.s, &un_addr.sa_socklen, flags);
#else
@@ -3067,6 +3221,8 @@ static int swrap_accept(int s,
fd = ret;
+ SWRAP_LOCK_SI(parent_si);
+
ret = sockaddr_convert_from_un(parent_si,
&un_addr.sa.un,
un_addr.sa_socklen,
@@ -3074,26 +3230,12 @@ static int swrap_accept(int s,
&in_addr.sa.s,
&in_addr.sa_socklen);
if (ret == -1) {
+ SWRAP_UNLOCK_SI(parent_si);
close(fd);
return ret;
}
- idx = socket_wrapper_first_free_index();
- if (idx == -1) {
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list