Merge pull request #179 from pysiak/master

Provide support for SO_REUSEPORT through LEV_OPT_REUSABLE_PORT
This commit is contained in:
Nick Mathewson 2014-10-13 17:59:32 -04:00
commit 6dba1694c8
4 changed files with 41 additions and 0 deletions

View File

@ -367,6 +367,20 @@ evutil_make_listen_socket_reuseable(evutil_socket_t sock)
#endif
}
int
evutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
{
#if defined __linux__ && defined(SO_REUSEPORT)
int one = 1;
/* REUSEPORT on Linux 3.9+ means, "Multiple servers (processes or
* threads) can bind to the same port if they each set the option. */
return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void*) &one,
(ev_socklen_t)sizeof(one));
#else
return 0;
#endif
}
int
evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
{

View File

@ -88,6 +88,15 @@ typedef void (*evconnlistener_errorcb)(struct evconnlistener *, void *);
* to use the option before it is actually bound.
*/
#define LEV_OPT_DEFERRED_ACCEPT (1u<<6)
/** Flag: Indicates that we ask to allow multiple servers (processes or
* threads) to bind to the same port if they each set the option.
*
* SO_REUSEPORT is what most people would expect SO_REUSEADDR to be, however
* SO_REUSEPORT does not imply SO_REUSEADDR.
*
* This is only available on Linux and kernel 3.9+
*/
#define LEV_OPT_REUSEABLE_PORT (1u<<7)
/**
Allocate a new evconnlistener object to listen for incoming TCP connections

View File

@ -327,6 +327,19 @@ int evutil_make_socket_nonblocking(evutil_socket_t sock);
EVENT2_EXPORT_SYMBOL
int evutil_make_listen_socket_reuseable(evutil_socket_t sock);
/** Do platform-specific operations to make a listener port reusable.
Specifically, we want to make sure that multiple programs which also
set the same socket option will be able to bind, listen at the same time.
This is a feature available only to Linux 3.9+
@param sock The socket to make reusable
@return 0 on success, -1 on failure
*/
EVENT2_EXPORT_SYMBOL
int evutil_make_listen_socket_reuseable_port(evutil_socket_t sock);
/** Do platform-specific operations as needed to close a socket upon a
successful execution of one of the exec*() functions.

View File

@ -235,6 +235,11 @@ evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
goto err;
}
if (flags & LEV_OPT_REUSEABLE_PORT) {
if (evutil_make_listen_socket_reuseable_port(fd) < 0)
goto err;
}
if (flags & LEV_OPT_DEFERRED_ACCEPT) {
if (evutil_make_tcp_listen_socket_deferred(fd) < 0)
goto err;