Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Provide support for SO_REUSEPORT through LEV_OPT_REUSABLE_PORT
  • Loading branch information
Maciej Soltysiak committed Oct 13, 2014
1 parent c750c70 commit b625361
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
14 changes: 14 additions & 0 deletions evutil.c
Expand Up @@ -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)
{
Expand Down
9 changes: 9 additions & 0 deletions include/event2/listener.h
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions include/event2/util.h
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions listener.c
Expand Up @@ -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;
Expand Down

0 comments on commit b625361

Please sign in to comment.