Browse Source

core: support to asign names to listen sockets

- full format:
  listen=proto:address:port advertise address:port name string
- example:
  listen=udp:10.0.0.10:5060 advertise 1.2.3.4:5060 name "sock1"
- the value for the name has to be enclosed in quotes
- name can be provided also when advertise is not needed
Daniel-Constantin Mierla 5 years ago
parent
commit
76889decfc
5 changed files with 144 additions and 51 deletions
  1. 2 0
      src/core/cfg.lex
  2. 39 0
      src/core/cfg.y
  3. 1 0
      src/core/ip_addr.h
  4. 95 51
      src/core/socket_info.c
  5. 7 0
      src/core/socket_info.h

+ 2 - 0
src/core/cfg.lex

@@ -297,6 +297,7 @@ XAVPVIAPARAMS	xavp_via_params
 XAVPVIAFIELDS	xavp_via_fields
 LISTEN		listen
 ADVERTISE	advertise|ADVERTISE
+STRNAME		name|NAME
 ALIAS		alias
 SR_AUTO_ALIASES	auto_aliases
 DNS		 dns
@@ -711,6 +712,7 @@ IMPORTFILE      "import_file"
 <INITIAL>{XAVPVIAFIELDS}	{ yylval.strval=yytext; return XAVPVIAFIELDS; }
 <INITIAL>{LISTEN}	{ count(); yylval.strval=yytext; return LISTEN; }
 <INITIAL>{ADVERTISE}	{ count(); yylval.strval=yytext; return ADVERTISE; }
+<INITIAL>{STRNAME}	{ count(); yylval.strval=yytext; return STRNAME; }
 <INITIAL>{ALIAS}	{ count(); yylval.strval=yytext; return ALIAS; }
 <INITIAL>{SR_AUTO_ALIASES}	{ count(); yylval.strval=yytext;
 									return SR_AUTO_ALIASES; }

+ 39 - 0
src/core/cfg.y

@@ -325,6 +325,7 @@ extern char *default_routename;
 %token XAVPVIAFIELDS
 %token LISTEN
 %token ADVERTISE
+%token STRNAME
 %token ALIAS
 %token SR_AUTO_ALIASES
 %token DNS
@@ -1454,6 +1455,18 @@ assign_stm:
 		}
 		free_socket_id_lst($3);
 	}
+	| LISTEN EQUAL id_lst STRNAME STRING {
+		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
+			if (add_listen_iface_name(lst_tmp->addr_lst->name,
+									lst_tmp->addr_lst->next,
+									lst_tmp->port, lst_tmp->proto, $5,
+									lst_tmp->flags)!=0) {
+				LM_CRIT("cfg. parser: failed to add listen address\n");
+				break;
+			}
+		}
+		free_socket_id_lst($3);
+	}
 	| LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER {
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
 			if (add_listen_advertise_iface(	lst_tmp->addr_lst->name,
@@ -1467,6 +1480,19 @@ assign_stm:
 		}
 		free_socket_id_lst($3);
 	}
+	| LISTEN EQUAL id_lst ADVERTISE listen_id COLON NUMBER STRNAME STRING {
+		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
+			if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name,
+									lst_tmp->addr_lst->next,
+									lst_tmp->port, lst_tmp->proto,
+									$5, $7, $9,
+									lst_tmp->flags)!=0) {
+				LM_CRIT("cfg. parser: failed to add listen address\n");
+				break;
+			}
+		}
+		free_socket_id_lst($3);
+	}
 	| LISTEN EQUAL id_lst ADVERTISE listen_id {
 		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
 			if (add_listen_advertise_iface(	lst_tmp->addr_lst->name,
@@ -1480,6 +1506,19 @@ assign_stm:
 		}
 		free_socket_id_lst($3);
 	}
+	| LISTEN EQUAL id_lst ADVERTISE listen_id STRNAME STRING {
+		for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next) {
+			if (add_listen_advertise_iface_name(lst_tmp->addr_lst->name,
+									lst_tmp->addr_lst->next,
+									lst_tmp->port, lst_tmp->proto,
+									$5, 0, $7,
+									lst_tmp->flags)!=0) {
+				LM_CRIT("cfg. parser: failed to add listen address\n");
+				break;
+			}
+		}
+		free_socket_id_lst($3);
+	}
 	| LISTEN EQUAL  error { yyerror("ip address, interface name or"
 									" hostname expected"); }
 	| ALIAS EQUAL  id_lst {

+ 1 - 0
src/core/ip_addr.h

@@ -116,6 +116,7 @@ typedef struct socket_info {
 	struct addr_info* addr_info_lst; /* extra addresses (e.g. SCTP mh) */
 	int workers; /* number of worker processes for this socket */
 	int workers_tcpidx; /* index of workers in tcp children array */
+	str sockname; /* socket name given in config listen value */
 	struct advertise_info useinfo; /* details to be used in SIP msg */
 #ifdef USE_MCAST
 	str mcast; /* name of interface that should join multicast group*/

+ 95 - 51
src/core/socket_info.c

@@ -289,13 +289,13 @@ static inline struct socket_info* new_sock_info(	char* name,
 								struct name_lst* addr_l,
 								unsigned short port, unsigned short proto,
 								char *usename, unsigned short useport,
-								enum si_flags flags)
+								char *sockname, enum si_flags flags)
 {
 	struct socket_info* si;
 	struct name_lst* n;
 	struct hostent* he;
 	char *p;
-	
+
 	si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
 	if (si==0) goto error;
 	memset(si, 0, sizeof(struct socket_info));
@@ -315,6 +315,12 @@ static inline struct socket_info* new_sock_info(	char* name,
 			goto error;
 		}
 	}
+	if(sockname!=NULL) {
+		si->sockname.len = strlen(sockname);
+		si->sockname.s=(char*)pkg_malloc(si->sockname.len+1); /* include \0 */
+		if (si->sockname.s==0) { goto error; }
+		memcpy(si->sockname.s, sockname, si->sockname.len+1);
+	}
 	if(usename!=NULL)
 	{
 		si->useinfo.name.len=strlen(usename);
@@ -356,8 +362,12 @@ static inline struct socket_info* new_sock_info(	char* name,
 error:
 	PKG_MEM_ERROR;
 	if (si) {
-		if(si->name.s)
+		if(si->name.s) {
 			pkg_free(si->name.s);
+		}
+		if(si->sockname.s) {
+			pkg_free(si->sockname.s);
+		}
 		pkg_free(si);
 	}
 	return 0;
@@ -374,6 +384,7 @@ static void free_sock_info(struct socket_info* si)
 		if(si->port_no_str.s) pkg_free(si->port_no_str.s);
 		if(si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
 		if(si->sock_str.s) pkg_free(si->sock_str.s);
+		if(si->sockname.s) pkg_free(si->sockname.s);
 		if(si->useinfo.name.s) pkg_free(si->useinfo.name.s);
 		if(si->useinfo.port_no_str.s) pkg_free(si->useinfo.port_no_str.s);
 		if(si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
@@ -767,12 +778,13 @@ static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
 									unsigned short port,
 									unsigned short proto,
 									char *usename, unsigned short useport,
+									char *sockname,
 									enum si_flags flags,
 									struct socket_info** list)
 {
 	struct socket_info* si;
 	/* allocates si and si->name in new pkg memory */
-	si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
+	si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
 	if (si==0){
 		LM_ERR("new_sock_info failed\n");
 		goto error;
@@ -811,12 +823,13 @@ static struct socket_info* new_sock2list_after(char* name,
 									unsigned short proto,
 									char *usename,
 									unsigned short useport,
+									char *sockname,
 									enum si_flags flags,
 									struct socket_info* after)
 {
 	struct socket_info* si;
-	
-	si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
+
+	si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
 	if (si==0){
 		LM_ERR("new_sock_info failed\n");
 		goto error;
@@ -831,22 +844,22 @@ error:
 
 /* adds a sock_info structure to the corresponding proto list
  * return  0 on success, -1 on error */
-int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
+int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
 						unsigned short port, unsigned short proto,
-						char *usename, unsigned short useport,
+						char *usename, unsigned short useport, char *sockname,
 						enum si_flags flags)
 {
 	struct socket_info** list;
 	unsigned short c_proto;
 	struct name_lst* a_l;
 	unsigned short c_port;
-	
+
 	c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
 	do{
 		list=get_sock_info_list(c_proto);
 		if (list==0) /* disabled or unknown protocol */
 			continue;
-		
+
 		if (port==0){ /* use default port */
 			c_port=
 #ifdef USE_TLS
@@ -865,15 +878,15 @@ int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
 		}
 		if (c_proto!=PROTO_SCTP){
 			if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
-								flags & ~SI_IS_MHOMED, list)==0){
+								sockname, flags & ~SI_IS_MHOMED, list)==0){
 				LM_ERR("new_sock2list failed\n");
 				goto error;
 			}
 			/* add the other addresses in the list as separate sockets
 			 * since only SCTP can bind to multiple addresses */
 			for (a_l=addr_l; a_l; a_l=a_l->next){
-				if (new_sock2list(a_l->name, 0, c_port, 
-									c_proto, usename, useport,
+				if (new_sock2list(a_l->name, 0, c_port,
+									c_proto, usename, useport, sockname,
 									flags & ~SI_IS_MHOMED, list)==0){
 					LM_ERR("new_sock2list failed\n");
 					goto error;
@@ -881,7 +894,7 @@ int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
 			}
 		}else{
 			if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
-						flags, list)==0){
+						sockname, flags, list)==0){
 				LM_ERR("new_sock2list failed\n");
 				goto error;
 			}
@@ -892,14 +905,37 @@ error:
 	return -1;
 }
 
+/* adds a sock_info structure to the corresponding proto list
+ * return  0 on success, -1 on error */
+int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
+						unsigned short port, unsigned short proto,
+						char *usename, unsigned short useport,
+						enum si_flags flags)
+{
+	return add_listen_advertise_iface_name(name, addr_l, port, proto,
+						usename, useport, NULL, flags);
+}
+
 /* adds a sock_info structure to the corresponding proto list
  * return  0 on success, -1 on error */
 int add_listen_iface(char* name, struct name_lst* addr_l,
 						unsigned short port, unsigned short proto,
 						enum si_flags flags)
 {
-	return add_listen_advertise_iface(name, addr_l, port, proto, 0, 0, flags);
+	return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0, 0,
+			flags);
+}
+
+/* adds a sock_info structure to the corresponding proto list
+ * return  0 on success, -1 on error */
+int add_listen_iface_name(char* name, struct name_lst* addr_l,
+						unsigned short port, unsigned short proto, char *sockname,
+						enum si_flags flags)
+{
+	return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0,
+			sockname, flags);
 }
+
 #ifdef __OS_linux
 
 #include "linux/types.h"
@@ -1433,14 +1469,14 @@ error:
  */
 static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
 								char proto, char *usename,
-								unsigned short useport,
+								unsigned short useport, char *sockname,
 								enum si_flags flags,
 								struct socket_info** list)
 {
 	struct addr_info* ail;
-	
+
 	for (ail=ai_lst; ail; ail=ail->next){
-		if(new_sock2list(ail->name.s, 0, port, proto, usename, useport,
+		if(new_sock2list(ail->name.s, 0, port, proto, usename, useport, sockname,
 					ail->flags | flags, list)==0)
 			return -1;
 	}
@@ -1449,7 +1485,7 @@ static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
 
 
 
-/* insert new elements to a socket_info list after "el", 
+/* insert new elements to a socket_info list after "el",
  * each element is created from addr_info_lst + port, * protocol and flags
  * return 0 on succes, -1 on error
  */
@@ -1458,15 +1494,17 @@ static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
 										char proto,
 										char *usename,
 										unsigned short useport,
+										char *sockname,
 										enum si_flags flags,
 										struct socket_info* el)
 {
 	struct addr_info* ail;
 	struct socket_info* new_si;
-	
+
 	for (ail=ai_lst; ail; ail=ail->next){
 		if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
-								usename, useport, ail->flags | flags, el))==0)
+								usename, useport, sockname,
+								ail->flags | flags, el))==0)
 			return -1;
 		el=new_si;
 	}
@@ -1475,7 +1513,7 @@ static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
 
 
 
-/* fixes a socket list => resolve addresses, 
+/* fixes a socket list => resolve addresses,
  * interface names, fills missing members, remove duplicates
  * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
 static int fix_socket_list(struct socket_info **list, int* type_flags)
@@ -1507,7 +1545,7 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 			if (si->flags & SI_IS_MHOMED){
 				if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
 											si->proto, si->useinfo.name.s,
-											si->useinfo.port_no,
+											si->useinfo.port_no, si->sockname.s,
 											ai_lst->flags|si->flags, si))==0)
 					break;
 				ail=ai_lst;
@@ -1527,12 +1565,11 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 					new_si->addr_info_lst=ail;
 					si->addr_info_lst=0; /* detached and moved to new_si */
 				}
-				
 			}else{
 				/* add all addr. as separate  interfaces */
 				if (addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto,
 							si->useinfo.name.s, si->useinfo.port_no,
-							si->flags, si)!=0)
+							si->sockname.s, si->flags, si)!=0)
 					goto error;
 				/* ai_lst not needed anymore */
 				free_addr_info_lst(&ai_lst);
@@ -1546,7 +1583,7 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 			new_si=si;
 			ail=si->addr_info_lst;
 		}
-		
+
 		if (ail){
 			if (new_si && (new_si->flags & SI_IS_MHOMED)){
 				ai_lst=0;
@@ -1592,7 +1629,7 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 		}
 		strncpy(si->port_no_str.s, tmp, len+1);
 		si->port_no_str.len=len;
-		
+
 		if (fix_hostname(&si->name, &si->address, &si->address_str,
 						&si->flags, type_flags, si) !=0 )
 			goto error;
@@ -1604,9 +1641,9 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 		}
 
 		if (fix_sock_str(si) < 0) goto error;
-		
+
 #ifdef EXTRA_DEBUG
-		printf("              %.*s [%s]:%s%s\n", si->name.len, 
+		printf("              %.*s [%s]:%s%s\n", si->name.len,
 				si->name.s, si->address_str.s, si->port_no_str.s,
 		                si->flags & SI_IS_MCAST ? " mcast" : "");
 #endif
@@ -1669,7 +1706,7 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 		/* check  for & remove internal duplicates: */
 		for (ail=si->addr_info_lst; ail;){
 			ail_next=ail->next;
-			/* 1. check if the extra addresses contain a duplicate for the 
+			/* 1. check if the extra addresses contain a duplicate for the
 			 * main  one */
 			if ((ail->address.af==si->address.af) &&
 				(memcmp(ail->address.u.addr, si->address.u.addr,
@@ -1778,7 +1815,7 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 			){
 			if (si->flags & SI_IS_MCAST){
 				LM_WARN("removing entry %s:%s [%s]:%s\n",
-					get_valid_proto_name(si->proto), si->name.s, 
+					get_valid_proto_name(si->proto), si->name.s,
 					si->address_str.s, si->port_no_str.s);
 				l = si;
 				si=si->next;
@@ -1790,7 +1827,7 @@ static int fix_socket_list(struct socket_info **list, int* type_flags)
 					if (ail->flags & SI_IS_MCAST){
 						LM_WARN("removing mh entry %s:%s"
 								" [%s]:%s\n",
-								get_valid_proto_name(si->proto), ail->name.s, 
+								get_valid_proto_name(si->proto), ail->name.s,
 								ail->address_str.s, si->port_no_str.s);
 						tmp_ail=ail;
 						ail=ail->next;
@@ -1822,9 +1859,9 @@ int fix_all_socket_lists()
 	struct utsname myname;
 	int flags;
 	struct addr_info* ai_lst;
-	
+
 	ai_lst=0;
-	
+
 	if ((udp_listen==0)
 #ifdef USE_TCP
 			&& (tcp_listen==0)
@@ -1843,7 +1880,7 @@ int fix_all_socket_lists()
 #else
 		&& ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0,  PROTO_UDP, &ai_lst) ==0 ) /* add_interface does not work for IPv6 on Linux */
 #endif /* __OS_linux */
-			 ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, 0, 0, &udp_listen)==0)){
+			 ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, &udp_listen)==0)){
 			free_addr_info_lst(&ai_lst);
 			ai_lst=0;
 			/* if ok, try to add the others too */
@@ -1855,7 +1892,7 @@ int fix_all_socket_lists()
 #else
 				|| (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TCP, &ai_lst) !=0 )
 #endif /* __OS_linux */
-				) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0,
+				) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0, 0,
 										 				&tcp_listen)!=0))
 					goto error;
 				free_addr_info_lst(&ai_lst);
@@ -1869,7 +1906,7 @@ int fix_all_socket_lists()
 #else
 				|| (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TLS, &ai_lst)!=0)
 #endif /* __OS_linux */
-					) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, 0,
+					) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, 0, 0,
 										 				&tls_listen)!=0))
 						goto error;
 				}
@@ -1886,7 +1923,7 @@ int fix_all_socket_lists()
 #else
 				|| (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_SCTP, &ai_lst) != 0)
 #endif /* __OS_linux */
-					) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0,
+					) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0, 0,
 							 				&sctp_listen)!=0))
 					goto error;
 				free_addr_info_lst(&ai_lst);
@@ -1972,8 +2009,7 @@ void print_all_socket_lists()
 	struct socket_info** list;
 	struct addr_info* ai;
 	unsigned short proto;
-	
-	
+
 	proto=PROTO_UDP;
 	do{
 		list=get_sock_info_list(proto);
@@ -1982,24 +2018,30 @@ void print_all_socket_lists()
 				printf("             %s: (%s",
 						get_valid_proto_name(proto),
 						si->address_str.s);
-				for (ai=si->addr_info_lst; ai; ai=ai->next)
+				for (ai=si->addr_info_lst; ai; ai=ai->next) {
 					printf(", %s", ai->address_str.s);
+				}
 				printf("):%s%s%s\n",
-						si->port_no_str.s, 
+						si->port_no_str.s,
 						si->flags & SI_IS_MCAST ? " mcast" : "",
 						si->flags & SI_IS_MHOMED? " mhomed" : "");
 			}else{
 				printf("             %s: %s",
 						get_valid_proto_name(proto),
 						si->name.s);
-				if (!(si->flags & SI_IS_IP))
+				if (!(si->flags & SI_IS_IP)) {
 					printf(" [%s]", si->address_str.s);
+				}
 				printf( ":%s%s%s",
-						si->port_no_str.s, 
+						si->port_no_str.s,
 						si->flags & SI_IS_MCAST ? " mcast" : "",
 						si->flags & SI_IS_MHOMED? " mhomed" : "");
-				if (si->useinfo.name.s)
+				if (si->sockname.s) {
+					printf(" name %s", si->sockname.s);
+				}
+				if (si->useinfo.name.s) {
 					printf(" advertise %s:%d", si->useinfo.name.s, si->useinfo.port_no);
+				}
 				printf("\n");
 			}
 		}
@@ -2011,13 +2053,15 @@ void print_aliases()
 {
 	struct host_alias* a;
 
-	for(a=aliases; a; a=a->next) 
-		if (a->port)
-			printf("             %s: %.*s:%d\n", get_valid_proto_name(a->proto), 
+	for(a=aliases; a; a=a->next) {
+		if (a->port) {
+			printf("             %s: %.*s:%d\n", get_valid_proto_name(a->proto),
 					a->alias.len, a->alias.s, a->port);
-		else
-			printf("             %s: %.*s:*\n", get_valid_proto_name(a->proto), 
+		} else {
+			printf("             %s: %.*s:*\n", get_valid_proto_name(a->proto),
 					a->alias.len, a->alias.s);
+		}
+	}
 }
 
 
@@ -2025,7 +2069,7 @@ void print_aliases()
 void init_proto_order()
 {
 	int r;
-	
+
 	/* fix proto list  (remove disabled protocols)*/
 #ifdef USE_TCP
 	if (tcp_disable)

+ 7 - 0
src/core/socket_info.h

@@ -82,10 +82,17 @@ void init_proto_order(void);
 int add_listen_iface(char* name, struct name_lst* nlst,
 						unsigned short port, unsigned short proto,
 						enum si_flags flags);
+int add_listen_iface_name(char* name, struct name_lst* addr_l,
+						unsigned short port, unsigned short proto, char *sockname,
+						enum si_flags flags);
 int add_listen_advertise_iface(char* name, struct name_lst* nlst,
 						unsigned short port, unsigned short proto,
 						char *useaddr, unsigned short useport,
 						enum si_flags flags);
+int add_listen_advertise_iface_name(char* name, struct name_lst* nlst,
+						unsigned short port, unsigned short proto,
+						char *useaddr, unsigned short useport, char *sockname,
+						enum si_flags flags);
 int fix_all_socket_lists(void);
 void print_all_socket_lists(void);
 void print_aliases(void);