From df2b1fb2caed423b22f6d59d22f087100dd1b7d8 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 11 Sep 2015 02:05:06 +0200 Subject: Fix closure of local server sockets Since bound socks always have a ref for their address, they would never get freed. Thanks Svante Signell for the investigation. * pflocal/sock.h (sock_deref): When `sock' has one ref left and is bound to an address, unbound it, and thus shut it down. --- pflocal/sock.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'pflocal') diff --git a/pflocal/sock.h b/pflocal/sock.h index 5800420c..f827c6f2 100644 --- a/pflocal/sock.h +++ b/pflocal/sock.h @@ -118,9 +118,32 @@ void _sock_norefs (struct sock *sock); static inline void __attribute__ ((unused)) sock_deref (struct sock *sock) { + error_t err; pthread_mutex_lock (&sock->lock); - if (--sock->refs == 0) + + sock->refs--; + + if (sock->refs == 0) _sock_norefs (sock); + else if (sock->refs == 1 && sock->addr) + { + /* Last ref is the address, there won't be any more port for this socket, + unbind SOCK from its addr, and they will all die. */ + + /* Keep another ref while unbinding. */ + sock->refs++; + pthread_mutex_unlock (&sock->lock); + + /* Unbind */ + err = sock_bind (sock, NULL); + assert (!err); + + /* And release the ref, and thus kill SOCK. */ + pthread_mutex_lock (&sock->lock); + sock->refs--; + assert(sock->refs == 0); + _sock_norefs (sock); + } else pthread_mutex_unlock (&sock->lock); } -- cgit v1.2.3