[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