Skip to content

Commit 0ac411f

Browse files
rootton31337
authored andcommitted
Add SO_REUSEPORT support to socket
1 parent 4bfcc42 commit 0ac411f

File tree

7 files changed

+39
-1
lines changed

7 files changed

+39
-1
lines changed

src/nc_conf.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ static struct command conf_commands[] = {
7878
conf_set_bool,
7979
offsetof(struct conf_pool, tcpkeepalive) },
8080

81+
{ string("reuseport"),
82+
conf_set_bool,
83+
offsetof(struct conf_pool, reuseport) },
84+
8185
{ string("redis_auth"),
8286
conf_set_string,
8387
offsetof(struct conf_pool, redis_auth) },
@@ -199,6 +203,7 @@ conf_pool_init(struct conf_pool *cp, struct string *name)
199203

200204
cp->redis = CONF_UNSET_NUM;
201205
cp->tcpkeepalive = CONF_UNSET_NUM;
206+
cp->reuseport = CONF_UNSET_NUM;
202207
cp->redis_db = CONF_UNSET_NUM;
203208
cp->preconnect = CONF_UNSET_NUM;
204209
cp->auto_eject_hosts = CONF_UNSET_NUM;
@@ -287,6 +292,7 @@ conf_pool_each_transform(void *elem, void *data)
287292
sp->hash_tag = cp->hash_tag;
288293

289294
sp->tcpkeepalive = cp->tcpkeepalive ? 1 : 0;
295+
sp->reuseport = cp->reuseport ? 1 : 0;
290296

291297
sp->redis = cp->redis ? 1 : 0;
292298
sp->timeout = cp->timeout;
@@ -1242,6 +1248,10 @@ conf_validate_pool(struct conf *cf, struct conf_pool *cp)
12421248
cp->tcpkeepalive = CONF_DEFAULT_TCPKEEPALIVE;
12431249
}
12441250

1251+
if (cp->reuseport == CONF_UNSET_NUM) {
1252+
cp->reuseport = CONF_DEFAULT_REUSEPORT;
1253+
}
1254+
12451255
if (cp->redis_db == CONF_UNSET_NUM) {
12461256
cp->redis_db = CONF_DEFAULT_REDIS_DB;
12471257
}

src/nc_conf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define CONF_DEFAULT_SERVER_CONNECTIONS 1
5656
#define CONF_DEFAULT_KETAMA_PORT 11211
5757
#define CONF_DEFAULT_TCPKEEPALIVE false
58+
#define CONF_DEFAULT_REUSEPORT false
5859

5960
struct conf_listen {
6061
struct string pname; /* listen: as "hostname:port" */
@@ -95,6 +96,7 @@ struct conf_pool {
9596
int server_failure_limit; /* server_failure_limit: */
9697
struct array server; /* servers: conf_server[] */
9798
unsigned valid:1; /* valid? */
99+
int reuseport; /* set SO_REUSEPORT to socket */
98100
};
99101

100102
struct conf {

src/nc_proxy.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ proxy_listen(struct context *ctx, struct conn *p)
134134
return NC_ERROR;
135135
}
136136

137+
if (pool->reuseport)
138+
nc_set_reuseport(p->sd);
139+
137140
status = proxy_reuse(p);
138141
if (status < 0) {
139142
log_error("reuse of addr '%.*s' for listening on p %d failed: %s",

src/nc_server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ struct server_pool {
121121
unsigned preconnect:1; /* preconnect? */
122122
unsigned redis:1; /* redis? */
123123
unsigned tcpkeepalive:1; /* tcpkeepalive? */
124+
unsigned reuseport:1; /* set SO_REUSEPORT to socket */
124125
};
125126

126127
void server_ref(struct conn *conn, void *owner);

src/nc_stats.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ stats_listen(struct stats *st)
827827
log_error("socket failed: %s", strerror(errno));
828828
return NC_ERROR;
829829
}
830-
830+
nc_set_reuseport(st->sd);
831831
status = nc_set_reuseaddr(st->sd);
832832
if (status < 0) {
833833
log_error("set reuseaddr on m %d failed: %s", st->sd, strerror(errno));

src/nc_util.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include <unistd.h>
2323
#include <fcntl.h>
2424
#include <netdb.h>
25+
#ifdef __linux
26+
#include <linux/version.h>
27+
#endif
2528

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

81+
int
82+
nc_set_reuseport(int sd)
83+
{
84+
int reuse;
85+
socklen_t len;
86+
87+
reuse = 1;
88+
len = sizeof(reuse);
89+
#ifdef __linux
90+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
91+
return setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &reuse, len);
92+
#endif
93+
#elif defined __FreeBSD__ || defined __APPLE__
94+
return setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &reuse, len);
95+
#endif
96+
return setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &reuse, len);
97+
}
98+
7899
/*
79100
* Disable Nagle algorithm on TCP socket.
80101
*

src/nc_util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
int nc_set_blocking(int sd);
8282
int nc_set_nonblocking(int sd);
8383
int nc_set_reuseaddr(int sd);
84+
int nc_set_reuseport(int sd);
8485
int nc_set_tcpnodelay(int sd);
8586
int nc_set_linger(int sd, int timeout);
8687
int nc_set_sndbuf(int sd, int size);

0 commit comments

Comments
 (0)