From 569bec5b5cd2028467ee21980739a3d720a13f87 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 11 Aug 2011 15:17:56 +0200 Subject: [PATCH] make port map thread safe This patch has been in Fedora and RHEL for a while. It adds a mutex to protect the port map from concurrent thread accesses. Original patch from Stefan Berger . Modified to use configure.in to check for libpthread --- configure.in | 1 + lib/socket.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 47567af..f217231 100644 --- a/configure.in +++ b/configure.in @@ -46,6 +46,7 @@ AC_ARG_ENABLE([cli], AM_CONDITIONAL([ENABLE_CLI], [test "$enable_cli" = "yes"]) AC_CHECK_LIB([m], [pow], [], AC_MSG_ERROR([libm is required])) +AC_CHECK_LIB([pthread], [pthread_mutex_lock], [], AC_MSG_ERROR([libpthread is required])) AC_CONFIG_FILES([Makefile doc/Doxyfile doc/Makefile lib/Makefile include/Makefile src/Makefile src/lib/Makefile man/Makefile diff --git a/lib/socket.c b/lib/socket.c index ebdf4e8..461cd41 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -15,6 +15,8 @@ * @{ */ +#include + #include #include #include @@ -43,12 +45,15 @@ static void __init init_default_cb(void) } static uint32_t used_ports_map[32]; +static pthread_mutex_t port_map_mutex = PTHREAD_MUTEX_INITIALIZER; static uint32_t generate_local_port(void) { int i, n; uint32_t pid = getpid() & 0x3FFFFF; + pthread_mutex_lock(&port_map_mutex); + for (i = 0; i < 32; i++) { if (used_ports_map[i] == 0xFFFFFFFF) continue; @@ -62,11 +67,15 @@ static uint32_t generate_local_port(void) /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit * to, i.e. 1024 unique ports per application. */ - return pid + (n << 22); + pthread_mutex_unlock(&port_map_mutex); + + return pid + (n << 22); } } + pthread_mutex_unlock(&port_map_mutex); + /* Out of sockets in our own PID namespace, what to do? FIXME */ return UINT_MAX; } @@ -79,7 +88,10 @@ static void release_local_port(uint32_t port) return; nr = port >> 22; - used_ports_map[nr / 32] &= ~(1 << nr % 32); + + pthread_mutex_lock(&port_map_mutex); + used_ports_map[nr / 32] &= ~(1 << (nr % 32)); + pthread_mutex_unlock(&port_map_mutex); } /**