Skip to content

Commit 3292a5a

Browse files
authored
Merge pull request #3039 from jes/master
Add REUSE_PORT socket option
2 parents 00a19ed + cabe591 commit 3292a5a

File tree

9 files changed

+40
-15
lines changed

9 files changed

+40
-15
lines changed

cfg.lex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,9 @@ DOT \.
328328
CR \n
329329
330330
ANY "any"
331-
ANYCAST "anycast"
332-
FRAG "frag"
331+
ANYCAST ("anycast"|"ANYCAST")
332+
FRAG ("frag"|"FRAG")
333+
REUSE_PORT ("reuse_port"|"REUSE_PORT")
333334
334335
335336
COM_LINE #
@@ -588,6 +589,7 @@ SPACE [ ]
588589
<INITIAL>{CR} { count();/* return CR;*/ }
589590
<INITIAL>{ANY} { count(); return ANY; }
590591
<INITIAL>{ANYCAST} { count(); return ANYCAST; }
592+
<INITIAL>{REUSE_PORT} { count(); return REUSE_PORT; }
591593
<INITIAL>{FRAG} { count(); return FRAG; }
592594
<INITIAL>{SLASH} { count(); return SLASH; }
593595
<INITIAL>{SCALE_UP_TO} { count(); return SCALE_UP_TO; }

cfg.y

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ extern int cfg_parse_only_routes;
433433
%token ANY
434434
%token ANYCAST
435435
%token FRAG
436+
%token REUSE_PORT
436437
%token SCRIPTVARERR
437438
%token SCALE_UP_TO
438439
%token SCALE_DOWN_TO
@@ -643,6 +644,9 @@ socket_def_param: ANYCAST { IFOR();
643644
| FRAG { IFOR();
644645
p_tmp.flags |= SI_FRAG;
645646
}
647+
| REUSE_PORT { IFOR();
648+
p_tmp.flags |= SI_REUSEPORT;
649+
}
646650
| USE_WORKERS NUMBER { IFOR();
647651
p_tmp.workers=$2;
648652
}

ip_addr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ union sockaddr_union{
8989

9090

9191
enum si_flags { SI_NONE=0, SI_IS_IP=1, SI_IS_LO=2, SI_IS_MCAST=4,
92-
SI_IS_ANYCAST=8, SI_FRAG=16 };
92+
SI_IS_ANYCAST=8, SI_FRAG=16, SI_REUSEPORT=32 };
9393

9494
struct receive_info {
9595
struct ip_addr src_ip;

modules/cgrates/cgrates_engine.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ static int cgrc_conn(struct cgr_conn *c)
270270

271271
tcp_con_get_profile(&c->engine->su, src_su, PROTO_TCP, &prof);
272272

273-
s = tcp_sync_connect_fd(src_su, &c->engine->su, PROTO_TCP, &prof);
273+
s = tcp_sync_connect_fd(src_su, &c->engine->su, PROTO_TCP, &prof, 0);
274274
if (s < 0) {
275275
LM_ERR("cannot connect to %.*s:%d\n", c->engine->host.len,
276276
c->engine->host.s, c->engine->port);

modules/proto_ws/ws_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ static struct tcp_connection* ws_sync_connect(struct socket_info* send_sock,
649649
goto error;
650650
}
651651

652-
if (tcp_init_sock_opt(s, prof)<0){
652+
if (tcp_init_sock_opt(s, prof, send_sock->flags)<0){
653653
LM_ERR("tcp_init_sock_opt failed\n");
654654
goto error;
655655
}

net/net_tcp.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,24 @@ static inline int init_sock_keepalive(int s, struct tcp_conn_profile *prof)
206206
return 0;
207207
}
208208

209+
static inline void set_sock_reuseport(int s)
210+
{
211+
int yes = 1;
212+
213+
if (setsockopt(s,SOL_SOCKET,SO_REUSEPORT,&yes,sizeof(yes))<0){
214+
LM_WARN("setsockopt failed to set SO_REUSEPORT: %s\n",
215+
strerror(errno));
216+
}
217+
if (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes))<0){
218+
LM_WARN("setsockopt failed to set SO_REUSEADDR: %s\n",
219+
strerror(errno));
220+
}
221+
}
209222

210223
/*! \brief Set all socket/fd options: disable nagle, tos lowdelay,
211224
* non-blocking
212225
* \return -1 on error */
213-
int tcp_init_sock_opt(int s, struct tcp_conn_profile *prof)
226+
int tcp_init_sock_opt(int s, struct tcp_conn_profile *prof, enum si_flags socketflags)
214227
{
215228
int flags;
216229
int optval;
@@ -235,6 +248,8 @@ int tcp_init_sock_opt(int s, struct tcp_conn_profile *prof)
235248
}
236249

237250
init_sock_keepalive(s, prof);
251+
if (socketflags & SI_REUSEPORT)
252+
set_sock_reuseport(s);
238253

239254
/* non-blocking */
240255
flags=fcntl(s, F_GETFL);
@@ -363,6 +378,8 @@ int tcp_init_listener(struct socket_info *si)
363378
}
364379

365380
init_sock_keepalive(si->socket, &tcp_con_df_profile);
381+
if (si->flags & SI_REUSEPORT)
382+
set_sock_reuseport(si->socket);
366383
if (bind(si->socket, &addr->s, sockaddru_len(*addr))==-1){
367384
LM_ERR("bind(%x, %p, %d) on %s:%d : %s\n",
368385
si->socket, &addr->s,
@@ -1071,7 +1088,7 @@ static inline int handle_new_connect(struct socket_info* si)
10711088
}
10721089

10731090
tcp_con_get_profile(&su, &si->su, si->proto, &prof);
1074-
if (tcp_init_sock_opt(new_sock, &prof)<0){
1091+
if (tcp_init_sock_opt(new_sock, &prof, si->flags)<0){
10751092
LM_ERR("tcp_init_sock_opt failed\n");
10761093
close(new_sock);
10771094
return 1; /* success, because the accept was successful */

net/net_tcp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ mi_response_t *mi_tcp_list_conns(const mi_params_t *params,
7979
int tcp_init_listener(struct socket_info *si);
8080

8181
/* helper function to set all TCP related options to a socket */
82-
int tcp_init_sock_opt(int s, struct tcp_conn_profile *prof);
82+
int tcp_init_sock_opt(int s, struct tcp_conn_profile *prof, enum si_flags socketflags);
8383

8484
/********************** TCP conn management functions ************************/
8585

net/tcp_common.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ int tcp_connect_blocking(int fd, const struct sockaddr *servaddr,
141141
}
142142

143143
int tcp_sync_connect_fd(union sockaddr_union* src, union sockaddr_union* dst,
144-
enum sip_protos proto, struct tcp_conn_profile *prof)
144+
enum sip_protos proto, struct tcp_conn_profile *prof, enum si_flags flags)
145145
{
146146
int s;
147147
union sockaddr_union my_name;
@@ -153,15 +153,16 @@ int tcp_sync_connect_fd(union sockaddr_union* src, union sockaddr_union* dst,
153153
goto error;
154154
}
155155

156-
if (tcp_init_sock_opt(s, prof)<0){
156+
if (tcp_init_sock_opt(s, prof, flags)<0){
157157
LM_ERR("tcp_init_sock_opt failed\n");
158158
goto error;
159159
}
160160

161161
if (src) {
162162
my_name_len = sockaddru_len(*src);
163163
memcpy( &my_name, src, my_name_len);
164-
su_setport( &my_name, 0);
164+
if (!(flags & SI_REUSEPORT))
165+
su_setport( &my_name, 0);
165166
if (bind(s, &my_name.s, my_name_len )!=0) {
166167
LM_ERR("bind failed (%d) %s\n", errno,strerror(errno));
167168
goto error;
@@ -187,7 +188,7 @@ struct tcp_connection* tcp_sync_connect(struct socket_info* send_sock,
187188
struct tcp_connection* con;
188189
int s;
189190

190-
s = tcp_sync_connect_fd(&send_sock->su, server, send_sock->proto, prof);
191+
s = tcp_sync_connect_fd(&send_sock->su, server, send_sock->proto, prof, send_sock->flags);
191192
if (s < 0)
192193
return NULL;
193194

@@ -231,14 +232,15 @@ int tcp_async_connect(struct socket_info* send_sock,
231232
return -1;
232233
}
233234

234-
if (tcp_init_sock_opt(fd, prof)<0){
235+
if (tcp_init_sock_opt(fd, prof, send_sock->flags)<0){
235236
LM_ERR("tcp_init_sock_opt failed\n");
236237
goto error;
237238
}
238239

239240
my_name_len = sockaddru_len(send_sock->su);
240241
memcpy( &my_name, &send_sock->su, my_name_len);
241-
su_setport( &my_name, 0);
242+
if (!(send_sock->flags & SI_REUSEPORT))
243+
su_setport( &my_name, 0);
242244
if (bind(fd, &my_name.s, my_name_len )!=0) {
243245
LM_ERR("bind failed (%d) %s\n", errno,strerror(errno));
244246
goto error;

net/tcp_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ int tcp_connect_blocking_timeout(int fd, const struct sockaddr *servaddr,
3131

3232

3333
int tcp_sync_connect_fd(union sockaddr_union* src, union sockaddr_union* dst,
34-
enum sip_protos proto, struct tcp_conn_profile *prof);
34+
enum sip_protos proto, struct tcp_conn_profile *prof, enum si_flags flags);
3535

3636
struct tcp_connection* tcp_sync_connect(struct socket_info* send_sock,
3737
union sockaddr_union* server, struct tcp_conn_profile *prof,

0 commit comments

Comments
 (0)