core: function to search socket by name
[sip-router] / src / core / socket_info.c
1
2 /* 
3  * find & manage listen addresses 
4  *
5  * Copyright (C) 2001-2003 FhG Fokus
6  *
7  * This file is part of Kamailio, a free SIP server.
8  *
9  * Kamailio is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * Kamailio is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License 
20  * along with this program; if not, write to the Free Software 
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23
24 /*!
25  * \file
26  * \brief Kamailio core :: find & manage listen addresses 
27  *
28  * This file contains code that initializes and handles Kamailio listen addresses
29  * lists (struct socket_info). It is used mainly on startup.
30  * \ingroup core
31  * Module: \ref core
32  */
33
34 #include <string.h>
35 #include <errno.h>
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <sys/utsname.h>
40 #include <stdio.h>
41
42 #include <sys/ioctl.h>
43 #include <net/if.h>
44 #include <ifaddrs.h>
45 #include <netdb.h>
46 #ifdef HAVE_SYS_SOCKIO_H
47 #include <sys/sockio.h>
48 #endif
49
50 #include "globals.h"
51 #include "socket_info.h"
52 #include "dprint.h"
53 #include "mem/mem.h"
54 #include "ut.h"
55 #include "resolve.h"
56 #include "name_alias.h"
57
58
59
60 /* list manip. functions (internal use only) */
61
62
63 /* append */
64 #define sock_listadd(head, el) \
65         do{\
66                 if (*(head)==0) *(head)=(el); \
67                 else{ \
68                         for((el)->next=*(head); (el)->next->next;\
69                                         (el)->next=(el)->next->next); \
70                         (el)->next->next=(el); \
71                         (el)->prev=(el)->next; \
72                         (el)->next=0; \
73                 }\
74         }while(0)
75
76
77 /* insert after "after" */
78 #define sock_listins(el, after) \
79         do{ \
80                 if ((after)){\
81                         (el)->next=(after)->next; \
82                         if ((after)->next) (after)->next->prev=(el); \
83                         (after)->next=(el); \
84                         (el)->prev=(after); \
85                 }else{ /* after==0 = list head */ \
86                         (after)=(el); \
87                         (el)->next=(el)->prev=0; \
88                 }\
89         }while(0)
90
91
92 #define sock_listrm(head, el) \
93         do {\
94                 if (*(head)==(el)) *(head)=(el)->next; \
95                 if ((el)->next) (el)->next->prev=(el)->prev; \
96                 if ((el)->prev) (el)->prev->next=(el)->next; \
97         }while(0)
98
99
100 #define addr_info_listadd sock_listadd
101 #define addr_info_listins sock_listins
102 #define addr_info_listrm sock_listrm
103
104 /**
105  * return the scope for IPv6 interface matching the ipval parameter
106  * - needed for binding to link local IPv6 addresses
107  */
108 unsigned int ipv6_get_netif_scope(char *ipval)
109 {
110         struct ifaddrs *netiflist = NULL;
111         struct ifaddrs *netif = NULL;
112         char ipaddr[NI_MAXHOST];
113         unsigned int iscope = 0;
114         int i = 0;
115         int r = 0;
116         ip_addr_t *ipa = NULL;
117         ip_addr_t vaddr;
118         str ips;
119
120         ips.s = ipval;
121         ips.len = strlen(ipval);
122
123         ipa = str2ip6(&ips);
124         if(ipa==NULL) {
125                 LM_ERR("could not parse ipv6 address: %s\n", ipval);
126                 return 0;
127         }
128         memcpy(&vaddr, ipa, sizeof(ip_addr_t));
129         ipa = NULL;
130
131         /* walk over the list of all network interface addresses */
132         if(getifaddrs(&netiflist)!=0) {
133                 LM_ERR("failed to get network interfaces - errno: %d\n", errno);
134                 return 0;
135         }
136         for(netif = netiflist; netif; netif = netif->ifa_next) {
137                 /* only active and ipv6 */
138                 if (netif->ifa_addr && (netif->ifa_flags & IFF_UP)
139                                         && netif->ifa_addr->sa_family==AF_INET6) {
140                         r = getnameinfo(netif->ifa_addr, sizeof(struct sockaddr_in6),
141                                         ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST);
142                         if(r!=0) {
143                                 LM_ERR("failed to get the name info - ret: %d\n", r);
144                                 goto done;
145                         }
146                         /* strip the interface name after */
147                         for(i=0; ipaddr[i]; i++) {
148                                 if(ipaddr[i]=='%') {
149                                         ipaddr[i]='\0';
150                                         break;
151                                 }
152                         }
153                         ips.s = ipaddr;
154                         ips.len = strlen(ipaddr);
155                         ipa = str2ip6(&ips);
156                         if(ipa!=NULL) {
157                                 /* if the ips match, get scope index from interface name */
158                                 if(ip_addr_cmp(&vaddr, ipa)) {
159                                         iscope=if_nametoindex(netif->ifa_name);
160                                         goto done;
161                                 }
162                         }
163                 }
164         }
165
166 done:
167         freeifaddrs(netiflist);
168         return iscope;
169 }
170
171 inline static void addr_info_list_ins_lst(struct addr_info* lst,
172                                                                                 struct addr_info* after)
173 {
174         struct addr_info* l;
175         struct addr_info* n;
176         
177         if (lst){
178                 n=after->next;
179                 after->next=lst;
180                 lst->prev=after;
181                 if (n){
182                         for(l=lst; l->next; l=l->next);
183                         l->next=n;
184                         n->prev=l;
185                 }
186         }
187 }
188
189
190 /* protocol order, filled by init_proto_order() */
191 enum sip_protos nxt_proto[PROTO_LAST+1]=
192 { PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, 0 };
193 /* Deliberately left PROTO_WS and PROTO_WSS out of this as they are just
194    upgraded TCP and TLS connections */
195
196
197
198 /* another helper function, it just fills a struct addr_info
199  * returns: 0 on success, -1 on error*/
200 static int init_addr_info(struct addr_info* a,
201                                                                 char* name, enum si_flags flags)
202 {
203
204         memset(a, 0, sizeof(*a));
205         a->name.len=strlen(name);
206         a->name.s=pkg_malloc(a->name.len+1); /* include \0 */
207         if (a->name.s==0) goto error;
208         memcpy(a->name.s, name, a->name.len+1);
209         a->flags=flags;
210         return 0;
211 error:
212         PKG_MEM_ERROR;
213         return -1;
214 }
215
216
217
218 /* returns 0 on error, new addr_info_lst element on success */
219 static inline struct addr_info* new_addr_info(char* name, 
220                                                                                                         enum si_flags gf)
221 {
222         struct addr_info* al;
223         
224         al=pkg_malloc(sizeof(*al));
225         if (al==0) goto error;
226         al->next=0;
227         al->prev=0;
228         if (init_addr_info(al, name, gf)!=0) goto error;
229         return al;
230 error:
231         PKG_MEM_ERROR;
232         if (al){
233                 if (al->name.s) pkg_free(al->name.s);
234                 pkg_free(al);
235         }
236         return 0;
237 }
238
239
240
241 static inline void free_addr_info(struct addr_info* a)
242 {
243         if (a){
244                 if (a->name.s){
245                         pkg_free(a->name.s);
246                         a->name.s=0;
247                 }
248                 pkg_free(a);
249         }
250 }
251
252
253
254 static inline void free_addr_info_lst(struct addr_info** lst)
255 {
256         struct addr_info* a;
257         struct addr_info* tmp;
258         
259         a=*lst;
260         while(a){
261                 tmp=a;
262                 a=a->next;
263                 free_addr_info(tmp);
264         }
265 }
266
267
268
269 /* adds a new add_info_lst element to the corresponding list
270  * returns 0 on success, -1 on error */
271 static int new_addr_info2list(char* name, enum si_flags f,
272                                                                 struct addr_info** l)
273 {
274         struct addr_info * al;
275         
276         al=new_addr_info(name, f);
277         if (al==0) goto error;
278         addr_info_listadd(l, al);
279         return 0;
280 error:
281         return -1;
282 }
283
284
285
286 /* another helper function, it just creates a socket_info struct
287  * allocates a si and a si->name in new pkg memory */
288 static inline struct socket_info* new_sock_info(        char* name,
289                                                                 struct name_lst* addr_l,
290                                                                 unsigned short port, unsigned short proto,
291                                                                 char *usename, unsigned short useport,
292                                                                 char *sockname, enum si_flags flags)
293 {
294         struct socket_info* si;
295         struct name_lst* n;
296         struct hostent* he;
297         char *p;
298
299         si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
300         if (si==0) goto error;
301         memset(si, 0, sizeof(struct socket_info));
302         si->socket=-1;
303         si->name.len=strlen(name);
304         si->name.s=(char*)pkg_malloc(si->name.len+1); /* include \0 */
305         if (si->name.s==0) goto error;
306         memcpy(si->name.s, name, si->name.len+1);
307         /* set port & proto */
308         si->port_no=port;
309         si->proto=proto;
310         si->flags=flags;
311         si->addr_info_lst=0;
312         for (n=addr_l; n; n=n->next){
313                 if (new_addr_info2list(n->name, n->flags, &si->addr_info_lst)!=0){
314                         LM_ERR("new_addr_info2list failed\n");
315                         goto error;
316                 }
317         }
318         if(sockname!=NULL) {
319                 si->sockname.len = strlen(sockname);
320                 si->sockname.s=(char*)pkg_malloc(si->sockname.len+1); /* include \0 */
321                 if (si->sockname.s==0) { goto error; }
322                 memcpy(si->sockname.s, sockname, si->sockname.len+1);
323         }
324         if(usename!=NULL)
325         {
326                 si->useinfo.name.len=strlen(usename);
327                 si->useinfo.name.s=(char*)pkg_malloc(si->useinfo.name.len+1);
328                 if (si->useinfo.name.s==0)
329                         goto error;
330                 strcpy(si->useinfo.name.s, usename);
331                 if(usename[0]=='[' && usename[si->useinfo.name.len-1]==']')
332                 {
333                         si->useinfo.address_str.len = si->useinfo.name.len - 2;
334                         p = si->useinfo.name.s + 1;
335                 } else {
336                         si->useinfo.address_str.len = si->useinfo.name.len;
337                         p = si->useinfo.name.s;
338                 }
339                 si->useinfo.address_str.s=(char*)pkg_malloc(si->useinfo.address_str.len+1);
340                 if(si->useinfo.address_str.s==NULL)
341                         goto error;
342                 strncpy(si->useinfo.address_str.s, p, si->useinfo.address_str.len);
343                 si->useinfo.address_str.s[si->useinfo.address_str.len] = '\0';
344
345                 p = int2str(useport, &si->useinfo.port_no_str.len);
346                 if(p==NULL)
347                         goto error;
348                 si->useinfo.port_no_str.s=(char*)pkg_malloc(si->useinfo.port_no_str.len+1);
349                 if(si->useinfo.port_no_str.s==NULL)
350                         goto error;
351                 strcpy(si->useinfo.port_no_str.s, p);
352                 si->useinfo.port_no = useport;
353
354                 he=resolvehost(si->useinfo.name.s);
355                 if (he==0){
356                         LM_ERR("unable to resolve advertised name %s\n", si->useinfo.name.s);
357                         goto error;
358                 }
359                 hostent2ip_addr(&si->useinfo.address, he, 0);
360         }
361         return si;
362 error:
363         PKG_MEM_ERROR;
364         if (si) {
365                 if(si->name.s) {
366                         pkg_free(si->name.s);
367                 }
368                 if(si->sockname.s) {
369                         pkg_free(si->sockname.s);
370                 }
371                 pkg_free(si);
372         }
373         return 0;
374 }
375
376
377
378 /*  delete a socket_info struct */
379 static void free_sock_info(struct socket_info* si)
380 {
381         if(si){
382                 if(si->name.s) pkg_free(si->name.s);
383                 if(si->address_str.s) pkg_free(si->address_str.s);
384                 if(si->port_no_str.s) pkg_free(si->port_no_str.s);
385                 if(si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
386                 if(si->sock_str.s) pkg_free(si->sock_str.s);
387                 if(si->sockname.s) pkg_free(si->sockname.s);
388                 if(si->useinfo.name.s) pkg_free(si->useinfo.name.s);
389                 if(si->useinfo.port_no_str.s) pkg_free(si->useinfo.port_no_str.s);
390                 if(si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
391         }
392 }
393
394
395
396 char* get_valid_proto_name(unsigned short proto)
397 {
398         switch(proto){
399                 case PROTO_NONE:
400                         return "*";
401                 case PROTO_UDP:
402                         return "udp";
403 #ifdef USE_TCP
404                 case PROTO_TCP:
405                         return "tcp";
406 #endif
407 #ifdef USE_TLS
408                 case PROTO_TLS:
409                         return "tls";
410 #endif
411 #ifdef USE_SCTP
412                 case PROTO_SCTP:
413                         return "sctp";
414 #endif
415                 default:
416                         return "unknown";
417         }
418 }
419
420 /** Convert socket to its textual representation.
421  *
422  * This function converts the transport protocol, the IP address and the port
423  * number in a comma delimited string of form proto:ip:port. The resulting
424  * string is NOT zero terminated
425  *
426  * @param s is a pointer to the destination memory buffer
427  * @param len is a pointer to an integer variable. Initially the variable
428  *        should contain the size of the buffer in s. The value of the variable
429  *        will be changed to the length of the resulting string on success and
430  *        to the desired size of the destination buffer if it is too small
431  * @param si is a pointer to the socket_info structure to be printed
432  * @return -1 on error and 0 on success
433  */
434 int socket2str(char* s, int* len, struct socket_info* si)
435 {
436         return socketinfo2str(s, len, si, 0);
437 }
438
439 int socketinfo2str(char* s, int* len, struct socket_info* si, int mode)
440 {
441         str proto;
442         int l;
443         
444         proto.s = get_valid_proto_name(si->proto);
445         proto.len = strlen(proto.s);
446         
447         if(mode==1)
448                 l = proto.len + si->useinfo.name.len + si->useinfo.port_no_str.len + 2;
449         else
450                 l = proto.len + si->address_str.len + si->port_no_str.len + 2;
451
452         if(si->address.af==AF_INET6)
453                 l += 2;
454         
455         if (*len < l) {
456                 LM_ERR("Destionation buffer too short\n");
457                 *len = l;
458                 return -1;
459         }
460         
461         memcpy(s, proto.s, proto.len);
462         s += proto.len;
463         *s = ':'; s++;
464         if(mode==1){
465                 memcpy(s, si->useinfo.name.s, si->useinfo.name.len);
466                 s += si->useinfo.name.len;
467                 *s = ':'; s++;
468                 memcpy(s, si->useinfo.port_no_str.s, si->useinfo.port_no_str.len);
469                 s += si->useinfo.port_no_str.len;
470         } else {
471                 if(si->address.af==AF_INET6) {
472                         *s = '['; s++;
473                 }
474                 memcpy(s, si->address_str.s, si->address_str.len);
475                 s += si->address_str.len;
476                 if(si->address.af==AF_INET6) {
477                         *s = ']'; s++;
478                 }
479                 *s = ':'; s++;
480                 memcpy(s, si->port_no_str.s, si->port_no_str.len);
481                 s += si->port_no_str.len;
482         }
483
484         *len = l;
485         return 0;
486 }
487
488
489
490 /* Fill si->sock_str with string representing the socket_info structure,
491  * format of the string is 'proto:address:port'. Returns 0 on success and
492  * negative number on failure.
493  */
494 static int fix_sock_str(struct socket_info* si)
495 {
496         int len = MAX_SOCKET_STR;
497
498         if (si->sock_str.s) pkg_free(si->sock_str.s);
499         
500         si->sock_str.s = pkg_malloc(len + 1);
501         if (si->sock_str.s == NULL) {
502                 PKG_MEM_ERROR;
503                 return -1;
504         }
505         if (socketinfo2str(si->sock_str.s, &len, si, 0) < 0) {
506                 BUG("fix_sock_str: Error in socket to str\n");
507                 return -1;
508         }
509         si->sock_str.s[len] = '\0';
510         si->sock_str.len = len;
511         if(si->useinfo.name.s!=NULL)
512         {
513                 len = MAX_SOCKET_ADVERTISE_STR;
514
515                 if (si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
516
517                 si->useinfo.sock_str.s = pkg_malloc(len + 1);
518                 if (si->useinfo.sock_str.s == NULL) {
519                         PKG_MEM_ERROR;
520                         return -1;
521                 }
522                 if (socketinfo2str(si->useinfo.sock_str.s, &len, si, 1) < 0) {
523                         BUG("fix_sock_str: Error in socket to str\n");
524                         return -1;
525                 }
526                 si->useinfo.sock_str.s[len] = '\0';
527                 si->useinfo.sock_str.len = len;
528         }
529         return 0;
530 }
531
532
533 /* returns 0 if support for the protocol is not compiled or if proto is 
534    invalid */
535 struct socket_info** get_sock_info_list(unsigned short proto)
536 {
537         
538         switch(proto){
539                 case PROTO_UDP:
540                         return &udp_listen;
541                         break;
542                 case PROTO_TCP:
543                 case PROTO_WS:
544 #ifdef USE_TCP
545                         return &tcp_listen;
546 #endif
547                         break;
548                 case PROTO_TLS:
549                 case PROTO_WSS:
550 #ifdef USE_TLS
551                         return &tls_listen;
552 #endif
553                         break;
554                 case PROTO_SCTP:
555 #ifdef USE_SCTP
556                         return &sctp_listen;
557 #endif
558                         break;
559                 default:
560                         LM_CRIT("invalid proto %d\n", proto);
561         }
562         return 0;
563 }
564
565
566 /* helper function for grep_sock_info
567  * params:
568  *  host - hostname to compare with
569  *  name - official name
570  *  addr_str - name's resolved ip address converted to string
571  *  ip_addr - name's ip address 
572  *  flags - set to SI_IS_IP if name contains an IP
573  *
574  * returns 0 if host matches, -1 if not */
575 inline static int si_hname_cmp(str* host, str* name, str* addr_str, 
576                                                                 struct ip_addr* ip_addr, int flags)
577 {
578         struct ip_addr* ip6;
579         
580         if ( (host->len==name->len) && 
581                 (strncasecmp(host->s, name->s, name->len)==0) /*slower*/)
582                 /* comp. must be case insensitive, host names
583                  * can be written in mixed case, it will also match
584                  * ipv6 addresses if we are lucky*/
585                 goto found;
586         /* check if host == ip address */
587         /* ipv6 case is uglier, host can be [3ffe::1] */
588         ip6=str2ip6(host);
589         if (ip6){
590                 if (ip_addr_cmp(ip6, ip_addr))
591                         goto found; /* match */
592                 else
593                         return -1; /* no match, but this is an ipv6 address
594                                                  so no point in trying ipv4 */
595         }
596         /* ipv4 */
597         if ( (!(flags&SI_IS_IP)) && (host->len==addr_str->len) && 
598                         (memcmp(host->s, addr_str->s, addr_str->len)==0) )
599                 goto found;
600         return -1;
601 found:
602         return 0;
603 }
604
605
606 /* checks if the proto: host:port is one of the address we listen on
607  * and returns the corresponding socket_info structure.
608  * if port==0, the  port number is ignored
609  * if proto==0 (PROTO_NONE) the protocol is ignored
610  * returns  0 if not found
611  * WARNING: uses str2ip6 so it will overwrite any previous
612  *  unsaved result of this function (static buffer)
613  */
614 struct socket_info* grep_sock_info(str* host, unsigned short port,
615                                                                                                 unsigned short proto)
616 {
617         str hname;
618         struct socket_info* si;
619         struct socket_info** list;
620         struct addr_info* ai;
621         unsigned short c_proto;
622         
623         hname=*host;
624         if ((hname.len>2)&&((*hname.s)=='[')&&(hname.s[hname.len-1]==']')){
625                 /* ipv6 reference, skip [] */
626                 hname.s++;
627                 hname.len-=2;
628         }
629
630         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
631 retry:
632         do{
633                 /* get the proper sock_list */
634                 list=get_sock_info_list(c_proto);
635         
636                 if (list==0) /* disabled or unknown protocol */
637                         continue;
638                 for (si=*list; si; si=si->next){
639                         LM_DBG("checking if host==us: %d==%d && [%.*s] == [%.*s]\n",
640                                                 hname.len,
641                                                 si->name.len,
642                                                 hname.len, hname.s,
643                                                 si->name.len, si->name.s
644                                 );
645                         if (port) {
646                                 LM_DBG("checking if port %d (advertise %d) matches port %d\n",
647                                                 si->port_no, si->useinfo.port_no, port);
648                                 if (si->port_no!=port && si->useinfo.port_no!=port) {
649                                         continue;
650                                 }
651                         }
652                         if (si_hname_cmp(&hname, &si->name, &si->address_str, 
653                                                                 &si->address, si->flags)==0)
654                                 goto found;
655                         if(si->useinfo.name.s!=NULL)
656                         {
657                                 LM_DBG("checking advertise if host==us:"
658                                                 " %d==%d && [%.*s] == [%.*s]\n",
659                                                 hname.len,
660                                                 si->useinfo.name.len,
661                                                 hname.len, hname.s,
662                                                 si->useinfo.name.len, si->useinfo.name.s
663                                 );
664                                 if (si_hname_cmp(&hname, &si->useinfo.name,
665                                                         &si->useinfo.address_str, &si->useinfo.address,
666                                                         si->flags)==0)
667                                         goto found;
668                         }
669                         /* try among the extra addresses */
670                         for (ai=si->addr_info_lst; ai; ai=ai->next)
671                                 if (si_hname_cmp(&hname, &ai->name, &ai->address_str, 
672                                                                         &ai->address, ai->flags)==0)
673                                         goto found;
674                 }
675
676         }while( (proto==0) && (c_proto=next_proto(c_proto)) );
677
678 #ifdef USE_TLS
679         if (unlikely(c_proto == PROTO_WS)) {
680                 c_proto = PROTO_WSS;
681                 goto retry;
682         }
683 #endif
684 /* not_found: */
685         return 0;
686 found:
687         return si;
688 }
689
690 socket_info_t* ksr_get_socket_by_name(str *sockname)
691 {
692         socket_info_t *si = NULL;
693         struct socket_info** list;
694         unsigned short c_proto;
695
696         c_proto = PROTO_UDP;
697         do {
698                 /* get the proper sock_list */
699                 list=get_sock_info_list(c_proto);
700
701                 if (list==0) {
702                         /* disabled or unknown protocol */
703                         continue;
704                 }
705
706                 for (si=*list; si; si=si->next) {
707                         if(si->sockname.s == NULL) {
708                                 continue;
709                         }
710                         LM_DBG("checking if sockname %.*s matches %.*s\n",
711                                         sockname->len, sockname->s,
712                                         si->sockname.len, si->sockname.s);
713                         if (sockname->len == si->sockname.len
714                                         && strncasecmp(sockname->s, si->sockname.s,
715                                                         sockname->len)==0) {
716                                 return si;
717                         }
718                 }
719         } while((c_proto = next_proto(c_proto))!=0);
720
721         return NULL;
722 }
723
724 /* checks if the proto:port is one of the ports we listen on
725  * and returns the corresponding socket_info structure.
726  * if proto==0 (PROTO_NONE) the protocol is ignored
727  * returns  0 if not found
728  */
729 struct socket_info* grep_sock_info_by_port(unsigned short port, 
730                                                                                         unsigned short proto)
731 {
732         struct socket_info* si;
733         struct socket_info** list;
734         unsigned short c_proto;
735
736         if (!port) {
737                 goto not_found;
738         }
739         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
740         do{
741                 /* get the proper sock_list */
742                 list=get_sock_info_list(c_proto);
743         
744                 if (list==0) /* disabled or unknown protocol */
745                         continue;
746                 
747                 for (si=*list; si; si=si->next){
748                         LM_DBG("checking if port %d matches port %d\n", si->port_no, port);
749                         if (si->port_no==port) {
750                                 goto found;
751                         }
752                 }
753         }while( (proto==0) && (c_proto=next_proto(c_proto)) );
754 not_found:
755         return 0;
756 found:
757         return si;
758 }
759
760
761
762 /* checks if the proto: ip:port is one of the address we listen on
763  * and returns the corresponding socket_info structure.
764  * (same as grep_socket_info, but use ip addr instead)
765  * if port==0, the  port number is ignored
766  * if proto==0 (PROTO_NONE) the protocol is ignored
767  * returns  0 if not found
768  * WARNING: uses str2ip6 so it will overwrite any previous
769  *  unsaved result of this function (static buffer)
770  */
771 struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
772                                                                                                 unsigned short proto)
773 {
774         struct socket_info* si;
775         struct socket_info** list;
776         struct addr_info* ai;
777         unsigned short c_proto;
778         
779         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
780         do{
781                 /* get the proper sock_list */
782                 list=get_sock_info_list(c_proto);
783         
784                 if (list==0) /* disabled or unknown protocol */
785                         continue;
786                 
787                 for (si=*list; si; si=si->next){
788                         if (port) {
789                                 if (si->port_no!=port) {
790                                         continue;
791                                 }
792                         }
793                         if (ip_addr_cmp(ip, &si->address)
794                                         || ip_addr_cmp(ip, &si->useinfo.address))
795                                 goto found;
796                         for (ai=si->addr_info_lst; ai; ai=ai->next)
797                                 if (ip_addr_cmp(ip, &ai->address))
798                                         goto found;
799                 }
800         }while( (proto==0) && (c_proto=next_proto(c_proto)) );
801 /* not_found: */
802         return 0;
803 found:
804         return si;
805 }
806
807
808
809 /* append a new sock_info structure to the corresponding list
810  * return  new sock info on success, 0 on error */
811 static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
812                                                                         unsigned short port,
813                                                                         unsigned short proto,
814                                                                         char *usename, unsigned short useport,
815                                                                         char *sockname,
816                                                                         enum si_flags flags,
817                                                                         struct socket_info** list)
818 {
819         struct socket_info* si;
820         /* allocates si and si->name in new pkg memory */
821         si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
822         if (si==0){
823                 LM_ERR("new_sock_info failed\n");
824                 goto error;
825         }
826         if(socket_workers>0) {
827                 si->workers = socket_workers;
828                 socket_workers = 0;
829         }
830 #ifdef USE_MCAST
831         if (mcast!=0) {
832                 si->mcast.len=strlen(mcast);
833                 si->mcast.s=(char*)pkg_malloc(si->mcast.len+1);
834                 if (si->mcast.s==0) {
835                         PKG_MEM_ERROR;
836                         pkg_free(si->name.s);
837                         pkg_free(si);
838                         return 0;
839                 }
840                 strcpy(si->mcast.s, mcast);
841                 mcast = 0;
842         }
843 #endif /* USE_MCAST */
844         sock_listadd(list, si);
845         return si;
846 error:
847         return 0;
848 }
849
850
851
852 /* adds a new sock_info structure immediately after "after"
853  * return  new sock info on success, 0 on error */
854 static struct socket_info* new_sock2list_after(char* name,
855                                                                         struct name_lst* addr_l,
856                                                                         unsigned short port,
857                                                                         unsigned short proto,
858                                                                         char *usename,
859                                                                         unsigned short useport,
860                                                                         char *sockname,
861                                                                         enum si_flags flags,
862                                                                         struct socket_info* after)
863 {
864         struct socket_info* si;
865
866         si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
867         if (si==0){
868                 LM_ERR("new_sock_info failed\n");
869                 goto error;
870         }
871         sock_listins(si, after);
872         return si;
873 error:
874         return 0;
875 }
876
877
878
879 /* adds a sock_info structure to the corresponding proto list
880  * return  0 on success, -1 on error */
881 int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
882                                                 unsigned short port, unsigned short proto,
883                                                 char *usename, unsigned short useport, char *sockname,
884                                                 enum si_flags flags)
885 {
886         struct socket_info** list;
887         unsigned short c_proto;
888         struct name_lst* a_l;
889         unsigned short c_port;
890
891         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
892         do{
893                 list=get_sock_info_list(c_proto);
894                 if (list==0) /* disabled or unknown protocol */
895                         continue;
896
897                 if (port==0){ /* use default port */
898                         c_port=
899 #ifdef USE_TLS
900                                 ((c_proto)==PROTO_TLS)?tls_port_no:
901 #endif
902                                 port_no;
903                 }
904 #ifdef USE_TLS
905                 else if ((c_proto==PROTO_TLS) && (proto==0)){
906                         /* -l  ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1?*/
907                         c_port=port+1;
908                 }
909 #endif
910                 else{
911                         c_port=port;
912                 }
913                 if (c_proto!=PROTO_SCTP){
914                         if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
915                                                                 sockname, flags & ~SI_IS_MHOMED, list)==0){
916                                 LM_ERR("new_sock2list failed\n");
917                                 goto error;
918                         }
919                         /* add the other addresses in the list as separate sockets
920                          * since only SCTP can bind to multiple addresses */
921                         for (a_l=addr_l; a_l; a_l=a_l->next){
922                                 if (new_sock2list(a_l->name, 0, c_port,
923                                                                         c_proto, usename, useport, sockname,
924                                                                         flags & ~SI_IS_MHOMED, list)==0){
925                                         LM_ERR("new_sock2list failed\n");
926                                         goto error;
927                                 }
928                         }
929                 }else{
930                         if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
931                                                 sockname, flags, list)==0){
932                                 LM_ERR("new_sock2list failed\n");
933                                 goto error;
934                         }
935                 }
936         }while( (proto==0) && (c_proto=next_proto(c_proto)));
937         return 0;
938 error:
939         return -1;
940 }
941
942 /* adds a sock_info structure to the corresponding proto list
943  * return  0 on success, -1 on error */
944 int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
945                                                 unsigned short port, unsigned short proto,
946                                                 char *usename, unsigned short useport,
947                                                 enum si_flags flags)
948 {
949         return add_listen_advertise_iface_name(name, addr_l, port, proto,
950                                                 usename, useport, NULL, flags);
951 }
952
953 /* adds a sock_info structure to the corresponding proto list
954  * return  0 on success, -1 on error */
955 int add_listen_iface(char* name, struct name_lst* addr_l,
956                                                 unsigned short port, unsigned short proto,
957                                                 enum si_flags flags)
958 {
959         return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0, 0,
960                         flags);
961 }
962
963 /* adds a sock_info structure to the corresponding proto list
964  * return  0 on success, -1 on error */
965 int add_listen_iface_name(char* name, struct name_lst* addr_l,
966                                                 unsigned short port, unsigned short proto, char *sockname,
967                                                 enum si_flags flags)
968 {
969         return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0,
970                         sockname, flags);
971 }
972
973 #ifdef __OS_linux
974
975 #include "linux/types.h"
976 #include "linux/netlink.h"
977 #include "linux/rtnetlink.h"
978 #include "arpa/inet.h"
979
980
981 #define MAX_IF_LEN 64
982 struct idx
983 {
984         struct idx *    next;
985         int             family;
986         unsigned        ifa_flags;
987         char            addr[MAX_IF_LEN];
988
989 };
990
991 struct idxlist{
992         struct idx*     addresses;
993         int             index;
994         char            name[MAX_IF_LEN];
995         unsigned        flags;
996 };
997
998 #define MAX_IFACE_NO 32
999
1000 static struct idxlist *ifaces = NULL;
1001 static int seq = 0;
1002
1003 #define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
1004
1005 #define NLMSG_TAIL(nmsg) \
1006         ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
1007
1008 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
1009               int alen)
1010 {
1011         int len = RTA_LENGTH(alen);
1012         struct rtattr *rta;
1013
1014         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
1015                 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
1016                 return -1;
1017         }
1018         rta = NLMSG_TAIL(n);
1019         rta->rta_type = type;
1020         rta->rta_len = len;
1021         memcpy(RTA_DATA(rta), data, alen);
1022         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
1023         return 0;
1024 }
1025
1026
1027
1028 static int nl_bound_sock(void)
1029 {
1030         int sock = -1;
1031         struct sockaddr_nl la;
1032
1033         sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1034         if(sock < 0){
1035                 LM_ERR("could not create NETLINK sock to get interface list\n");
1036                 goto error;
1037         }
1038
1039         /* bind NETLINK socket to pid */
1040         bzero(&la, sizeof(la));
1041         la.nl_family = AF_NETLINK;
1042         la.nl_pad = 0;
1043         la.nl_pid = getpid();
1044         la.nl_groups = 0;
1045         if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
1046                 LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
1047                 goto error;
1048         }
1049
1050         return sock;
1051 error:
1052         if(sock >= 0) close(sock);
1053         return -1;
1054 }
1055
1056 #define fill_nl_req(req, type, family) do {\
1057         memset(&req, 0, sizeof(req));\
1058         req.nlh.nlmsg_len = sizeof(req);\
1059         req.nlh.nlmsg_type = type;\
1060         req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP;\
1061         req.nlh.nlmsg_pid = getpid();\
1062         req.nlh.nlmsg_seq = seq++;\
1063         req.g.rtgen_family = family;\
1064         } while(0);
1065
1066         
1067 static int get_flags(int family){
1068         struct {
1069                 struct nlmsghdr nlh;
1070                 struct rtgenmsg g;
1071         } req;
1072         int rtn = 0;
1073         struct nlmsghdr*  nlp;
1074         struct ifinfomsg *ifi;
1075         char buf[8192];
1076         char *p = buf;
1077         int nll = 0;
1078     int nl_sock = -1;
1079
1080         fill_nl_req(req, RTM_GETLINK, AF_INET);
1081
1082         if((nl_sock = nl_bound_sock()) < 0) return -1;
1083
1084         if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0)
1085         {
1086                 LM_ERR("error sending NETLINK request\n");
1087                 goto error;
1088         }
1089
1090         while(1) {
1091                 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1092                 nlp = (struct nlmsghdr *) p;
1093                 if(nlp->nlmsg_type == NLMSG_DONE){
1094                         LM_DBG("done\n");
1095                          break;
1096                 }
1097                 if(nlp->nlmsg_type == NLMSG_ERROR){
1098                          LM_DBG("Error on message to netlink");
1099                          break;
1100                 }
1101                 p += rtn;
1102
1103                 nll += rtn;
1104         }
1105
1106         nlp = (struct nlmsghdr *) buf;
1107         for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1108                 ifi = NLMSG_DATA(nlp);
1109
1110                 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1111                         goto error;
1112
1113                 LM_ERR("Interface with index %d has flags %d\n", ifi->ifi_index, ifi->ifi_flags);
1114                 if(ifaces == NULL){
1115                         LM_ERR("get_flags must not be called on empty interface list");
1116                         goto error;
1117                 }
1118                 if(ifi->ifi_index >= MAX_IFACE_NO){
1119                         LM_ERR("invalid network interface index returned %d", ifi->ifi_index);
1120                         goto error;
1121                 }
1122                 ifaces[ifi->ifi_index].flags = ifi->ifi_flags;
1123         }
1124
1125         if(nl_sock>=0) close(nl_sock);
1126         return 0;
1127
1128 error:
1129         if(nl_sock>=0) close(nl_sock);
1130         return -1;
1131 }
1132
1133 static int build_iface_list(void)
1134 {
1135         struct {
1136                 struct nlmsghdr nlh;
1137                 struct rtgenmsg g;
1138         } req;
1139
1140         int rtn = 0;
1141         struct nlmsghdr*  nlp;
1142         struct ifaddrmsg *ifi;
1143         int rtl;
1144         char buf[8192];
1145         char *p = buf;
1146         int nll = 0;
1147         struct rtattr * rtap;
1148         int index, i;
1149         struct idx* entry;
1150         struct idx* tmp;
1151         int nl_sock = -1;
1152         int families[] = {AF_INET, AF_INET6};
1153         char name[MAX_IF_LEN];
1154         int is_link_local = 0;
1155
1156         if(ifaces == NULL){
1157                 if((ifaces = (struct idxlist*)pkg_malloc(MAX_IFACE_NO
1158                                                 *sizeof(struct idxlist))) == NULL){
1159                         PKG_MEM_ERROR;
1160                         return -1;
1161                 }
1162                 memset(ifaces, 0, sizeof(struct idxlist)*MAX_IFACE_NO);
1163         }
1164
1165         /* bind netlink socket */
1166         if((nl_sock = nl_bound_sock()) < 0) return -1;
1167
1168         for (i = 0 ; i < sizeof(families)/sizeof(int); i++) {
1169                 fill_nl_req(req, RTM_GETADDR, families[i]);
1170
1171                 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0){
1172                         LM_ERR("error sending NETLINK request\n");
1173                         goto error;
1174                 };
1175
1176                 memset(buf, 0, sizeof(buf));
1177                 nll = 0;
1178                 p = buf;
1179                 while(1) {
1180                         rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1181                         LM_DBG("received %d byles \n", rtn);
1182                         nlp = (struct nlmsghdr *) p;
1183                         if(nlp->nlmsg_type == NLMSG_DONE){
1184                                 LM_DBG("done receiving netlink info \n");
1185                                  break;
1186                         }
1187                         if(nlp->nlmsg_type == NLMSG_ERROR){
1188                                  LM_ERR("Error on message to netlink");
1189                                  break;
1190                         }
1191                         p += rtn;
1192
1193                         nll += rtn;
1194                 }
1195
1196                 nlp = (struct nlmsghdr *) buf;
1197                 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1198                         ifi = NLMSG_DATA(nlp);
1199
1200                         if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1201                                 continue;
1202                         // init all the strings
1203                         // inner loop: loop thru all the attributes of
1204                         // one route entry
1205                         rtap = (struct rtattr *) IFA_RTA(ifi);
1206
1207                         rtl = IFA_PAYLOAD(nlp);
1208
1209                         index = ifi->ifa_index;
1210                         if(index >= MAX_IFACE_NO){
1211                                 LM_ERR("Invalid interface index returned: %d\n", index);
1212                                 goto error;
1213                         }
1214
1215                         entry = (struct idx*)pkg_malloc(sizeof(struct idx));
1216                         if(entry == 0)
1217                         {
1218                                 PKG_MEM_ERROR;
1219                                 goto error;
1220                         }
1221
1222                         entry->next = 0;
1223                         entry->family = families[i];
1224                         entry->ifa_flags = ifi->ifa_flags;
1225             is_link_local = 0;
1226
1227                         name[0] = '\0';
1228                         for(;RTA_OK(rtap, rtl);rtap=RTA_NEXT(rtap,rtl)){
1229                                 switch(rtap->rta_type){
1230                                         case IFA_ADDRESS:
1231                                                 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1232                                                         LM_DBG("Link Local Address, ignoring ...\n");
1233                                                         is_link_local = 1;
1234                                                         break;
1235                                                 }
1236                                                 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1237                                                 LM_DBG("iface <IFA_ADDRESS> addr is  %s\n", entry->addr);
1238                                                 break;
1239                                         case IFA_LOCAL:
1240                                                 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1241                                                         LM_DBG("Link Local Address, ignoring ...\n");
1242                                                         is_link_local = 1;
1243                                                 }
1244                                                 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1245                                                 LM_DBG("iface <IFA_LOCAL> addr is %s\n", entry->addr);
1246                                                 break;
1247                                         case IFA_LABEL:
1248                                                 LM_DBG("iface name is %s\n", (char*)RTA_DATA(rtap));
1249                                                 strncpy(name, (char*)RTA_DATA(rtap), MAX_IF_LEN-1);
1250                                                 break;
1251                                         case IFA_BROADCAST:
1252                                         case IFA_ANYCAST:
1253                                         case IFA_UNSPEC:
1254                                         case IFA_CACHEINFO:
1255                                         default:
1256                                                 break;
1257                                 }
1258                         }
1259                         if(is_link_local) {
1260                                 if(sr_bind_ipv6_link_local==0) {
1261                                         /* skip - link local addresses are not bindable without scope */
1262                                         pkg_free(entry);
1263                                         continue;
1264                                 }
1265                         }
1266
1267                         if(strlen(ifaces[index].name)==0 && strlen(name)>0) {
1268                                 strncpy(ifaces[index].name, name, MAX_IF_LEN-1);
1269                         }
1270
1271                         ifaces[index].index = index;
1272
1273                         if(ifaces[index].addresses == 0 )
1274                                 ifaces[index].addresses = entry;
1275                         else {
1276                                 for(tmp = ifaces[index].addresses; tmp->next ; tmp = tmp->next)/*empty*/;
1277                                 tmp->next = entry;
1278                         }
1279                 }
1280         }
1281         if(nl_sock>0) close(nl_sock);
1282         /* the socket should be closed so we can bind again */
1283         for(i = 0; i < sizeof(families)/sizeof(int); i++){
1284                 /* get device flags */
1285                 get_flags(families[i]); /* AF_INET or AF_INET6 */
1286         }
1287
1288         return 0;
1289 error:
1290         if(nl_sock>=0) close(nl_sock);
1291         return -1;
1292
1293 }
1294 /* add all family type addresses of interface if_name to the socket_info array
1295  * if family ==0, uses all families
1296  * if if_name==0, adds all addresses on all interfaces
1297  * uses RTNETLINK sockets to get addresses on the present interface on LINUX
1298  * return: -1 on error, 0 on success
1299  */
1300 int add_interfaces_via_netlink(char* if_name, int family, unsigned short port,
1301                                         unsigned short proto,
1302                                         struct addr_info** ai_l)
1303 {
1304         int i;
1305         struct idx* tmp;
1306         enum si_flags flags;
1307
1308         if(ifaces == NULL && (build_iface_list()!=0)){
1309                 LM_ERR("Could not get network interface list\n");
1310                 return -1;
1311         }
1312
1313         flags=SI_NONE;
1314         for(i=0; i< MAX_IFACE_NO; ++i){
1315                 if(ifaces[i].addresses == NULL) continue; /* not present/configured */
1316                 if ((if_name==0)||
1317                         (strncmp(if_name, ifaces[i].name, strlen(ifaces[i].name))==0)){
1318
1319                         /* check if iface is up */
1320                         //if(! (ifaces[i].flags & IFF_UP) ) continue;
1321
1322                         for(tmp = ifaces[i].addresses; tmp; tmp = tmp->next){
1323                                 LM_DBG("in add_iface_via_netlink Name %s Address %s\n",
1324                                                         ifaces[i].name, tmp->addr);
1325                                         /* match family */
1326                                         if (family && family == tmp->family){
1327                                         /* check if loopback */
1328                                         if (ifaces[i].flags & IFF_LOOPBACK){
1329                                                 LM_DBG("INTERFACE %s is loopback", ifaces[i].name);
1330                                                 flags|=SI_IS_LO;
1331                                         }
1332                                         /* save the info */
1333                                         if (new_addr_info2list(tmp->addr, flags, ai_l)!=0){
1334                                                 LM_ERR("new_addr_info2list failed\n");
1335                                                 goto error;
1336                                         }
1337                                 }
1338                         }
1339                 }
1340         }
1341         return 0;
1342 error:
1343         return -1;
1344 }
1345 #endif /* __OS_linux */
1346
1347 /* add all family type addresses of interface if_name to the socket_info array
1348  * if family ==0, uses all families
1349  * if if_name==0, adds all addresses on all interfaces
1350  * return: -1 on error, 0 on success
1351  */
1352 int add_interfaces(char* if_name, int family, unsigned short port,
1353                                         unsigned short proto,
1354                                         struct addr_info** ai_l)
1355 {
1356         char* tmp;
1357         struct ip_addr addr;
1358         int ret = -1;
1359         enum si_flags flags;
1360         struct ifaddrs *ifap, *ifa;
1361
1362         if (getifaddrs (&ifap) != 0) {
1363                 LM_ERR("getifaddrs failed\n");
1364                 return -1;
1365         }
1366
1367         for (ifa = ifap; ifa; ifa = ifa->ifa_next)
1368         {
1369                 /* skip if no IP addr associated with the interface */
1370                 if (ifa->ifa_addr==0)
1371                         continue;
1372 #ifdef AF_PACKET
1373                 /* skip AF_PACKET addr family since it is of no use later on */
1374                 if (ifa->ifa_addr->sa_family == AF_PACKET)
1375                         continue;
1376 #endif
1377                 if (if_name && strcmp(if_name, ifa->ifa_name))
1378                         continue;
1379                 if (family && family != ifa->ifa_addr->sa_family)
1380                         continue;
1381                 sockaddr2ip_addr(&addr, (struct sockaddr*)ifa->ifa_addr);
1382                 tmp=ip_addr2a(&addr);
1383                 if (ifa->ifa_flags & IFF_LOOPBACK)
1384                         flags = SI_IS_LO;
1385                 else
1386                         flags = SI_NONE;
1387                 if (new_addr_info2list(tmp, flags, ai_l)!=0)
1388                 {
1389                         LM_ERR("new_addr_info2list failed\n");
1390                         ret = -1;
1391                         break;
1392                 }
1393                 LM_DBG("If: %8s Fam: %8x Flg: %16lx Adr: %s\n",
1394                                 ifa->ifa_name, ifa->ifa_addr->sa_family,
1395                                 (unsigned long)ifa->ifa_flags, tmp);
1396
1397                 ret = 0;
1398         }
1399         freeifaddrs(ifap);
1400         return  ret;
1401 }
1402
1403
1404
1405 /* internal helper function: resolve host names and add aliases
1406  * name is a value result parameter: it should contain the hostname that
1407  * will be used to fill all the other members, including name itself
1408  * in some situation (name->s should be a 0 terminated pkg_malloc'ed string)
1409  * return 0 on success and -1 on error */
1410 static int fix_hostname(str* name, struct ip_addr* address, str* address_str,
1411                                                 enum si_flags* flags, int* type_flags,
1412                                                 struct socket_info* s)
1413 {
1414         struct hostent* he;
1415         char* tmp;
1416         char** h;
1417         
1418         /* get "official hostnames", all the aliases etc. */
1419         he=resolvehost(name->s);
1420         if (he==0){
1421                 LM_ERR("could not resolve %s\n", name->s);
1422                 goto error;
1423         }
1424         /* check if we got the official name */
1425         if (strcasecmp(he->h_name, name->s)!=0){
1426                 if (sr_auto_aliases && 
1427                                 add_alias(name->s, name->len, s->port_no, s->proto)<0){
1428                         LM_ERR("add_alias failed\n");
1429                 }
1430                 /* change the official name */
1431                 pkg_free(name->s);
1432                 name->s=(char*)pkg_malloc(strlen(he->h_name)+1);
1433                 if (name->s==0){
1434                         PKG_MEM_ERROR;
1435                         goto error;
1436                 }
1437                 name->len=strlen(he->h_name);
1438                 strncpy(name->s, he->h_name, name->len+1);
1439         }
1440         /* add the aliases*/
1441         for(h=he->h_aliases; sr_auto_aliases && h && *h; h++)
1442                 if (add_alias(*h, strlen(*h), s->port_no, s->proto)<0){
1443                         LM_ERR("add_alias failed\n");
1444                 }
1445         hostent2ip_addr(address, he, 0); /*convert to ip_addr format*/
1446         if (type_flags){
1447                 *type_flags|=(address->af==AF_INET)?SOCKET_T_IPV4:SOCKET_T_IPV6;
1448         }
1449         if ((tmp=ip_addr2a(address))==0) goto error;
1450         address_str->s=pkg_malloc(strlen(tmp)+1);
1451         if (address_str->s==0){
1452                 PKG_MEM_ERROR;
1453                 goto error;
1454         }
1455         strncpy(address_str->s, tmp, strlen(tmp)+1);
1456         /* set is_ip (1 if name is an ip address, 0 otherwise) */
1457         address_str->len=strlen(tmp);
1458         if (sr_auto_aliases && (address_str->len==name->len) &&
1459                 (strncasecmp(address_str->s, name->s, address_str->len)==0)){
1460                 *flags|=SI_IS_IP;
1461                 /* do rev. DNS on it (for aliases)*/
1462                 he=rev_resolvehost(address);
1463                 if (he==0){
1464                         LM_WARN("could not rev. resolve %s\n", name->s);
1465                 }else{
1466                         /* add the aliases*/
1467                         if (add_alias(he->h_name, strlen(he->h_name), s->port_no,
1468                                                         s->proto)<0){
1469                                 LM_ERR("add_alias failed\n");
1470                         }
1471                         for(h=he->h_aliases; h && *h; h++)
1472                                 if (add_alias(*h, strlen(*h), s->port_no, s->proto) < 0){
1473                                         LM_ERR("add_alias failed\n");
1474                                 }
1475                 }
1476         }
1477         
1478 #ifdef USE_MCAST
1479         /* Check if it is an multicast address and
1480          * set the flag if so
1481          */
1482         if (is_mcast(address)){
1483                 *flags |= SI_IS_MCAST;
1484         }
1485 #endif /* USE_MCAST */
1486         
1487         /* check if INADDR_ANY */
1488         if (ip_addr_any(address))
1489                 *flags|=SI_IS_ANY;
1490         else if (ip_addr_loopback(address)) /* check for loopback */
1491                 *flags|=SI_IS_LO;
1492         
1493         return 0;
1494 error:
1495         return -1;
1496 }
1497
1498
1499
1500 /* append new elements to a socket_info list after "list"
1501  * each element is created  from addr_info_lst + port, protocol and flags
1502  * return 0 on succes, -1 on error
1503  */
1504 static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
1505                                                                 char proto, char *usename,
1506                                                                 unsigned short useport, char *sockname,
1507                                                                 enum si_flags flags,
1508                                                                 struct socket_info** list)
1509 {
1510         struct addr_info* ail;
1511
1512         for (ail=ai_lst; ail; ail=ail->next){
1513                 if(new_sock2list(ail->name.s, 0, port, proto, usename, useport, sockname,
1514                                         ail->flags | flags, list)==0)
1515                         return -1;
1516         }
1517         return 0;
1518 }
1519
1520
1521
1522 /* insert new elements to a socket_info list after "el",
1523  * each element is created from addr_info_lst + port, * protocol and flags
1524  * return 0 on succes, -1 on error
1525  */
1526 static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
1527                                                                                 unsigned short port,
1528                                                                                 char proto,
1529                                                                                 char *usename,
1530                                                                                 unsigned short useport,
1531                                                                                 char *sockname,
1532                                                                                 enum si_flags flags,
1533                                                                                 struct socket_info* el)
1534 {
1535         struct addr_info* ail;
1536         struct socket_info* new_si;
1537
1538         for (ail=ai_lst; ail; ail=ail->next){
1539                 if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
1540                                                                 usename, useport, sockname,
1541                                                                 ail->flags | flags, el))==0)
1542                         return -1;
1543                 el=new_si;
1544         }
1545         return 0;
1546 }
1547
1548
1549
1550 /* fixes a socket list => resolve addresses,
1551  * interface names, fills missing members, remove duplicates
1552  * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
1553 static int fix_socket_list(struct socket_info **list, int* type_flags)
1554 {
1555         struct socket_info* si;
1556         struct socket_info* new_si;
1557         struct socket_info* l;
1558         struct socket_info* next;
1559         struct socket_info* next_si;
1560         struct socket_info* del_si;
1561         struct socket_info* keep_si;
1562         char* tmp;
1563         int len;
1564         struct addr_info* ai_lst;
1565         struct addr_info* ail;
1566         struct addr_info* tmp_ail;
1567         struct addr_info* tmp_ail_next;
1568         struct addr_info* ail_next;
1569
1570         if (type_flags)
1571                 *type_flags=0;
1572         /* try to change all the interface names into addresses
1573          *  --ugly hack */
1574         for (si=*list;si;){
1575                 next=si->next;
1576                 ai_lst=0;
1577                 if (add_interfaces(si->name.s, auto_bind_ipv6 ? 0 : AF_INET,
1578                                                         si->port_no, si->proto, &ai_lst)!=-1){
1579                         if (si->flags & SI_IS_MHOMED){
1580                                 if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
1581                                                                                         si->proto, si->useinfo.name.s,
1582                                                                                         si->useinfo.port_no, si->sockname.s,
1583                                                                                         ai_lst->flags|si->flags, si))==0)
1584                                         break;
1585                                 ail=ai_lst;
1586                                 ai_lst=ai_lst->next;
1587                                 free_addr_info(ail); /* free the first elem. */
1588                                 if (ai_lst){
1589                                         ai_lst->prev=0;
1590                                         /* find the end */
1591                                         for (ail=ai_lst; ail->next; ail=ail->next);
1592                                         /* add the mh list after the last position in ai_lst */
1593                                         addr_info_list_ins_lst(si->addr_info_lst, ail);
1594                                         new_si->addr_info_lst=ai_lst;
1595                                         si->addr_info_lst=0; /* detached and moved to new_si */
1596                                         ail=ail->next; /* ail== old si->addr_info_lst */
1597                                 }else{
1598                                         ail=si->addr_info_lst;
1599                                         new_si->addr_info_lst=ail;
1600                                         si->addr_info_lst=0; /* detached and moved to new_si */
1601                                 }
1602                         }else{
1603                                 /* add all addr. as separate  interfaces */
1604                                 if (addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto,
1605                                                         si->useinfo.name.s, si->useinfo.port_no,
1606                                                         si->sockname.s, si->flags, si)!=0)
1607                                         goto error;
1608                                 /* ai_lst not needed anymore */
1609                                 free_addr_info_lst(&ai_lst);
1610                                 ail=0;
1611                                 new_si=0;
1612                         }
1613                         /* success => remove current entry (shift the entire array)*/
1614                         sock_listrm(list, si);
1615                         free_sock_info(si);
1616                 }else{
1617                         new_si=si;
1618                         ail=si->addr_info_lst;
1619                 }
1620
1621                 if (ail){
1622                         if (new_si && (new_si->flags & SI_IS_MHOMED)){
1623                                 ai_lst=0;
1624                                 for (; ail;){
1625                                         ail_next=ail->next;
1626                                         if (add_interfaces(ail->name.s, AF_INET, new_si->port_no,
1627                                                                                         new_si->proto, &ai_lst)!=-1){
1628                                                 /* add the resolved list after the current position */
1629                                                 addr_info_list_ins_lst(ai_lst, ail);
1630                                                 /* success, remove the current entity */
1631                                                 addr_info_listrm(&new_si->addr_info_lst, ail);
1632                                                 free_addr_info(ail);
1633                                                 ai_lst=0;
1634                                         }
1635                                         ail=ail_next;
1636                                 }
1637                         }
1638                 }
1639                 si=next;
1640         }
1641         /* get ips & fill the port numbers*/
1642 #ifdef EXTRA_DEBUG
1643         LM_DBG("Listening on\n");
1644 #endif
1645         for (si=*list;si;si=si->next){
1646                 /* fix port number, port_no should be !=0 here */
1647                 if (si->port_no==0){
1648 #ifdef USE_TLS
1649                         si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
1650 #else
1651                         si->port_no= port_no;
1652 #endif
1653                 }
1654                 tmp=int2str(si->port_no, &len);
1655                 if (len>=MAX_PORT_LEN){
1656                         LM_ERR("bad port number: %d\n", si->port_no);
1657                         goto error;
1658                 }
1659                 si->port_no_str.s=(char*)pkg_malloc(len+1);
1660                 if (si->port_no_str.s==0){
1661                         PKG_MEM_ERROR;
1662                         goto error;
1663                 }
1664                 strncpy(si->port_no_str.s, tmp, len+1);
1665                 si->port_no_str.len=len;
1666
1667                 if (fix_hostname(&si->name, &si->address, &si->address_str,
1668                                                 &si->flags, type_flags, si) !=0 )
1669                         goto error;
1670                 /* fix hostnames in mh addresses */
1671                 for (ail=si->addr_info_lst; ail; ail=ail->next){
1672                         if (fix_hostname(&ail->name, &ail->address, &ail->address_str,
1673                                                 &ail->flags, type_flags, si) !=0 )
1674                                 goto error;
1675                 }
1676
1677                 if (fix_sock_str(si) < 0) goto error;
1678
1679 #ifdef EXTRA_DEBUG
1680                 printf("              %.*s [%s]:%s%s\n", si->name.len,
1681                                 si->name.s, si->address_str.s, si->port_no_str.s,
1682                                 si->flags & SI_IS_MCAST ? " mcast" : "");
1683 #endif
1684         }
1685         /* removing duplicate addresses*/
1686         for (si=*list;si; ){
1687                 next_si=si->next;
1688                 for (l=si->next;l;){
1689                         next=l->next;
1690                         if ((si->port_no==l->port_no) &&
1691                                 (si->address.af==l->address.af) &&
1692                                 (memcmp(si->address.u.addr, l->address.u.addr,
1693                                                 si->address.len) == 0)
1694                                 ){
1695                                 /* remove the socket with no  extra addresses.,
1696                                  * if both of them have extra addresses, remove one of them
1697                                  * and merge the extra addresses into the other */
1698                                 if (l->addr_info_lst==0){
1699                                         del_si=l;
1700                                         keep_si=si;
1701                                 }else if (si->addr_info_lst==0){
1702                                         del_si=si;
1703                                         keep_si=l;
1704                                 }else{
1705                                         /* move l->addr_info_lst to si->addr_info_lst */
1706                                         /* find last elem */
1707                                         for (ail=si->addr_info_lst; ail->next; ail=ail->next);
1708                                         /* add the l list after the last position in si lst */
1709                                         addr_info_list_ins_lst(l->addr_info_lst, ail);
1710                                         l->addr_info_lst=0; /* detached */
1711                                         del_si=l; /* l will be removed */
1712                                         keep_si=l;
1713                                 }
1714 #ifdef EXTRA_DEBUG
1715                                 printf("removing duplicate %s [%s] ==  %s [%s]\n",
1716                                                 keep_si->name.s, keep_si->address_str.s,
1717                                                  del_si->name.s, del_si->address_str.s);
1718 #endif
1719                                 /* add the name to the alias list*/
1720                                 if ((!(del_si->flags& SI_IS_IP)) && (
1721                                                 (del_si->name.len!=keep_si->name.len)||
1722                                                 (strncmp(del_si->name.s, keep_si->name.s,
1723                                                                  del_si->name.len)!=0))
1724                                         )
1725                                         add_alias(del_si->name.s, del_si->name.len,
1726                                                                 l->port_no, l->proto);
1727                                 /* make sure next_si doesn't point to del_si */
1728                                 if (del_si==next_si)
1729                                         next_si=next_si->next;
1730                                 /* remove del_si*/
1731                                 sock_listrm(list, del_si);
1732                                 free_sock_info(del_si);
1733                         }
1734                         l=next;
1735                 }
1736                 si=next_si;
1737         }
1738         /* check for duplicates in extra_addresses */
1739         for (si=*list;si; si=si->next){
1740                 /* check  for & remove internal duplicates: */
1741                 for (ail=si->addr_info_lst; ail;){
1742                         ail_next=ail->next;
1743                         /* 1. check if the extra addresses contain a duplicate for the
1744                          * main  one */
1745                         if ((ail->address.af==si->address.af) &&
1746                                 (memcmp(ail->address.u.addr, si->address.u.addr,
1747                                                         ail->address.len) == 0)){
1748                                 /* add the name to the alias list*/
1749                                 if ((!(ail->flags& SI_IS_IP)) && (
1750                                         (ail->name.len!=si->name.len)||
1751                                         (strncmp(ail->name.s, si->name.s, ail->name.len)!=0)))
1752                                         add_alias(ail->name.s, ail->name.len, si->port_no,
1753                                                                 si->proto);
1754                                         /* remove ail*/
1755                                 addr_info_listrm(&si->addr_info_lst, ail);
1756                                 free_addr_info(ail);
1757                                 ail=ail_next;
1758                                 continue;
1759                         }
1760                         /* 2. check if the extra addresses contain a duplicates for
1761                          *  other addresses in the same list */
1762                         for (tmp_ail=ail->next; tmp_ail;){
1763                                 tmp_ail_next=tmp_ail->next;
1764                                 if ((ail->address.af==tmp_ail->address.af) &&
1765                                         (memcmp(ail->address.u.addr, tmp_ail->address.u.addr,
1766                                                         ail->address.len) == 0)){
1767                                         /* add the name to the alias list*/
1768                                         if ((!(tmp_ail->flags& SI_IS_IP)) && (
1769                                                 (ail->name.len!=tmp_ail->name.len)||
1770                                                 (strncmp(ail->name.s, tmp_ail->name.s,
1771                                                                                 tmp_ail->name.len)!=0))
1772                                                 )
1773                                                 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1774                                                                         si->port_no, si->proto);
1775                                                 /* remove tmp_ail*/
1776                                         addr_info_listrm(&si->addr_info_lst, tmp_ail);
1777                                         if(ail_next==tmp_ail) {
1778                                                 ail_next = tmp_ail_next;
1779                                         }
1780                                         free_addr_info(tmp_ail);
1781                                 }
1782                                 tmp_ail=tmp_ail_next;
1783                         }
1784                         ail=ail_next;
1785                 }
1786                 /* check for duplicates between extra addresses (e.g. sctp MH)
1787                  * and other main addresses, on conflict remove the corresponding
1788                  * extra addresses (another possible solution would be to join
1789                  * the 2 si entries into one). */
1790                 for (ail=si->addr_info_lst; ail;){
1791                         ail_next=ail->next;
1792                         for (l=*list;l; l=l->next){
1793                                 if (l==si) continue;
1794                                 if (si->port_no==l->port_no){
1795                                         if ((ail->address.af==l->address.af) &&
1796                                                 (memcmp(ail->address.u.addr, l->address.u.addr,
1797                                                                                 ail->address.len) == 0)){
1798                                                 /* add the name to the alias list*/
1799                                                 if ((!(ail->flags& SI_IS_IP)) && (
1800                                                         (ail->name.len!=l->name.len)||
1801                                                         (strncmp(ail->name.s, l->name.s, l->name.len)!=0))
1802                                                         )
1803                                                         add_alias(ail->name.s, ail->name.len,
1804                                                                                 l->port_no, l->proto);
1805                                                 /* remove ail*/
1806                                                 addr_info_listrm(&si->addr_info_lst, ail);
1807                                                 free_addr_info(ail);
1808                                                 break;
1809                                         }
1810                                         /* check for duplicates with other  extra addresses
1811                                          * lists */
1812                                         for (tmp_ail=l->addr_info_lst; tmp_ail; ){
1813                                                 tmp_ail_next=tmp_ail->next;
1814                                                 if ((ail->address.af==tmp_ail->address.af) &&
1815                                                         (memcmp(ail->address.u.addr,
1816                                                                         tmp_ail->address.u.addr,
1817                                                                         ail->address.len) == 0)){
1818                                                         /* add the name to the alias list*/
1819                                                         if ((!(tmp_ail->flags& SI_IS_IP)) && (
1820                                                                         (ail->name.len!=tmp_ail->name.len)||
1821                                                                         (strncmp(ail->name.s, tmp_ail->name.s,
1822                                                                                         tmp_ail->name.len)!=0))
1823                                                                 )
1824                                                                 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1825                                                                                 l->port_no, l->proto);
1826                                                         /* remove tmp_ail*/
1827                                                         addr_info_listrm(&l->addr_info_lst, tmp_ail);
1828                                                         free_addr_info(tmp_ail);
1829                                                 }
1830                                                 tmp_ail=tmp_ail_next;
1831                                         }
1832                                 }
1833                         }
1834                         ail=ail_next;
1835                 }
1836         }
1837
1838 #ifdef USE_MCAST
1839              /* Remove invalid multicast entries */
1840         si=*list;
1841         while(si){
1842                 if ((si->proto == PROTO_TCP)
1843 #ifdef USE_TLS
1844                     || (si->proto == PROTO_TLS)
1845 #endif /* USE_TLS */
1846 #ifdef USE_SCTP
1847                         || (si->proto == PROTO_SCTP)
1848 #endif
1849                         ){
1850                         if (si->flags & SI_IS_MCAST){
1851                                 LM_WARN("removing entry %s:%s [%s]:%s\n",
1852                                         get_valid_proto_name(si->proto), si->name.s,
1853                                         si->address_str.s, si->port_no_str.s);
1854                                 l = si;
1855                                 si=si->next;
1856                                 sock_listrm(list, l);
1857                                 free_sock_info(l);
1858                         }else{
1859                                 ail=si->addr_info_lst;
1860                                 while(ail){
1861                                         if (ail->flags & SI_IS_MCAST){
1862                                                 LM_WARN("removing mh entry %s:%s"
1863                                                                 " [%s]:%s\n",
1864                                                                 get_valid_proto_name(si->proto), ail->name.s,
1865                                                                 ail->address_str.s, si->port_no_str.s);
1866                                                 tmp_ail=ail;
1867                                                 ail=ail->next;
1868                                                 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1869                                                 free_addr_info(tmp_ail);
1870                                         }else{
1871                                                 ail=ail->next;
1872                                         }
1873                                 }
1874                                 si=si->next;
1875                         }
1876                 } else {
1877                         si=si->next;
1878                 }
1879         }
1880 #endif /* USE_MCAST */
1881
1882         return 0;
1883 error:
1884         return -1;
1885 }
1886
1887 int socket_types = 0;
1888
1889 /* fix all 3 socket lists, fills socket_types if non-null
1890  * return 0 on success, -1 on error */
1891 int fix_all_socket_lists()
1892 {
1893         struct utsname myname;
1894         int flags;
1895         struct addr_info* ai_lst;
1896
1897         ai_lst=0;
1898
1899         if ((udp_listen==0)
1900 #ifdef USE_TCP
1901                         && (tcp_listen==0)
1902 #ifdef USE_TLS
1903                         && (tls_listen==0)
1904 #endif
1905 #endif
1906 #ifdef USE_SCTP
1907                         && (sctp_listen==0)
1908 #endif
1909                 ){
1910                 /* get all listening ipv4/ipv6 interfaces */
1911                 if ( ( (add_interfaces(0, AF_INET, 0,  PROTO_UDP, &ai_lst)==0)
1912 #ifdef __OS_linux
1913                 &&  (!auto_bind_ipv6 || add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0)
1914 #else
1915                 && ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0,  PROTO_UDP, &ai_lst) ==0 ) /* add_interface does not work for IPv6 on Linux */
1916 #endif /* __OS_linux */
1917                          ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, &udp_listen)==0)){
1918                         free_addr_info_lst(&ai_lst);
1919                         ai_lst=0;
1920                         /* if ok, try to add the others too */
1921 #ifdef USE_TCP
1922                         if (!tcp_disable){
1923                                 if ( ((add_interfaces(0, AF_INET, 0,  PROTO_TCP, &ai_lst)!=0)
1924 #ifdef __OS_linux
1925                                 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TCP, &ai_lst) != 0)
1926 #else
1927                                 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TCP, &ai_lst) !=0 )
1928 #endif /* __OS_linux */
1929                                 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0, 0,
1930                                                                                                                 &tcp_listen)!=0))
1931                                         goto error;
1932                                 free_addr_info_lst(&ai_lst);
1933                                 ai_lst=0;
1934 #ifdef USE_TLS
1935                                 if (!tls_disable){
1936                                         if (((add_interfaces(0, AF_INET, 0, PROTO_TLS,
1937                                                                                 &ai_lst)!=0)
1938 #ifdef __OS_linux
1939                                 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TLS, &ai_lst) != 0)
1940 #else
1941                                 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TLS, &ai_lst)!=0)
1942 #endif /* __OS_linux */
1943                                         ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, 0, 0,
1944                                                                                                                 &tls_listen)!=0))
1945                                                 goto error;
1946                                 }
1947                                 free_addr_info_lst(&ai_lst);
1948                                 ai_lst=0;
1949 #endif
1950                         }
1951 #endif
1952 #ifdef USE_SCTP
1953                         if (!sctp_disable){
1954                                 if (((add_interfaces(0, AF_INET, 0,  PROTO_SCTP, &ai_lst)!=0)
1955 #ifdef __OS_linux
1956                                 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1957 #else
1958                                 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_SCTP, &ai_lst) != 0)
1959 #endif /* __OS_linux */
1960                                         ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0, 0,
1961                                                                                         &sctp_listen)!=0))
1962                                         goto error;
1963                                 free_addr_info_lst(&ai_lst);
1964                                 ai_lst=0;
1965                         }
1966 #endif /* USE_SCTP */
1967                 }else{
1968                         /* if error fall back to get hostname */
1969                         /* get our address, only the first one */
1970                         if (uname (&myname) <0){
1971                                 LM_ERR("cannot determine hostname, try -l address\n");
1972                                 goto error;
1973                         }
1974                         if (add_listen_iface(myname.nodename, 0, 0, 0, 0)!=0){
1975                                 LM_ERR("add_listen_iface failed \n");
1976                                 goto error;
1977                         }
1978                 }
1979         }
1980         flags=0;
1981         if (fix_socket_list(&udp_listen, &flags)!=0){
1982                 LM_ERR("fix_socket_list udp failed\n");
1983                 goto error;
1984         }
1985         if (flags){
1986                 socket_types|=flags|SOCKET_T_UDP;
1987         }
1988 #ifdef USE_TCP
1989         flags=0;
1990         if (!tcp_disable && (fix_socket_list(&tcp_listen, &flags)!=0)){
1991                 LM_ERR("fix_socket_list tcp failed\n");
1992                 goto error;
1993         }
1994         if (flags){
1995                 socket_types|=flags|SOCKET_T_TCP;
1996         }
1997 #ifdef USE_TLS
1998         flags=0;
1999         if (!tls_disable && (fix_socket_list(&tls_listen, &flags)!=0)){
2000                 LM_ERR("fix_socket_list tls failed\n");
2001                 goto error;
2002         }
2003         if (flags){
2004                 socket_types|=flags|SOCKET_T_TLS;
2005         }
2006 #endif
2007 #endif
2008 #ifdef USE_SCTP
2009         flags=0;
2010         if (!sctp_disable && (fix_socket_list(&sctp_listen, &flags)!=0)){
2011                 LM_ERR("fix_socket_list sctp failed\n");
2012                 goto error;
2013         }
2014         if (flags){
2015                 socket_types|=flags|SOCKET_T_SCTP;
2016         }
2017 #endif /* USE_SCTP */
2018         if ((udp_listen==0)
2019 #ifdef USE_TCP
2020                         && (tcp_listen==0)
2021 #ifdef USE_TLS
2022                         && (tls_listen==0)
2023 #endif
2024 #endif
2025 #ifdef USE_SCTP
2026                         && (sctp_listen==0)
2027 #endif
2028                 ){
2029                 LM_ERR("no listening sockets\n");
2030                 goto error;
2031         }
2032         return 0;
2033 error:
2034         if (ai_lst) free_addr_info_lst(&ai_lst);
2035         return -1;
2036 }
2037
2038
2039
2040 void print_all_socket_lists()
2041 {
2042         struct socket_info *si;
2043         struct socket_info** list;
2044         struct addr_info* ai;
2045         unsigned short proto;
2046
2047         proto=PROTO_UDP;
2048         do{
2049                 list=get_sock_info_list(proto);
2050                 for(si=list?*list:0; si; si=si->next){
2051                         if (si->addr_info_lst){
2052                                 printf("             %s: (%s",
2053                                                 get_valid_proto_name(proto),
2054                                                 si->address_str.s);
2055                                 for (ai=si->addr_info_lst; ai; ai=ai->next) {
2056                                         printf(", %s", ai->address_str.s);
2057                                 }
2058                                 printf("):%s%s%s\n",
2059                                                 si->port_no_str.s,
2060                                                 si->flags & SI_IS_MCAST ? " mcast" : "",
2061                                                 si->flags & SI_IS_MHOMED? " mhomed" : "");
2062                         }else{
2063                                 printf("             %s: %s",
2064                                                 get_valid_proto_name(proto),
2065                                                 si->name.s);
2066                                 if (!(si->flags & SI_IS_IP)) {
2067                                         printf(" [%s]", si->address_str.s);
2068                                 }
2069                                 printf( ":%s%s%s",
2070                                                 si->port_no_str.s,
2071                                                 si->flags & SI_IS_MCAST ? " mcast" : "",
2072                                                 si->flags & SI_IS_MHOMED? " mhomed" : "");
2073                                 if (si->sockname.s) {
2074                                         printf(" name %s", si->sockname.s);
2075                                 }
2076                                 if (si->useinfo.name.s) {
2077                                         printf(" advertise %s:%d", si->useinfo.name.s, si->useinfo.port_no);
2078                                 }
2079                                 printf("\n");
2080                         }
2081                 }
2082         }while((proto=next_proto(proto)));
2083 }
2084
2085
2086 void print_aliases()
2087 {
2088         struct host_alias* a;
2089
2090         for(a=aliases; a; a=a->next) {
2091                 if (a->port) {
2092                         printf("             %s: %.*s:%d\n", get_valid_proto_name(a->proto),
2093                                         a->alias.len, a->alias.s, a->port);
2094                 } else {
2095                         printf("             %s: %.*s:*\n", get_valid_proto_name(a->proto),
2096                                         a->alias.len, a->alias.s);
2097                 }
2098         }
2099 }
2100
2101
2102
2103 void init_proto_order()
2104 {
2105         int r;
2106
2107         /* fix proto list  (remove disabled protocols)*/
2108 #ifdef USE_TCP
2109         if (tcp_disable)
2110 #endif
2111                 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2112                         if (nxt_proto[r]==PROTO_TCP)
2113                                 nxt_proto[r]=nxt_proto[PROTO_TCP];
2114                 }
2115 #ifdef USE_TCP
2116 #ifdef USE_TLS
2117         if (tls_disable || tcp_disable)
2118 #endif
2119 #endif
2120                 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2121                         if (nxt_proto[r]==PROTO_TLS)
2122                                 nxt_proto[r]=nxt_proto[PROTO_TLS];
2123                 }
2124 #ifdef USE_SCTP
2125         if (sctp_disable)
2126 #endif
2127                 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2128                         if (nxt_proto[r]==PROTO_SCTP)
2129                                 nxt_proto[r]=nxt_proto[PROTO_SCTP];
2130                 }
2131
2132         /* Deliberately skipping PROTO_WS and PROTO_WSS here as these
2133            are just upgraded TCP and TLS connections */
2134 }
2135
2136
2137 /**
2138  * parse '[port:]host[:port]' string to a broken down structure
2139  */
2140 int parse_protohostport(str* ins, sr_phostp_t *r)
2141 {
2142         char* first; /* first ':' occurrence */
2143         char* second; /* second ':' occurrence */
2144         char* p;
2145         int bracket;
2146         str tmp=STR_NULL;
2147
2148         first=second=0;
2149         bracket=0;
2150         memset(r, 0, sizeof(sr_phostp_t));
2151
2152         /* find the first 2 ':', ignoring possible ipv6 addresses
2153          * (substrings between [])
2154          */
2155         for(p=ins->s; p<ins->s+ins->len; p++){
2156                 switch(*p){
2157                         case '[':
2158                                 bracket++;
2159                                 if (bracket>1) goto error_brackets;
2160                                 break;
2161                         case ']':
2162                                 bracket--;
2163                                 if (bracket<0) goto error_brackets;
2164                                 break;
2165                         case ':':
2166                                 if (bracket==0){
2167                                         if (first==0) first=p;
2168                                         else if( second==0) second=p;
2169                                         else goto error_colons;
2170                                 }
2171                                 break;
2172                 }
2173         }
2174         if (p==ins->s) return -1;
2175         if (*(p-1)==':') goto error_colons;
2176
2177         if (first==0) { /* no ':' => only host */
2178                 r->host.s=ins->s;
2179                 r->host.len=(int)(p-ins->s);
2180                 goto end;
2181         }
2182         if (second) { /* 2 ':' found => check if valid */
2183                 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2184                         goto error_proto;
2185
2186                 tmp.s=second+1;
2187                 tmp.len=(ins->s + ins->len) - tmp.s;
2188
2189                 if (str2int(&tmp, (unsigned int *)&(r->port))<0) goto error_port;
2190
2191                 r->host.s=first+1;
2192                 r->host.len=(int)(second-r->host.s);
2193                 goto end;
2194         }
2195         /* only 1 ':' found => it's either proto:host or host:port */
2196         tmp.s=first+1;
2197         tmp.len=(ins->s + ins->len) - tmp.s;
2198         if (str2int(&tmp, (unsigned int *)&(r->port))<0) {
2199                 /* invalid port => it's proto:host */
2200                 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2201                         goto error_proto;
2202                 r->host.s=first+1;
2203                 r->host.len=(int)(p-r->host.s);
2204         }else{
2205                 /* valid port => its host:port */
2206                 r->host.s=ins->s;
2207                 r->host.len=(int)(first-r->host.s);
2208         }
2209 end:
2210         return 0;
2211 error_brackets:
2212         LM_ERR("too many brackets in %.*s\n", ins->len, ins->s);
2213         return -1;
2214 error_colons:
2215         LM_ERR("too many colons in %.*s\n", ins->len, ins->s);
2216         return -1;
2217 error_proto:
2218         LM_ERR("bad protocol in %.*s\n", ins->len, ins->s);
2219         return -1;
2220 error_port:
2221         LM_ERR("bad port number in %.*s\n", ins->len, ins->s);
2222         return -1;
2223 }
2224
2225 /**
2226  * lookup a local socket by '[port:]host[:port]' string
2227  */
2228 struct socket_info* lookup_local_socket(str *phostp)
2229 {
2230         sr_phostp_t r;
2231         if(parse_protohostport(phostp, &r)<0)
2232                 return NULL;
2233         return grep_sock_info(&r.host, (unsigned short)r.port,
2234                         (unsigned short)r.proto);
2235 }