瀏覽代碼

- listen & alias accept lists (e.g. listen= 1.2.3.4 5.6.7.8)
- listen & -l accept interface names (e.g -l eth0 or listen= eth0 eth1)
- if no interface is specified ser will listen on all the UP ipv4 interfaces
it can find
- ser will remove duplicate addresses automatically (e.g -l 1.2.3.4 -l 1.2.3.4
works now)

Andrei Pelinescu-Onciul 23 年之前
父節點
當前提交
57e2cd15b8
共有 6 個文件被更改,包括 317 次插入106 次删除
  1. 1 1
      Makefile.defs
  2. 87 80
      cfg.y
  3. 24 0
      ip_addr.h
  4. 198 19
      main.c
  5. 3 2
      msg_translator.c
  6. 4 4
      test/stateless.cfg

+ 1 - 1
Makefile.defs

@@ -8,7 +8,7 @@
 VERSION = 0
 VERSION = 0
 PATCHLEVEL = 8
 PATCHLEVEL = 8
 SUBLEVEL = 7
 SUBLEVEL = 7
-EXTRAVERSION = -11-srv2
+EXTRAVERSION = -12-listen
 
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s)
 OS = $(shell uname -s)

+ 87 - 80
cfg.y

@@ -30,10 +30,17 @@
 #endif
 #endif
 
 
 
 
+struct id_list{
+	char* s;
+	struct id_list* next;
+};
+
 extern int yylex();
 extern int yylex();
 void yyerror(char* s);
 void yyerror(char* s);
 char* tmp;
 char* tmp;
 void* f_tmp;
 void* f_tmp;
+struct id_list* lst_tmp;
+
 
 
 %}
 %}
 
 
@@ -45,6 +52,7 @@ void* f_tmp;
 	struct action* action;
 	struct action* action;
 	struct net* ipnet;
 	struct net* ipnet;
 	struct ip_addr* ipaddr;
 	struct ip_addr* ipaddr;
+	struct id_list* idlst;
 }
 }
 
 
 /* terminals */
 /* terminals */
@@ -142,6 +150,8 @@ void* f_tmp;
 %type <ipaddr> ipv4, ipv6, ip
 %type <ipaddr> ipv4, ipv6, ip
 %type <ipnet> ipnet
 %type <ipnet> ipnet
 %type <strval> host
 %type <strval> host
+%type <strval> listen_id
+%type <idlst>  id_lst
 /*%type <route_el> rules;
 /*%type <route_el> rules;
   %type <route_el> rule;
   %type <route_el> rule;
 */
 */
@@ -166,6 +176,67 @@ statement:	assign_stm
 		| CR	/* null statement*/
 		| CR	/* null statement*/
 	;
 	;
 
 
+listen_id:	ip			{	tmp=ip_addr2a($1);
+		 					if(tmp==0){
+								LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
+										"addresss.\n");
+								$$=0;
+							}else{
+								$$=malloc(strlen(tmp)+1);
+								if ($$==0){
+									LOG(L_CRIT, "ERROR: cfg. parser: out of "
+											"memory.\n");
+								}else{
+									strncpy($$, tmp, strlen(tmp)+1);
+								}
+							}
+						}
+		 |	ID			{	$$=malloc(strlen($1)+1);
+		 					if ($$==0){
+									LOG(L_CRIT, "ERROR: cfg. parser: out of "
+											"memory.\n");
+							}else{
+									strncpy($$, $1, strlen($1)+1);
+							}
+						}
+		 |	STRING			{	$$=malloc(strlen($1)+1);
+		 					if ($$==0){
+									LOG(L_CRIT, "ERROR: cfg. parser: out of "
+											"memory.\n");
+							}else{
+									strncpy($$, $1, strlen($1)+1);
+							}
+						}
+		 |	host		{	$$=malloc(strlen($1)+1);
+		 					if ($$==0){
+									LOG(L_CRIT, "ERROR: cfg. parser: out of "
+											"memory.\n");
+							}else{
+									strncpy($$, $1, strlen($1)+1);
+							}
+						}
+	;
+
+id_lst:	  listen_id	{	$$=malloc(sizeof(struct id_list));
+						if ($$==0){
+							LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
+						}else{
+							$$->s=$1;
+							$$->next=0;
+						}
+					}
+		| listen_id id_lst	{
+						$$=malloc(sizeof(struct id_list));
+						if ($$==0){
+							LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
+						}else{
+							$$->s=$1;
+							$$->next=$2;
+						}
+							}
+		;
+
+
 assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 		| DEBUG EQUAL error  { yyerror("number  expected"); }
 		| DEBUG EQUAL error  { yyerror("number  expected"); }
 		| FORK  EQUAL NUMBER { dont_fork= ! $3; }
 		| FORK  EQUAL NUMBER { dont_fork= ! $3; }
@@ -204,87 +275,21 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
 		| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
 		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
 		| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
 		| REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
 		| REPLY_TO_VIA EQUAL error { yyerror("boolean value expected"); }
-		| LISTEN EQUAL ip  {
-								if (sock_no< MAX_LISTEN){
-									tmp=ip_addr2a($3);
-								/*	tmp=inet_ntoa(*(struct in_addr*)&$3);*/
-									if (tmp==0){
-										LOG(L_CRIT, "ERROR: cfg. parser: "
-											" bad ip address: %s\n",
-											strerror(errno));
-									}else{
-										sock_info[sock_no].name.s=
-												(char*)malloc(strlen(tmp)+1);
-										if (sock_info[sock_no].name.s==0){
-											LOG(L_CRIT, "ERROR: cfg. parser: "
-														"out of memory.\n");
-										}else{
-											strncpy(sock_info[sock_no].name.s,
-													tmp, strlen(tmp)+1);
-											sock_info[sock_no].name.len=
-													strlen(tmp);
-											sock_info[sock_no].port_no=
-													port_no;
-											sock_no++;
-										}
-									}
-								}else{
-									LOG(L_CRIT, "ERROR: cfg. parser:"
-												" too many listen addresses"
-												"(max. %d).\n", MAX_LISTEN);
-								}
-							  }
-		| LISTEN EQUAL ID	 {
-								if (sock_no < MAX_LISTEN){
-									sock_info[sock_no].name.s=
-												(char*)malloc(strlen($3)+1);
-									if (sock_info[sock_no].name.s==0){
-										LOG(L_CRIT, "ERROR: cfg. parser:"
-														" out of memory.\n");
-									}else{
-										strncpy(sock_info[sock_no].name.s, $3,
-													strlen($3)+1);
-										sock_info[sock_no].name.len=strlen($3);
-										sock_info[sock_no].port_no= port_no;
-										sock_no++;
-									}
-								}else{
-									LOG(L_CRIT, "ERROR: cfg. parser: "
-												"too many listen addresses"
-												"(max. %d).\n", MAX_LISTEN);
-								}
-							  }
-		| LISTEN EQUAL STRING {
-								if (sock_no < MAX_LISTEN){
-									sock_info[sock_no].name.s=
-										(char*)malloc(strlen($3)+1);
-									if (sock_info[sock_no].name.s==0){
-										LOG(L_CRIT, "ERROR: cfg. parser:"
-													" out of memory.\n");
-									}else{
-										strncpy(sock_info[sock_no].name.s, $3,
-												strlen($3)+1);
-										sock_info[sock_no].name.len=strlen($3);
-										sock_info[sock_no].port_no=port_no;
-										sock_no++;
-									}
-								}else{
-									LOG(L_CRIT, "ERROR: cfg. parser: "
-												"too many listen addresses"
-												"(max. %d).\n", MAX_LISTEN);
-								}
-							  }
-		| LISTEN EQUAL  host {
+		| LISTEN EQUAL id_lst {
+							for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next){
 								if (sock_no < MAX_LISTEN){
 								if (sock_no < MAX_LISTEN){
 									sock_info[sock_no].name.s=
 									sock_info[sock_no].name.s=
-										(char*)malloc(strlen($3)+1);
+										(char*)malloc(strlen(lst_tmp->s)+1);
 									if (sock_info[sock_no].name.s==0){
 									if (sock_info[sock_no].name.s==0){
 										LOG(L_CRIT, "ERROR: cfg. parser:"
 										LOG(L_CRIT, "ERROR: cfg. parser:"
 													" out of memory.\n");
 													" out of memory.\n");
+										break;
 									}else{
 									}else{
-										strncpy(sock_info[sock_no].name.s, $3,
-												strlen($3)+1);
-										sock_info[sock_no].name.len=strlen($3);
+										strncpy(sock_info[sock_no].name.s,
+												lst_tmp->s,
+												strlen(lst_tmp->s)+1);
+										sock_info[sock_no].name.len=
+													strlen(lst_tmp->s);
 										sock_info[sock_no].port_no=port_no;
 										sock_info[sock_no].port_no=port_no;
 										sock_no++;
 										sock_no++;
 									}
 									}
@@ -292,14 +297,16 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 									LOG(L_CRIT, "ERROR: cfg. parser: "
 									LOG(L_CRIT, "ERROR: cfg. parser: "
 												"too many listen addresses"
 												"too many listen addresses"
 												"(max. %d).\n", MAX_LISTEN);
 												"(max. %d).\n", MAX_LISTEN);
+									break;
 								}
 								}
-							  }
-		
+							}
+							 }
 		| LISTEN EQUAL  error { yyerror("ip address or hostname"
 		| LISTEN EQUAL  error { yyerror("ip address or hostname"
 						"expected"); }
 						"expected"); }
-		| ALIAS  EQUAL STRING { add_alias($3, strlen($3)); }
-		| ALIAS  EQUAL ID     { add_alias($3, strlen($3)); }
-		| ALIAS  EQUAL host   { add_alias($3, strlen($3)); }
+		| ALIAS EQUAL  id_lst { 
+								for(lst_tmp=$3; lst_tmp; lst_tmp=lst_tmp->next)
+									add_alias(lst_tmp->s, strlen(lst_tmp->s));
+							  }
 		| ALIAS  EQUAL error  { yyerror(" hostname expected"); }
 		| ALIAS  EQUAL error  { yyerror(" hostname expected"); }
 		| error EQUAL { yyerror("unknown config variable"); }
 		| error EQUAL { yyerror("unknown config variable"); }
 	;
 	;

+ 24 - 0
ip_addr.h

@@ -117,6 +117,30 @@ inline static int matchnet(struct ip_addr* ip, struct net* net)
 
 
 
 
 
 
+/* inits an ip_addr pointer from a sockaddr structure*/
+static inline void sockaddr2ip_addr(struct ip_addr* ip, struct sockaddr* sa)
+{
+	switch(sa->sa_family){
+	case AF_INET:
+			ip->af=AF_INET;
+			ip->len=4;
+			memcpy(ip->u.addr, &((struct sockaddr_in*)sa)->sin_addr, 4);
+			break;
+#ifdef USE_IPV6
+	case AF_INET6:
+			ip->af=AF_INET6;
+			ip->len=16;
+			memcpy(ip->u.addr, &((struct sockaddr_in6*)sa)->sin6_addr, 16);
+			break;
+#endif
+	default:
+			LOG(L_CRIT, "sockaddr2ip_addr: BUG: unknown address family %d\n",
+					sa->sa_family);
+	}
+}
+
+
+
 /* inits an ip_addr pointer from a sockaddr_union ip address */
 /* inits an ip_addr pointer from a sockaddr_union ip address */
 static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
 static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
 {
 {

+ 198 - 19
main.c

@@ -20,6 +20,12 @@
 #include <sys/wait.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <signal.h>
 
 
+#include <sys/ioctl.h>
+#include <net/if.h>
+#ifdef __sun__
+#include <sys/sockio.h>
+#endif
+
 #include "config.h"
 #include "config.h"
 #include "dprint.h"
 #include "dprint.h"
 #include "route.h"
 #include "route.h"
@@ -681,14 +687,129 @@ static void sig_usr(int signo)
 
 
 
 
 
 
-void test();
+/* add all family type addresses of interface if_name to the socket_info array
+ * if if_name==0, adds all addresses on all interfaces
+ * WARNING: it only works with ipv6 addresses on FreeBSD
+ * return: -1 on error, 0 on success
+ */
+int add_interfaces(char* if_name, int family, unsigned short port)
+{
+	struct ifconf ifc;
+	struct ifreq* ifr;
+	struct ifreq ifrcopy;
+	char*  last;
+	int size;
+	int lastlen;
+	int s;
+	char* tmp;
+	struct ip_addr addr;
+	int ret;
+	
+	/* ipv4 or ipv6 only*/
+	s=socket(family, SOCK_DGRAM, 0);
+	ret=-1;
+	lastlen=0;
+	ifc.ifc_req=0;
+	for (size=10; ; size*=2){
+		ifc.ifc_len=size*sizeof(struct ifreq);
+		ifc.ifc_req=(struct ifreq*) malloc(size*sizeof(struct ifreq));
+		if (ifc.ifc_req==0){
+			fprintf(stderr, "memory allocation failure\n");
+			goto error;
+		}
+		if (ioctl(s, SIOCGIFCONF, &ifc)==-1){
+			if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
+			fprintf(stderr, "ioctl failed: %s\n", strerror(errno));
+			goto error;
+		}
+		if  ((lastlen) && (ifc.ifc_len==lastlen)) break; /*success,
+														   len not changed*/
+		lastlen=ifc.ifc_len;
+		/* try a bigger array*/
+		free(ifc.ifc_req);
+	}
+	
+	last=(char*)ifc.ifc_req+ifc.ifc_len;
+	for(ifr=ifc.ifc_req; (char*)ifr<last;
+			ifr=(struct ifreq*)((char*)ifr+sizeof(ifr->ifr_name)+
+			#ifdef  __FreeBSD__
+				MAX(ifr->ifr_addr.sa_len, sizeof(struct sockaddr))
+			#else
+				( (ifr->ifr_addr.sa_family==AF_INET)?
+					sizeof(struct sockaddr_in):
+					((ifr->ifr_addr.sa_family==AF_INET6)?
+						sizeof(struct sockaddr_in6):sizeof(struct sockaddr)) )
+			#endif
+				)
+		)
+	{
+		if (ifr->ifr_addr.sa_family!=family){
+			/*printf("strange family %d skipping...\n",
+					ifr->ifr_addr.sa_family);*/
+			continue;
+		}
+		
+		if (if_name==0){ /* ignore down ifs only if listening on all of them*/
+			memcpy(&ifrcopy, ifr, sizeof(ifrcopy));
+			/*get flags*/
+			if (ioctl(s, SIOCGIFFLAGS,  &ifrcopy)!=-1){ /* ignore errors */
+				/* if if not up, skip it*/
+				if (!(ifrcopy.ifr_flags & IFF_UP)) continue;
+			}
+		}
+		
+		
+		
+		if ((if_name==0)||
+			(strncmp(if_name, ifr->ifr_name, sizeof(ifr->ifr_name))==0)){
+			
+				/*add address*/
+			if (sock_no<MAX_LISTEN){
+				sockaddr2ip_addr(&addr, &ifr->ifr_addr);
+				if ((tmp=ip_addr2a(&addr))==0) goto error;
+				/* fill the strings*/
+				sock_info[sock_no].name.s=(char*)malloc(strlen(tmp)+1);
+				if(sock_info[sock_no].name.s==0){
+					fprintf(stderr, "Out of memory.\n");
+					goto error;
+				}
+				/* fill in the new name and port */
+				sock_info[sock_no].name.len=strlen(tmp);
+				strncpy(sock_info[sock_no].name.s, tmp, 
+							sock_info[sock_no].name.len+1);
+				sock_info[sock_no].port_no=port;
+				sock_no++;
+				ret=0;
+			}else{
+				fprintf(stderr, "Too many addresses (max %d)\n", MAX_LISTEN);
+				goto error;
+			}
+		}
+			/*
+			printf("%s:\n", ifr->ifr_name);
+			printf("        ");
+			print_sockaddr(&(ifr->ifr_addr));
+			printf("        ");
+			ls_ifflags(ifr->ifr_name, family, options);
+			printf("\n");*/
+	}
+	free(ifc.ifc_req); /*clean up*/
+	close(s);
+	return  ret;
+error:
+	if (ifc.ifc_req) free(ifc.ifc_req);
+	close(s);
+	return -1;
+}
+
+
 
 
 int main(int argc, char** argv)
 int main(int argc, char** argv)
 {
 {
 
 
 	FILE* cfg_stream;
 	FILE* cfg_stream;
 	struct hostent* he;
 	struct hostent* he;
-	int c,r;
+	int c,r,t;
 	char *tmp;
 	char *tmp;
 	char** h;
 	char** h;
 	struct host_alias* a;
 	struct host_alias* a;
@@ -963,24 +1084,42 @@ int main(int argc, char** argv)
 	memset(pids, 0, sizeof(int)*(children_no+1));
 	memset(pids, 0, sizeof(int)*(children_no+1));
 
 
 	if (sock_no==0) {
 	if (sock_no==0) {
-		/* get our address, only the first one */
-		if (uname (&myname) <0){
-			fprintf(stderr, "cannot determine hostname, try -l address\n");
-			goto error;
-		}
-		sock_info[sock_no].name.s=(char*)malloc(strlen(myname.nodename)+1);
-		if (sock_info[sock_no].name.s==0){
-			fprintf(stderr, "Out of memory.\n");
-			goto error;
+		/* try to get all listening ipv4 interfaces */
+		if (add_interfaces(0, AF_INET, 0)==-1){
+			/* if error fall back to get hostname*/
+			/* get our address, only the first one */
+			if (uname (&myname) <0){
+				fprintf(stderr, "cannot determine hostname, try -l address\n");
+				goto error;
+			}
+			sock_info[sock_no].name.s=(char*)malloc(strlen(myname.nodename)+1);
+			if (sock_info[sock_no].name.s==0){
+				fprintf(stderr, "Out of memory.\n");
+				goto error;
+			}
+			sock_info[sock_no].name.len=strlen(myname.nodename);
+			strncpy(sock_info[sock_no].name.s, myname.nodename,
+					sock_info[sock_no].name.len+1);
+			sock_no++;
 		}
 		}
-		sock_info[sock_no].name.len=strlen(myname.nodename);
-		strncpy(sock_info[sock_no].name.s, myname.nodename,
-				sock_info[sock_no].name.len+1);
-		sock_no++;
 	}
 	}
 
 
+	/* try to change all the interface names into addresses
+	 *  --ugly hack */
+	for (r=0; r<sock_no;){
+		if (add_interfaces(sock_info[r].name.s, AF_INET,
+					sock_info[r].port_no)!=-1){
+			/* success => remove current entry (shift the entire array)*/
+			free(sock_info[r].name.s);
+			memmove(&sock_info[r], &sock_info[r+1], 
+						(sock_no-r)*sizeof(struct socket_info));
+			sock_no--;
+			continue;
+		}
+		r++;
+	}
 	/* get ips & fill the port numbers*/
 	/* get ips & fill the port numbers*/
-	printf("Listening on ");
+	printf("Listening on \n");
 	for (r=0; r<sock_no;r++){
 	for (r=0; r<sock_no;r++){
 		he=resolvehost(sock_info[r].name.s);
 		he=resolvehost(sock_info[r].name.s);
 		if (he==0){
 		if (he==0){
@@ -1010,7 +1149,7 @@ int main(int argc, char** argv)
 		
 		
 		hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr 
 		hostent2ip_addr(&sock_info[r].address, he, 0); /*convert to ip_addr 
 														 format*/
 														 format*/
-		tmp=ip_addr2a(&sock_info[r].address);
+		if ((tmp=ip_addr2a(&sock_info[r].address))==0) goto error;
 		sock_info[r].address_str.s=(char*)malloc(strlen(tmp)+1);
 		sock_info[r].address_str.s=(char*)malloc(strlen(tmp)+1);
 		if (sock_info[r].address_str.s==0){
 		if (sock_info[r].address_str.s==0){
 			fprintf(stderr, "Out of memory.\n");
 			fprintf(stderr, "Out of memory.\n");
@@ -1045,9 +1184,49 @@ int main(int argc, char** argv)
 		strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1);
 		strncpy(sock_info[r].port_no_str.s, port_no_str, strlen(port_no_str)+1);
 		sock_info[r].port_no_str.len=strlen(port_no_str);
 		sock_info[r].port_no_str.len=strlen(port_no_str);
 		
 		
-		printf("%s [%s]:%s\n",sock_info[r].name.s, sock_info[r].address_str.s,
-				sock_info[r].port_no_str.s);
+		printf("              %s [%s]:%s\n",sock_info[r].name.s,
+				sock_info[r].address_str.s, sock_info[r].port_no_str.s);
+	}
+	/* removing duplicate addresses*/
+	for (r=0; r<sock_no; r++){
+		for (t=r+1; t<sock_no;){
+			if ((sock_info[r].port_no==sock_info[t].port_no) &&
+				(sock_info[r].address.af==sock_info[t].address.af) &&
+				(memcmp(sock_info[r].address.u.addr, 
+						sock_info[t].address.u.addr,
+						sock_info[r].address.len)  == 0)
+				){
+				printf("removing duplicate (%d) %s [%s] == (%d) %s [%s]\n",
+						r, sock_info[r].name.s, sock_info[r].address_str.s,
+						t, sock_info[t].name.s, sock_info[t].address_str.s);
+				
+				/* add the name to the alias list*/
+				if ((!sock_info[t].is_ip) && (
+						(sock_info[t].name.len!=sock_info[r].name.len)||
+						(strncmp(sock_info[t].name.s, sock_info[r].name.s,
+								 sock_info[r].name.len)!=0))
+					)
+					add_alias(sock_info[t].name.s, sock_info[t].name.len);
+						
+				/* free space*/
+				free(sock_info[t].name.s);
+				free(sock_info[t].address_str.s);
+				free(sock_info[t].port_no_str.s);
+				/* shift the array*/
+				memmove(&sock_info[t], &sock_info[t+1], 
+							(sock_no-t)*sizeof(struct socket_info));
+				sock_no--;
+				continue;
+			}
+			t++;
+		}
 	}
 	}
+	/* print all the listen addresses */
+	printf("Listening on \n");
+	for (r=0; r<sock_no; r++)
+		printf("              %s [%s]:%s\n",sock_info[r].name.s,
+				sock_info[r].address_str.s, sock_info[r].port_no_str.s);
+
 	printf("Aliases: ");
 	printf("Aliases: ");
 	for(a=aliases; a; a=a->next) printf("%.*s ", a->alias.len, a->alias.s);
 	for(a=aliases; a; a=a->next) printf("%.*s ", a->alias.len, a->alias.s);
 	printf("\n");
 	printf("\n");

+ 3 - 2
msg_translator.c

@@ -53,7 +53,7 @@ int check_address(struct ip_addr* ip, char *name, int resolver)
 	/* maybe we are lucky and name it's an ip */
 	/* maybe we are lucky and name it's an ip */
 	s=ip_addr2a(ip);
 	s=ip_addr2a(ip);
 	if (s){
 	if (s){
-		DBG("check_address(%s, %s, %d)\n", ip_addr2a(ip), name, resolver);
+		DBG("check_address(%s, %s, %d)\n", s, name, resolver);
 	#ifdef USE_IPV6
 	#ifdef USE_IPV6
 		if ((ip->af==AF_INET6) && (strcasecmp(name, s)==0))
 		if ((ip->af==AF_INET6) && (strcasecmp(name, s)==0))
 				return 0;
 				return 0;
@@ -164,7 +164,8 @@ char* received_builder(struct sip_msg *msg, int *received_len)
 							inet_ntoa(*(struct in_addr *)&source_ip));
 							inet_ntoa(*(struct in_addr *)&source_ip));
 	*/
 	*/
 	memcpy(buf, RECEIVED, RECEIVED_LEN);
 	memcpy(buf, RECEIVED, RECEIVED_LEN);
-	tmp=ip_addr2a(source_ip);
+	if ( (tmp=ip_addr2a(source_ip))==0)
+		return 0; /* error*/
 	tmp_len=strlen(tmp);
 	tmp_len=strlen(tmp);
 	len=RECEIVED_LEN+tmp_len;
 	len=RECEIVED_LEN+tmp_len;
 	if(source_ip->af==AF_INET6){
 	if(source_ip->af==AF_INET6){

+ 4 - 4
test/stateless.cfg

@@ -6,9 +6,8 @@
 
 
 
 
 debug=9          # debug level (cmd line: -dddddddddd)
 debug=9          # debug level (cmd line: -dddddddddd)
-#fork=yes          # (cmd. line: -D)
-fork=yes
-fork=no
+fork=yes          # (cmd. line: -D)
+#fork=no
 log_stderror=yes # (cmd line: -E)
 log_stderror=yes # (cmd line: -E)
 #log_stderror=no	# (cmd line: -E)
 #log_stderror=no	# (cmd line: -E)
 
 
@@ -18,7 +17,8 @@ check_via=no     # (cmd. line: -v)
 dns=off           # (cmd. line: -r)
 dns=off           # (cmd. line: -r)
 rev_dns=off      # (cmd. line: -R)
 rev_dns=off      # (cmd. line: -R)
 #port=5070
 #port=5070
-#listen=10.0.0.179
+listen=10.0.0.179 lo	dorian
+listen=eth0
 #listen=127.0.0.1
 #listen=127.0.0.1
 #listen=192.168.57.33
 #listen=192.168.57.33
 #listen=192.168.57.72
 #listen=192.168.57.72