Mercurial > dovecot > core-2.2
changeset 16822:6a814345f16c
lib: Added net_listen_full() with a flag to set SO_REUSEPORT on the socket if available.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 23 Sep 2013 04:06:08 +0300 |
parents | 1a5d92b8d3d5 |
children | a991a0547daa |
files | src/lib/net.c src/lib/net.h |
diffstat | 2 files changed, 24 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/net.c Sun Sep 22 07:43:31 2013 +0300 +++ b/src/lib/net.c Mon Sep 23 04:06:08 2013 +0300 @@ -384,6 +384,14 @@ int net_listen(const struct ip_addr *my_ip, unsigned int *port, int backlog) { + enum net_listen_flags flags = 0; + + return net_listen_full(my_ip, port, &flags, backlog); +} + +int net_listen_full(const struct ip_addr *my_ip, unsigned int *port, + enum net_listen_flags *flags, int backlog) +{ union sockaddr_union so; int ret, fd, opt = 1; socklen_t len; @@ -413,6 +421,14 @@ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); + if ((*flags & NET_LISTEN_FLAG_REUSEPORT) != 0) { +#ifdef SO_REUSEPORT + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, + &opt, sizeof(opt)) < 0) +#endif + *flags &= ~NET_LISTEN_FLAG_REUSEPORT; + } + /* If using IPv6, bind only to IPv6 if possible. This avoids ambiguities with IPv4-mapped IPv6 addresses. */ #ifdef IPV6_V6ONLY
--- a/src/lib/net.h Sun Sep 22 07:43:31 2013 +0300 +++ b/src/lib/net.h Mon Sep 23 04:06:08 2013 +0300 @@ -55,6 +55,12 @@ #define IPADDR_IS_V6(ip) ((ip)->family == AF_INET6) #define IPADDR_BITS(ip) (IPADDR_IS_V4(ip) ? 32 : 128) +enum net_listen_flags { + /* Try to use SO_REUSEPORT if available. If it's not, this flag is + cleared on return. */ + NET_LISTEN_FLAG_REUSEPORT = 0x01 +}; + /* Returns TRUE if IPs are the same */ bool net_ip_compare(const struct ip_addr *ip1, const struct ip_addr *ip2); /* Returns 0 if IPs are the same, -1 or 1 otherwise. */ @@ -91,6 +97,8 @@ /* Listen for connections on a socket */ int net_listen(const struct ip_addr *my_ip, unsigned int *port, int backlog); +int net_listen_full(const struct ip_addr *my_ip, unsigned int *port, + enum net_listen_flags *flags, int backlog); /* Listen for connections on an UNIX socket */ int net_listen_unix(const char *path, int backlog); /* Like net_listen_unix(), but if socket already exists, try to connect to it.