Skip to content

Commit

Permalink
Add SO_REUSEPORT support to socket
Browse files Browse the repository at this point in the history
  • Loading branch information
root authored and ton31337 committed Aug 17, 2015
1 parent 4bfcc42 commit 0ac411f
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/nc_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ static struct command conf_commands[] = {
conf_set_bool,
offsetof(struct conf_pool, tcpkeepalive) },

{ string("reuseport"),
conf_set_bool,
offsetof(struct conf_pool, reuseport) },

{ string("redis_auth"),
conf_set_string,
offsetof(struct conf_pool, redis_auth) },
Expand Down Expand Up @@ -199,6 +203,7 @@ conf_pool_init(struct conf_pool *cp, struct string *name)

cp->redis = CONF_UNSET_NUM;
cp->tcpkeepalive = CONF_UNSET_NUM;
cp->reuseport = CONF_UNSET_NUM;
cp->redis_db = CONF_UNSET_NUM;
cp->preconnect = CONF_UNSET_NUM;
cp->auto_eject_hosts = CONF_UNSET_NUM;
Expand Down Expand Up @@ -287,6 +292,7 @@ conf_pool_each_transform(void *elem, void *data)
sp->hash_tag = cp->hash_tag;

sp->tcpkeepalive = cp->tcpkeepalive ? 1 : 0;
sp->reuseport = cp->reuseport ? 1 : 0;

sp->redis = cp->redis ? 1 : 0;
sp->timeout = cp->timeout;
Expand Down Expand Up @@ -1242,6 +1248,10 @@ conf_validate_pool(struct conf *cf, struct conf_pool *cp)
cp->tcpkeepalive = CONF_DEFAULT_TCPKEEPALIVE;
}

if (cp->reuseport == CONF_UNSET_NUM) {
cp->reuseport = CONF_DEFAULT_REUSEPORT;
}

if (cp->redis_db == CONF_UNSET_NUM) {
cp->redis_db = CONF_DEFAULT_REDIS_DB;
}
Expand Down
2 changes: 2 additions & 0 deletions src/nc_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#define CONF_DEFAULT_SERVER_CONNECTIONS 1
#define CONF_DEFAULT_KETAMA_PORT 11211
#define CONF_DEFAULT_TCPKEEPALIVE false
#define CONF_DEFAULT_REUSEPORT false

struct conf_listen {
struct string pname; /* listen: as "hostname:port" */
Expand Down Expand Up @@ -95,6 +96,7 @@ struct conf_pool {
int server_failure_limit; /* server_failure_limit: */
struct array server; /* servers: conf_server[] */
unsigned valid:1; /* valid? */
int reuseport; /* set SO_REUSEPORT to socket */
};

struct conf {
Expand Down
3 changes: 3 additions & 0 deletions src/nc_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ proxy_listen(struct context *ctx, struct conn *p)
return NC_ERROR;
}

if (pool->reuseport)
nc_set_reuseport(p->sd);

status = proxy_reuse(p);
if (status < 0) {
log_error("reuse of addr '%.*s' for listening on p %d failed: %s",
Expand Down
1 change: 1 addition & 0 deletions src/nc_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ struct server_pool {
unsigned preconnect:1; /* preconnect? */
unsigned redis:1; /* redis? */
unsigned tcpkeepalive:1; /* tcpkeepalive? */
unsigned reuseport:1; /* set SO_REUSEPORT to socket */
};

void server_ref(struct conn *conn, void *owner);
Expand Down
2 changes: 1 addition & 1 deletion src/nc_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ stats_listen(struct stats *st)
log_error("socket failed: %s", strerror(errno));
return NC_ERROR;
}

nc_set_reuseport(st->sd);
status = nc_set_reuseaddr(st->sd);
if (status < 0) {
log_error("set reuseaddr on m %d failed: %s", st->sd, strerror(errno));
Expand Down
21 changes: 21 additions & 0 deletions src/nc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#ifdef __linux
#include <linux/version.h>
#endif

#include <sys/time.h>
#include <sys/types.h>
Expand Down Expand Up @@ -75,6 +78,24 @@ nc_set_reuseaddr(int sd)
return setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &reuse, len);
}

int
nc_set_reuseport(int sd)
{
int reuse;
socklen_t len;

reuse = 1;
len = sizeof(reuse);
#ifdef __linux
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
return setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &reuse, len);
#endif
#elif defined __FreeBSD__ || defined __APPLE__
return setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &reuse, len);
#endif
return setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &reuse, len);
}

/*
* Disable Nagle algorithm on TCP socket.
*
Expand Down
1 change: 1 addition & 0 deletions src/nc_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
int nc_set_blocking(int sd);
int nc_set_nonblocking(int sd);
int nc_set_reuseaddr(int sd);
int nc_set_reuseport(int sd);
int nc_set_tcpnodelay(int sd);
int nc_set_linger(int sd, int timeout);
int nc_set_sndbuf(int sd, int size);
Expand Down

0 comments on commit 0ac411f

Please sign in to comment.