Browse code

core: new socket global parameter to set listen attributes with a structure style

- alternative to listen when a usual bind address is provided
- example:

socket = {
bind = udp:127.0.0.1:5060;
advertise = 1.2.3.4:5080;
name = "udp0";
}

Daniel-Constantin Mierla authored on 01/06/2022 06:24:50
Showing 5 changed files
... ...
@@ -361,6 +361,9 @@ STATS_NAMESEP	stats_name_separator
361 361
 MAXBUFFER maxbuffer
362 362
 SQL_BUFFER_SIZE sql_buffer_size
363 363
 CHILDREN children
364
+SOCKET socket
365
+BIND bind
366
+WORKERS workers
364 367
 SOCKET_WORKERS socket_workers
365 368
 ASYNC_WORKERS async_workers
366 369
 ASYNC_USLEEP async_usleep
... ...
@@ -832,6 +835,8 @@ IMPORTFILE      "import_file"
832 835
 <INITIAL>{MAXBUFFER}	{ count(); yylval.strval=yytext; return MAXBUFFER; }
833 836
 <INITIAL>{SQL_BUFFER_SIZE}	{ count(); yylval.strval=yytext; return SQL_BUFFER_SIZE; }
834 837
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
838
+<INITIAL>{SOCKET}	{ count(); yylval.strval=yytext; return SOCKET; }
839
+<INITIAL>{BIND}	{ count(); yylval.strval=yytext; return BIND; }
835 840
 <INITIAL>{SOCKET_WORKERS}	{ count(); yylval.strval=yytext; return SOCKET_WORKERS; }
836 841
 <INITIAL>{ASYNC_WORKERS}	{ count(); yylval.strval=yytext; return ASYNC_WORKERS; }
837 842
 <INITIAL>{ASYNC_USLEEP}	{ count(); yylval.strval=yytext; return ASYNC_USLEEP; }
... ...
@@ -151,6 +151,7 @@ static struct action *mod_func_action = NULL;
151 151
 static struct lvalue* lval_tmp = NULL;
152 152
 static struct rvalue* rval_tmp = NULL;
153 153
 static struct rval_expr* rve_tmp = NULL;
154
+static socket_attrs_t tmp_sa;
154 155
 
155 156
 static void warn(char* s, ...);
156 157
 static void warn_at(struct cfg_pos* pos, char* s, ...);
... ...
@@ -382,6 +383,9 @@ extern char *default_routename;
382 383
 %token STAT
383 384
 %token STATS_NAMESEP
384 385
 %token CHILDREN
386
+%token SOCKET
387
+%token BIND
388
+%token WORKERS
385 389
 %token SOCKET_WORKERS
386 390
 %token ASYNC_WORKERS
387 391
 %token ASYNC_USLEEP
... ...
@@ -797,6 +801,48 @@ avpflag_spec:
797 801
 			yyerror("cannot declare avpflag");
798 802
 	}
799 803
 	;
804
+socket_lattr:
805
+	BIND EQUAL proto COLON listen_id COLON port	{
806
+			tmp_sa.bindproto = $3;
807
+			tmp_sa.bindaddr.s = $5;
808
+			tmp_sa.bindaddr.len = strlen(tmp_sa.bindaddr.s);
809
+			tmp_sa.bindport = $7;
810
+		}
811
+	| BIND EQUAL listen_id COLON port	{
812
+			tmp_sa.bindaddr.s = $3;
813
+			tmp_sa.bindaddr.len = strlen(tmp_sa.bindaddr.s);
814
+			tmp_sa.bindport = $5;
815
+		}
816
+	| BIND EQUAL proto COLON listen_id	{
817
+			tmp_sa.bindproto = $3;
818
+			tmp_sa.bindaddr.s = $5;
819
+			tmp_sa.bindaddr.len = strlen(tmp_sa.bindaddr.s);
820
+		}
821
+	| BIND EQUAL listen_id	{
822
+			tmp_sa.bindaddr.s = $3;
823
+			tmp_sa.bindaddr.len = strlen(tmp_sa.bindaddr.s);
824
+		}
825
+	| BIND EQUAL error { yyerror("string value expected"); }
826
+	| STRNAME EQUAL STRING {
827
+			tmp_sa.sockname.s = $3;
828
+			tmp_sa.sockname.len = strlen(tmp_sa.sockname.s);
829
+		}
830
+	| STRNAME EQUAL error { yyerror("string value expected"); }
831
+	| ADVERTISE EQUAL listen_id COLON NUMBER {
832
+			tmp_sa.useaddr.s = $3;
833
+			tmp_sa.useaddr.len = strlen(tmp_sa.useaddr.s);
834
+			tmp_sa.useport = $5;
835
+		}
836
+	| WORKERS EQUAL NUMBER { tmp_sa.workers=$3; }
837
+	| WORKERS EQUAL error { yyerror("number expected"); }
838
+	| VIRTUAL EQUAL NUMBER { if($3!=0) { tmp_sa.sflags |= SI_IS_VIRTUAL; } }
839
+	| VIRTUAL EQUAL error { yyerror("number expected"); }
840
+	| SEMICOLON {}
841
+	;
842
+socket_lattrs:
843
+	socket_lattrs socket_lattr {}
844
+	| socket_lattr {}
845
+	;
800 846
 assign_stm:
801 847
 	DEBUG_V EQUAL intno { default_core_cfg.debug=$3; }
802 848
 	| DEBUG_V EQUAL error  { yyerror("number  expected"); }
... ...
@@ -949,6 +995,15 @@ assign_stm:
949 995
 	| CHILDREN EQUAL error { yyerror("number expected"); }
950 996
 	| STATS_NAMESEP EQUAL STRING { ksr_stats_namesep=$3; }
951 997
 	| STATS_NAMESEP EQUAL error { yyerror("string value expected"); }
998
+	| SOCKET {
999
+				memset(&tmp_sa, 0, sizeof(socket_attrs_t));
1000
+			} EQUAL LBRACE socket_lattrs RBRACE {
1001
+				if(add_listen_socket(&tmp_sa)<0) {
1002
+					LM_ERR("failed to add listen socket\n");
1003
+					yyerror("failed to add listen socket");
1004
+					ksr_exit(-1);
1005
+				}
1006
+	}
952 1007
 	| SOCKET_WORKERS EQUAL NUMBER { socket_workers=$3; }
953 1008
 	| SOCKET_WORKERS EQUAL error { yyerror("number expected"); }
954 1009
 	| ASYNC_WORKERS EQUAL NUMBER { async_task_set_workers($3); }
... ...
@@ -134,6 +134,16 @@ typedef struct socket_info {
134 134
 #endif /* USE_MCAST */
135 135
 } socket_info_t;
136 136
 
137
+typedef struct socket_attrs {
138
+	int bindproto;
139
+	str bindaddr;
140
+	int bindport;
141
+	str useaddr;
142
+	int useport;
143
+	str sockname;
144
+	int workers;
145
+	int sflags;
146
+} socket_attrs_t;
137 147
 
138 148
 /* send flags */
139 149
 typedef enum send_flags {
... ...
@@ -1117,13 +1117,14 @@ error:
1117 1117
 
1118 1118
 
1119 1119
 /* adds a sock_info structure to the corresponding proto list
1120
- * return  0 on success, -1 on error */
1121
-int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
1120
+ * return last new socket info structur on success, NULL on error */
1121
+socket_info_t* add_listen_socket_info(char* name, struct name_lst* addr_l,
1122 1122
 						unsigned short port, unsigned short proto,
1123 1123
 						char *usename, unsigned short useport, char *sockname,
1124 1124
 						enum si_flags flags)
1125 1125
 {
1126
-	struct socket_info** list;
1126
+	socket_info_t* newsi = NULL;
1127
+	socket_info_t** list = NULL;
1127 1128
 	unsigned short c_proto;
1128 1129
 	struct name_lst* a_l;
1129 1130
 	unsigned short c_port;
... ...
@@ -1151,8 +1152,9 @@ int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
1151 1152
 			c_port=port;
1152 1153
 		}
1153 1154
 		if (c_proto!=PROTO_SCTP){
1154
-			if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
1155
-								sockname, flags & ~SI_IS_MHOMED, list)==0){
1155
+			newsi = new_sock2list(name, 0, c_port, c_proto, usename, useport,
1156
+								sockname, flags & ~SI_IS_MHOMED, list);
1157
+			if(newsi==0){
1156 1158
 				LM_ERR("new_sock2list failed\n");
1157 1159
 				goto error;
1158 1160
 			}
... ...
@@ -1167,16 +1169,32 @@ int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
1167 1169
 				}
1168 1170
 			}
1169 1171
 		}else{
1170
-			if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
1171
-						sockname, flags, list)==0){
1172
+			newsi = new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
1173
+						sockname, flags, list);
1174
+			if(newsi==0){
1172 1175
 				LM_ERR("new_sock2list failed\n");
1173 1176
 				goto error;
1174 1177
 			}
1175 1178
 		}
1176
-	}while( (proto==0) && (c_proto=next_proto(c_proto)));
1177
-	return 0;
1179
+	} while((proto==0) && (c_proto=next_proto(c_proto)));
1180
+
1181
+	return newsi;
1178 1182
 error:
1179
-	return -1;
1183
+	return NULL;
1184
+}
1185
+
1186
+/* adds a sock_info structure to the corresponding proto list
1187
+ * return  0 on success, -1 on error */
1188
+int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
1189
+						unsigned short port, unsigned short proto,
1190
+						char *usename, unsigned short useport, char *sockname,
1191
+						enum si_flags flags)
1192
+{
1193
+	if(add_listen_socket_info(name, addr_l, port, proto, usename, useport,
1194
+				sockname, flags)==NULL) {
1195
+		return -1;
1196
+	}
1197
+	return 0;
1180 1198
 }
1181 1199
 
1182 1200
 /* adds a sock_info structure to the corresponding proto list
... ...
@@ -1210,6 +1228,24 @@ int add_listen_iface_name(char* name, struct name_lst* addr_l,
1210 1228
 			sockname, flags);
1211 1229
 }
1212 1230
 
1231
+int add_listen_socket(socket_attrs_t *sa)
1232
+{
1233
+	socket_info_t* newsi;
1234
+	name_lst_t addr_l;
1235
+
1236
+	if(sa->bindaddr.s==NULL) {
1237
+		LM_ERR("no bind address provided\n");
1238
+		return -1;
1239
+	}
1240
+	memset(&addr_l, 0, sizeof(name_lst_t));
1241
+	addr_l.name = sa->bindaddr.s;
1242
+
1243
+	newsi = add_listen_socket_info(sa->bindaddr.s, &addr_l, sa->bindport,
1244
+			sa->bindproto, sa->useaddr.s, sa->useport, sa->sockname.s, sa->sflags);
1245
+
1246
+	return (newsi!=NULL)?0:-1;
1247
+}
1248
+
1213 1249
 #ifdef __OS_linux
1214 1250
 
1215 1251
 #include "linux/types.h"
... ...
@@ -97,6 +97,8 @@ int fix_all_socket_lists(void);
97 97
 void print_all_socket_lists(void);
98 98
 void print_aliases(void);
99 99
 
100
+int add_listen_socket(socket_attrs_t *sa);
101
+
100 102
 struct socket_info* grep_sock_info(str* host, unsigned short port,
101 103
 										unsigned short proto);
102 104
 struct socket_info* grep_sock_info_by_port(unsigned short port,