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 <a...@samba.org> Date: Wed May 2 17:05:21 2018 +0200 cmake: Run threaded tests with helgrind Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 1ff35b6bb9a2702c4b0785281f22018b05e549c8 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit da1fe44b27ce2dc66d795637c13bc13b2a657b79 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 7299ab3541c94f38ee62a9d39348bbeb438bfc1a Author: Michael Adam <ob...@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 <anoo...@redhat.com> Signed-off-by: Michael Adam <ob...@samba.org> Signed-off-by: Anoop C S <anoo...@redhat.com> Reviewed-by: Andreas Schneider <a...@samba.org> commit 01ceb512ccfb60431754fb40704c9fcfb46fc4ac Author: Anoop C S <anoo...@redhat.com> Date: Thu Mar 2 07:26:20 2017 +0000 tests: New threaded test cases Signed-off-by: Anoop C S <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit c48282b7920b6b0037d08b181403042731585d21 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a5c08518e985bd3f0cb274c274c034be37fa5629 Author: Michael Adam <ob...@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 <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit b6909fc91d5d16ced108700cbd5cd8a13481a6c4 Author: Anoop C S <anoo...@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 <ob...@samba.org> Signed-off-by: Anoop C S <anoo...@redhat.com> Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 501b5f3e6444117dab213f8a3dfdda0a860ecde9 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 64c848748077f31a95b5338d8d6e92050b43e0fc Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 548f4d062b06e2cff7fadb0d1ee7de34c1223a8a Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit d0b13efcd590722784baaca85bb5c9b0d5ee2d92 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit e30b080e3188c4498af322c8464569489365d0c3 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 9702a15c2560988fe87119aa45787f935bef66fd Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 327cb50d8370833bad9d260b9dc8f5c70fb5e2ce Author: Michael Adam <ob...@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 <anoo...@redhat.com> Signed-off-by: Michael Adam <ob...@samba.org> Signed-off-by: Anoop C S <anoo...@redhat.com> Reviewed-by: Andreas Schneider <a...@samba.org> commit b1728e6754a0b864f70653fea8d91aa8f57ada6e Author: Michael Adam <ob...@samba.org> Date: Wed Aug 2 13:56:09 2017 +0200 swrap: Reorder code inside swrap_socket Signed-off-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 203a2793dd67461e01cd4267a35bbdc0cb8a162d Author: Michael Adam <ob...@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 <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 6661997701aef9f609465b3a1863cf03402bc06a Author: Michael Adam <ob...@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 <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit aec1e1207d70f1b2a12a3cb3641691bb99ba7581 Author: Michael Adam <ob...@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 <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 10b6cc0ff0891b345d7f71dac44be963792ca32d Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit f55c1be920a989f4ec7f946eb7c17960fc3cf489 Author: Anoop C S <anoo...@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 <anoo...@redhat.com> Reviewed-by: Michael Adam <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a68511296862f48158a7f3623bb94e883b936b2a Author: Michael Adam <ob...@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 <ob...@samba.org> Reviewed-by: Andreas Schneider <a...@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