core: more debug messages when matching myself
[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 - 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) {
637                         /* disabled or unknown protocol */
638                         continue;
639                 }
640                 for (si=*list; si; si=si->next) {
641                         LM_DBG("checking if host==us: %d==%d && [%.*s] == [%.*s]\n",
642                                                 hname.len,
643                                                 si->name.len,
644                                                 hname.len, hname.s,
645                                                 si->name.len, si->name.s
646                                 );
647                         if (port) {
648                                 LM_DBG("checking if port %d (advertise %d) matches port %d\n",
649                                                 si->port_no, si->useinfo.port_no, port);
650                                 if (si->port_no!=port && si->useinfo.port_no!=port) {
651                                         continue;
652                                 }
653                         }
654                         if (si_hname_cmp(&hname, &si->name, &si->address_str,
655                                                                 &si->address, si->flags)==0) {
656                                 goto found;
657                         }
658                         if(si->useinfo.name.s!=NULL) {
659                                 LM_DBG("checking advertise if host==us:"
660                                                 " %d==%d && [%.*s] == [%.*s]\n",
661                                                 hname.len,
662                                                 si->useinfo.name.len,
663                                                 hname.len, hname.s,
664                                                 si->useinfo.name.len, si->useinfo.name.s
665                                         );
666                                 if (si_hname_cmp(&hname, &si->useinfo.name,
667                                                         &si->useinfo.address_str, &si->useinfo.address,
668                                                         si->flags)==0) {
669                                         goto found;
670                                 }
671                         }
672                         /* try among the extra addresses */
673                         for (ai=si->addr_info_lst; ai; ai=ai->next) {
674                                 if (si_hname_cmp(&hname, &ai->name, &ai->address_str,
675                                                                         &ai->address, ai->flags)==0) {
676                                         goto found;
677                                 }
678                         }
679                 }
680
681         } while( (proto==0) && (c_proto=next_proto(c_proto)) );
682
683 #ifdef USE_TLS
684         if (unlikely(c_proto == PROTO_WS)) {
685                 c_proto = PROTO_WSS;
686                 goto retry;
687         }
688 #endif
689 /* not_found: */
690         return 0;
691 found:
692         return si;
693 }
694
695 socket_info_t* ksr_get_socket_by_name(str *sockname)
696 {
697         socket_info_t *si = NULL;
698         struct socket_info** list;
699         unsigned short c_proto;
700
701         c_proto = PROTO_UDP;
702         do {
703                 /* get the proper sock_list */
704                 list=get_sock_info_list(c_proto);
705
706                 if (list==0) {
707                         /* disabled or unknown protocol */
708                         continue;
709                 }
710
711                 for (si=*list; si; si=si->next) {
712                         if(si->sockname.s == NULL) {
713                                 continue;
714                         }
715                         LM_DBG("checking if sockname %.*s matches %.*s\n",
716                                         sockname->len, sockname->s,
717                                         si->sockname.len, si->sockname.s);
718                         if (sockname->len == si->sockname.len
719                                         && strncasecmp(sockname->s, si->sockname.s,
720                                                         sockname->len)==0) {
721                                 return si;
722                         }
723                 }
724         } while((c_proto = next_proto(c_proto))!=0);
725
726         return NULL;
727 }
728
729 /* checks if the proto:port is one of the ports we listen on
730  * and returns the corresponding socket_info structure.
731  * if proto==0 (PROTO_NONE) the protocol is ignored
732  * returns  0 if not found
733  */
734 struct socket_info* grep_sock_info_by_port(unsigned short port,
735                 unsigned short proto)
736 {
737         struct socket_info* si;
738         struct socket_info** list;
739         unsigned short c_proto;
740
741         if (!port) {
742                 goto not_found;
743         }
744         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
745         do {
746                 /* get the proper sock_list */
747                 list=get_sock_info_list(c_proto);
748
749                 if (list==0) /* disabled or unknown protocol */
750                         continue;
751
752                 for (si=*list; si; si=si->next){
753                         LM_DBG("checking if port %d matches port %d\n", si->port_no, port);
754                         if (si->port_no==port) {
755                                 goto found;
756                         }
757                 }
758         } while( (proto==0) && (c_proto=next_proto(c_proto)) );
759
760 not_found:
761         return 0;
762
763 found:
764         return si;
765 }
766
767
768
769 /* checks if the proto: ip:port is one of the address we listen on
770  * and returns the corresponding socket_info structure.
771  * (same as grep_socket_info, but use ip addr instead)
772  * if port==0, the  port number is ignored
773  * if proto==0 (PROTO_NONE) the protocol is ignored
774  * returns  0 if not found
775  * WARNING: uses str2ip6 so it will overwrite any previous
776  *  unsaved result of this function (static buffer)
777  */
778 struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
779                                                                                                 unsigned short proto)
780 {
781         struct socket_info* si;
782         struct socket_info** list;
783         struct addr_info* ai;
784         unsigned short c_proto;
785         
786         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
787         do{
788                 /* get the proper sock_list */
789                 list=get_sock_info_list(c_proto);
790         
791                 if (list==0) /* disabled or unknown protocol */
792                         continue;
793                 
794                 for (si=*list; si; si=si->next){
795                         if (port) {
796                                 if (si->port_no!=port) {
797                                         continue;
798                                 }
799                         }
800                         if (ip_addr_cmp(ip, &si->address)
801                                         || ip_addr_cmp(ip, &si->useinfo.address))
802                                 goto found;
803                         for (ai=si->addr_info_lst; ai; ai=ai->next)
804                                 if (ip_addr_cmp(ip, &ai->address))
805                                         goto found;
806                 }
807         }while( (proto==0) && (c_proto=next_proto(c_proto)) );
808 /* not_found: */
809         return 0;
810 found:
811         return si;
812 }
813
814
815
816 /* append a new sock_info structure to the corresponding list
817  * return  new sock info on success, 0 on error */
818 static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
819                                                                         unsigned short port,
820                                                                         unsigned short proto,
821                                                                         char *usename, unsigned short useport,
822                                                                         char *sockname,
823                                                                         enum si_flags flags,
824                                                                         struct socket_info** list)
825 {
826         struct socket_info* si;
827         /* allocates si and si->name in new pkg memory */
828         si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
829         if (si==0){
830                 LM_ERR("new_sock_info failed\n");
831                 goto error;
832         }
833         if(socket_workers>0) {
834                 si->workers = socket_workers;
835                 socket_workers = 0;
836         }
837 #ifdef USE_MCAST
838         if (mcast!=0) {
839                 si->mcast.len=strlen(mcast);
840                 si->mcast.s=(char*)pkg_malloc(si->mcast.len+1);
841                 if (si->mcast.s==0) {
842                         PKG_MEM_ERROR;
843                         pkg_free(si->name.s);
844                         pkg_free(si);
845                         return 0;
846                 }
847                 strcpy(si->mcast.s, mcast);
848                 mcast = 0;
849         }
850 #endif /* USE_MCAST */
851         sock_listadd(list, si);
852         return si;
853 error:
854         return 0;
855 }
856
857
858
859 /* adds a new sock_info structure immediately after "after"
860  * return  new sock info on success, 0 on error */
861 static struct socket_info* new_sock2list_after(char* name,
862                                                                         struct name_lst* addr_l,
863                                                                         unsigned short port,
864                                                                         unsigned short proto,
865                                                                         char *usename,
866                                                                         unsigned short useport,
867                                                                         char *sockname,
868                                                                         enum si_flags flags,
869                                                                         struct socket_info* after)
870 {
871         struct socket_info* si;
872
873         si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
874         if (si==0){
875                 LM_ERR("new_sock_info failed\n");
876                 goto error;
877         }
878         sock_listins(si, after);
879         return si;
880 error:
881         return 0;
882 }
883
884
885
886 /* adds a sock_info structure to the corresponding proto list
887  * return  0 on success, -1 on error */
888 int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
889                                                 unsigned short port, unsigned short proto,
890                                                 char *usename, unsigned short useport, char *sockname,
891                                                 enum si_flags flags)
892 {
893         struct socket_info** list;
894         unsigned short c_proto;
895         struct name_lst* a_l;
896         unsigned short c_port;
897
898         c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
899         do{
900                 list=get_sock_info_list(c_proto);
901                 if (list==0) /* disabled or unknown protocol */
902                         continue;
903
904                 if (port==0){ /* use default port */
905                         c_port=
906 #ifdef USE_TLS
907                                 ((c_proto)==PROTO_TLS)?tls_port_no:
908 #endif
909                                 port_no;
910                 }
911 #ifdef USE_TLS
912                 else if ((c_proto==PROTO_TLS) && (proto==0)){
913                         /* -l  ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1?*/
914                         c_port=port+1;
915                 }
916 #endif
917                 else{
918                         c_port=port;
919                 }
920                 if (c_proto!=PROTO_SCTP){
921                         if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
922                                                                 sockname, flags & ~SI_IS_MHOMED, list)==0){
923                                 LM_ERR("new_sock2list failed\n");
924                                 goto error;
925                         }
926                         /* add the other addresses in the list as separate sockets
927                          * since only SCTP can bind to multiple addresses */
928                         for (a_l=addr_l; a_l; a_l=a_l->next){
929                                 if (new_sock2list(a_l->name, 0, c_port,
930                                                                         c_proto, usename, useport, sockname,
931                                                                         flags & ~SI_IS_MHOMED, list)==0){
932                                         LM_ERR("new_sock2list failed\n");
933                                         goto error;
934                                 }
935                         }
936                 }else{
937                         if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
938                                                 sockname, flags, list)==0){
939                                 LM_ERR("new_sock2list failed\n");
940                                 goto error;
941                         }
942                 }
943         }while( (proto==0) && (c_proto=next_proto(c_proto)));
944         return 0;
945 error:
946         return -1;
947 }
948
949 /* adds a sock_info structure to the corresponding proto list
950  * return  0 on success, -1 on error */
951 int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
952                                                 unsigned short port, unsigned short proto,
953                                                 char *usename, unsigned short useport,
954                                                 enum si_flags flags)
955 {
956         return add_listen_advertise_iface_name(name, addr_l, port, proto,
957                                                 usename, useport, NULL, flags);
958 }
959
960 /* adds a sock_info structure to the corresponding proto list
961  * return  0 on success, -1 on error */
962 int add_listen_iface(char* name, struct name_lst* addr_l,
963                                                 unsigned short port, unsigned short proto,
964                                                 enum si_flags flags)
965 {
966         return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0, 0,
967                         flags);
968 }
969
970 /* adds a sock_info structure to the corresponding proto list
971  * return  0 on success, -1 on error */
972 int add_listen_iface_name(char* name, struct name_lst* addr_l,
973                                                 unsigned short port, unsigned short proto, char *sockname,
974                                                 enum si_flags flags)
975 {
976         return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0,
977                         sockname, flags);
978 }
979
980 #ifdef __OS_linux
981
982 #include "linux/types.h"
983 #include "linux/netlink.h"
984 #include "linux/rtnetlink.h"
985 #include "arpa/inet.h"
986
987
988 #define MAX_IF_LEN 64
989 struct idx
990 {
991         struct idx *    next;
992         int             family;
993         unsigned        ifa_flags;
994         char            addr[MAX_IF_LEN];
995
996 };
997
998 struct idxlist{
999         struct idx*     addresses;
1000         int             index;
1001         char            name[MAX_IF_LEN];
1002         unsigned        flags;
1003 };
1004
1005 #define MAX_IFACE_NO 32
1006
1007 static struct idxlist *ifaces = NULL;
1008 static int seq = 0;
1009
1010 #define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
1011
1012 #define NLMSG_TAIL(nmsg) \
1013         ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
1014
1015 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
1016               int alen)
1017 {
1018         int len = RTA_LENGTH(alen);
1019         struct rtattr *rta;
1020
1021         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
1022                 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
1023                 return -1;
1024         }
1025         rta = NLMSG_TAIL(n);
1026         rta->rta_type = type;
1027         rta->rta_len = len;
1028         memcpy(RTA_DATA(rta), data, alen);
1029         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
1030         return 0;
1031 }
1032
1033
1034
1035 static int nl_bound_sock(void)
1036 {
1037         int sock = -1;
1038         struct sockaddr_nl la;
1039
1040         sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1041         if(sock < 0){
1042                 LM_ERR("could not create NETLINK sock to get interface list\n");
1043                 goto error;
1044         }
1045
1046         /* bind NETLINK socket to pid */
1047         bzero(&la, sizeof(la));
1048         la.nl_family = AF_NETLINK;
1049         la.nl_pad = 0;
1050         la.nl_pid = getpid();
1051         la.nl_groups = 0;
1052         if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
1053                 LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
1054                 goto error;
1055         }
1056
1057         return sock;
1058 error:
1059         if(sock >= 0) close(sock);
1060         return -1;
1061 }
1062
1063 #define fill_nl_req(req, type, family) do {\
1064         memset(&req, 0, sizeof(req));\
1065         req.nlh.nlmsg_len = sizeof(req);\
1066         req.nlh.nlmsg_type = type;\
1067         req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP;\
1068         req.nlh.nlmsg_pid = getpid();\
1069         req.nlh.nlmsg_seq = seq++;\
1070         req.g.rtgen_family = family;\
1071         } while(0);
1072
1073         
1074 static int get_flags(int family){
1075         struct {
1076                 struct nlmsghdr nlh;
1077                 struct rtgenmsg g;
1078         } req;
1079         int rtn = 0;
1080         struct nlmsghdr*  nlp;
1081         struct ifinfomsg *ifi;
1082         char buf[8192];
1083         char *p = buf;
1084         int nll = 0;
1085     int nl_sock = -1;
1086
1087         fill_nl_req(req, RTM_GETLINK, AF_INET);
1088
1089         if((nl_sock = nl_bound_sock()) < 0) return -1;
1090
1091         if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0)
1092         {
1093                 LM_ERR("error sending NETLINK request\n");
1094                 goto error;
1095         }
1096
1097         while(1) {
1098                 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1099                 nlp = (struct nlmsghdr *) p;
1100                 if(nlp->nlmsg_type == NLMSG_DONE){
1101                         LM_DBG("done\n");
1102                          break;
1103                 }
1104                 if(nlp->nlmsg_type == NLMSG_ERROR){
1105                          LM_DBG("Error on message to netlink");
1106                          break;
1107                 }
1108                 p += rtn;
1109
1110                 nll += rtn;
1111         }
1112
1113         nlp = (struct nlmsghdr *) buf;
1114         for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1115                 ifi = NLMSG_DATA(nlp);
1116
1117                 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1118                         goto error;
1119
1120                 LM_ERR("Interface with index %d has flags %d\n", ifi->ifi_index, ifi->ifi_flags);
1121                 if(ifaces == NULL){
1122                         LM_ERR("get_flags must not be called on empty interface list");
1123                         goto error;
1124                 }
1125                 if(ifi->ifi_index >= MAX_IFACE_NO){
1126                         LM_ERR("invalid network interface index returned %d", ifi->ifi_index);
1127                         goto error;
1128                 }
1129                 ifaces[ifi->ifi_index].flags = ifi->ifi_flags;
1130         }
1131
1132         if(nl_sock>=0) close(nl_sock);
1133         return 0;
1134
1135 error:
1136         if(nl_sock>=0) close(nl_sock);
1137         return -1;
1138 }
1139
1140 static int build_iface_list(void)
1141 {
1142         struct {
1143                 struct nlmsghdr nlh;
1144                 struct rtgenmsg g;
1145         } req;
1146
1147         int rtn = 0;
1148         struct nlmsghdr*  nlp;
1149         struct ifaddrmsg *ifi;
1150         int rtl;
1151         char buf[8192];
1152         char *p = buf;
1153         int nll = 0;
1154         struct rtattr * rtap;
1155         int index, i;
1156         struct idx* entry;
1157         struct idx* tmp;
1158         int nl_sock = -1;
1159         int families[] = {AF_INET, AF_INET6};
1160         char name[MAX_IF_LEN];
1161         int is_link_local = 0;
1162
1163         if(ifaces == NULL){
1164                 if((ifaces = (struct idxlist*)pkg_malloc(MAX_IFACE_NO
1165                                                 *sizeof(struct idxlist))) == NULL){
1166                         PKG_MEM_ERROR;
1167                         return -1;
1168                 }
1169                 memset(ifaces, 0, sizeof(struct idxlist)*MAX_IFACE_NO);
1170         }
1171
1172         /* bind netlink socket */
1173         if((nl_sock = nl_bound_sock()) < 0) return -1;
1174
1175         for (i = 0 ; i < sizeof(families)/sizeof(int); i++) {
1176                 fill_nl_req(req, RTM_GETADDR, families[i]);
1177
1178                 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0){
1179                         LM_ERR("error sending NETLINK request\n");
1180                         goto error;
1181                 };
1182
1183                 memset(buf, 0, sizeof(buf));
1184                 nll = 0;
1185                 p = buf;
1186                 while(1) {
1187                         rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1188                         LM_DBG("received %d byles \n", rtn);
1189                         nlp = (struct nlmsghdr *) p;
1190                         if(nlp->nlmsg_type == NLMSG_DONE){
1191                                 LM_DBG("done receiving netlink info \n");
1192                                  break;
1193                         }
1194                         if(nlp->nlmsg_type == NLMSG_ERROR){
1195                                  LM_ERR("Error on message to netlink");
1196                                  break;
1197                         }
1198                         p += rtn;
1199
1200                         nll += rtn;
1201                 }
1202
1203                 nlp = (struct nlmsghdr *) buf;
1204                 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1205                         ifi = NLMSG_DATA(nlp);
1206
1207                         if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1208                                 continue;
1209                         // init all the strings
1210                         // inner loop: loop thru all the attributes of
1211                         // one route entry
1212                         rtap = (struct rtattr *) IFA_RTA(ifi);
1213
1214                         rtl = IFA_PAYLOAD(nlp);
1215
1216                         index = ifi->ifa_index;
1217                         if(index >= MAX_IFACE_NO){
1218                                 LM_ERR("Invalid interface index returned: %d\n", index);
1219                                 goto error;
1220                         }
1221
1222                         entry = (struct idx*)pkg_malloc(sizeof(struct idx));
1223                         if(entry == 0)
1224                         {
1225                                 PKG_MEM_ERROR;
1226                                 goto error;
1227                         }
1228
1229                         entry->next = 0;
1230                         entry->family = families[i];
1231                         entry->ifa_flags = ifi->ifa_flags;
1232             is_link_local = 0;
1233
1234                         name[0] = '\0';
1235                         for(;RTA_OK(rtap, rtl);rtap=RTA_NEXT(rtap,rtl)){
1236                                 switch(rtap->rta_type){
1237                                         case IFA_ADDRESS:
1238                                                 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1239                                                         LM_DBG("Link Local Address, ignoring ...\n");
1240                                                         is_link_local = 1;
1241                                                         break;
1242                                                 }
1243                                                 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1244                                                 LM_DBG("iface <IFA_ADDRESS> addr is  %s\n", entry->addr);
1245                                                 break;
1246                                         case IFA_LOCAL:
1247                                                 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1248                                                         LM_DBG("Link Local Address, ignoring ...\n");
1249                                                         is_link_local = 1;
1250                                                 }
1251                                                 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1252                                                 LM_DBG("iface <IFA_LOCAL> addr is %s\n", entry->addr);
1253                                                 break;
1254                                         case IFA_LABEL:
1255                                                 LM_DBG("iface name is %s\n", (char*)RTA_DATA(rtap));
1256                                                 strncpy(name, (char*)RTA_DATA(rtap), MAX_IF_LEN-1);
1257                                                 break;
1258                                         case IFA_BROADCAST:
1259                                         case IFA_ANYCAST:
1260                                         case IFA_UNSPEC:
1261                                         case IFA_CACHEINFO:
1262                                         default:
1263                                                 break;
1264                                 }
1265                         }
1266                         if(is_link_local) {
1267                                 if(sr_bind_ipv6_link_local==0) {
1268                                         /* skip - link local addresses are not bindable without scope */
1269                                         pkg_free(entry);
1270                                         continue;
1271                                 }
1272                         }
1273
1274                         if(strlen(ifaces[index].name)==0 && strlen(name)>0) {
1275                                 strncpy(ifaces[index].name, name, MAX_IF_LEN-1);
1276                         }
1277
1278                         ifaces[index].index = index;
1279
1280                         if(ifaces[index].addresses == 0 )
1281                                 ifaces[index].addresses = entry;
1282                         else {
1283                                 for(tmp = ifaces[index].addresses; tmp->next ; tmp = tmp->next)/*empty*/;
1284                                 tmp->next = entry;
1285                         }
1286                 }
1287         }
1288         if(nl_sock>0) close(nl_sock);
1289         /* the socket should be closed so we can bind again */
1290         for(i = 0; i < sizeof(families)/sizeof(int); i++){
1291                 /* get device flags */
1292                 get_flags(families[i]); /* AF_INET or AF_INET6 */
1293         }
1294
1295         return 0;
1296 error:
1297         if(nl_sock>=0) close(nl_sock);
1298         return -1;
1299
1300 }
1301 /* add all family type addresses of interface if_name to the socket_info array
1302  * if family ==0, uses all families
1303  * if if_name==0, adds all addresses on all interfaces
1304  * uses RTNETLINK sockets to get addresses on the present interface on LINUX
1305  * return: -1 on error, 0 on success
1306  */
1307 int add_interfaces_via_netlink(char* if_name, int family, unsigned short port,
1308                                         unsigned short proto,
1309                                         struct addr_info** ai_l)
1310 {
1311         int i;
1312         struct idx* tmp;
1313         enum si_flags flags;
1314
1315         if(ifaces == NULL && (build_iface_list()!=0)){
1316                 LM_ERR("Could not get network interface list\n");
1317                 return -1;
1318         }
1319
1320         flags=SI_NONE;
1321         for(i=0; i< MAX_IFACE_NO; ++i){
1322                 if(ifaces[i].addresses == NULL) continue; /* not present/configured */
1323                 if ((if_name==0)||
1324                         (strncmp(if_name, ifaces[i].name, strlen(ifaces[i].name))==0)){
1325
1326                         /* check if iface is up */
1327                         //if(! (ifaces[i].flags & IFF_UP) ) continue;
1328
1329                         for(tmp = ifaces[i].addresses; tmp; tmp = tmp->next){
1330                                 LM_DBG("in add_iface_via_netlink Name %s Address %s\n",
1331                                                         ifaces[i].name, tmp->addr);
1332                                         /* match family */
1333                                         if (family && family == tmp->family){
1334                                         /* check if loopback */
1335                                         if (ifaces[i].flags & IFF_LOOPBACK){
1336                                                 LM_DBG("INTERFACE %s is loopback", ifaces[i].name);
1337                                                 flags|=SI_IS_LO;
1338                                         }
1339                                         /* save the info */
1340                                         if (new_addr_info2list(tmp->addr, flags, ai_l)!=0){
1341                                                 LM_ERR("new_addr_info2list failed\n");
1342                                                 goto error;
1343                                         }
1344                                 }
1345                         }
1346                 }
1347         }
1348         return 0;
1349 error:
1350         return -1;
1351 }
1352 #endif /* __OS_linux */
1353
1354 /* add all family type addresses of interface if_name to the socket_info array
1355  * if family ==0, uses all families
1356  * if if_name==0, adds all addresses on all interfaces
1357  * return: -1 on error, 0 on success
1358  */
1359 int add_interfaces(char* if_name, int family, unsigned short port,
1360                                         unsigned short proto,
1361                                         struct addr_info** ai_l)
1362 {
1363         char* tmp;
1364         struct ip_addr addr;
1365         int ret = -1;
1366         enum si_flags flags;
1367         struct ifaddrs *ifap, *ifa;
1368
1369         if (getifaddrs (&ifap) != 0) {
1370                 LM_ERR("getifaddrs failed\n");
1371                 return -1;
1372         }
1373
1374         for (ifa = ifap; ifa; ifa = ifa->ifa_next)
1375         {
1376                 /* skip if no IP addr associated with the interface */
1377                 if (ifa->ifa_addr==0)
1378                         continue;
1379 #ifdef AF_PACKET
1380                 /* skip AF_PACKET addr family since it is of no use later on */
1381                 if (ifa->ifa_addr->sa_family == AF_PACKET)
1382                         continue;
1383 #endif
1384                 if (if_name && strcmp(if_name, ifa->ifa_name))
1385                         continue;
1386                 if (family && family != ifa->ifa_addr->sa_family)
1387                         continue;
1388                 sockaddr2ip_addr(&addr, (struct sockaddr*)ifa->ifa_addr);
1389                 tmp=ip_addr2a(&addr);
1390                 if (ifa->ifa_flags & IFF_LOOPBACK)
1391                         flags = SI_IS_LO;
1392                 else
1393                         flags = SI_NONE;
1394                 if (new_addr_info2list(tmp, flags, ai_l)!=0)
1395                 {
1396                         LM_ERR("new_addr_info2list failed\n");
1397                         ret = -1;
1398                         break;
1399                 }
1400                 LM_DBG("If: %8s Fam: %8x Flg: %16lx Adr: %s\n",
1401                                 ifa->ifa_name, ifa->ifa_addr->sa_family,
1402                                 (unsigned long)ifa->ifa_flags, tmp);
1403
1404                 ret = 0;
1405         }
1406         freeifaddrs(ifap);
1407         return  ret;
1408 }
1409
1410
1411
1412 /* internal helper function: resolve host names and add aliases
1413  * name is a value result parameter: it should contain the hostname that
1414  * will be used to fill all the other members, including name itself
1415  * in some situation (name->s should be a 0 terminated pkg_malloc'ed string)
1416  * return 0 on success and -1 on error */
1417 static int fix_hostname(str* name, struct ip_addr* address, str* address_str,
1418                                                 enum si_flags* flags, int* type_flags,
1419                                                 struct socket_info* s)
1420 {
1421         struct hostent* he;
1422         char* tmp;
1423         char** h;
1424         
1425         /* get "official hostnames", all the aliases etc. */
1426         he=resolvehost(name->s);
1427         if (he==0){
1428                 LM_ERR("could not resolve %s\n", name->s);
1429                 goto error;
1430         }
1431         /* check if we got the official name */
1432         if (strcasecmp(he->h_name, name->s)!=0){
1433                 if (sr_auto_aliases && 
1434                                 add_alias(name->s, name->len, s->port_no, s->proto)<0){
1435                         LM_ERR("add_alias failed\n");
1436                 }
1437                 /* change the official name */
1438                 pkg_free(name->s);
1439                 name->s=(char*)pkg_malloc(strlen(he->h_name)+1);
1440                 if (name->s==0){
1441                         PKG_MEM_ERROR;
1442                         goto error;
1443                 }
1444                 name->len=strlen(he->h_name);
1445                 strncpy(name->s, he->h_name, name->len+1);
1446         }
1447         /* add the aliases*/
1448         for(h=he->h_aliases; sr_auto_aliases && h && *h; h++)
1449                 if (add_alias(*h, strlen(*h), s->port_no, s->proto)<0){
1450                         LM_ERR("add_alias failed\n");
1451                 }
1452         hostent2ip_addr(address, he, 0); /*convert to ip_addr format*/
1453         if (type_flags){
1454                 *type_flags|=(address->af==AF_INET)?SOCKET_T_IPV4:SOCKET_T_IPV6;
1455         }
1456         if ((tmp=ip_addr2a(address))==0) goto error;
1457         address_str->s=pkg_malloc(strlen(tmp)+1);
1458         if (address_str->s==0){
1459                 PKG_MEM_ERROR;
1460                 goto error;
1461         }
1462         strncpy(address_str->s, tmp, strlen(tmp)+1);
1463         /* set is_ip (1 if name is an ip address, 0 otherwise) */
1464         address_str->len=strlen(tmp);
1465         if (sr_auto_aliases && (address_str->len==name->len) &&
1466                 (strncasecmp(address_str->s, name->s, address_str->len)==0)){
1467                 *flags|=SI_IS_IP;
1468                 /* do rev. DNS on it (for aliases)*/
1469                 he=rev_resolvehost(address);
1470                 if (he==0){
1471                         LM_WARN("could not rev. resolve %s\n", name->s);
1472                 }else{
1473                         /* add the aliases*/
1474                         if (add_alias(he->h_name, strlen(he->h_name), s->port_no,
1475                                                         s->proto)<0){
1476                                 LM_ERR("add_alias failed\n");
1477                         }
1478                         for(h=he->h_aliases; h && *h; h++)
1479                                 if (add_alias(*h, strlen(*h), s->port_no, s->proto) < 0){
1480                                         LM_ERR("add_alias failed\n");
1481                                 }
1482                 }
1483         }
1484         
1485 #ifdef USE_MCAST
1486         /* Check if it is an multicast address and
1487          * set the flag if so
1488          */
1489         if (is_mcast(address)){
1490                 *flags |= SI_IS_MCAST;
1491         }
1492 #endif /* USE_MCAST */
1493         
1494         /* check if INADDR_ANY */
1495         if (ip_addr_any(address))
1496                 *flags|=SI_IS_ANY;
1497         else if (ip_addr_loopback(address)) /* check for loopback */
1498                 *flags|=SI_IS_LO;
1499         
1500         return 0;
1501 error:
1502         return -1;
1503 }
1504
1505
1506
1507 /* append new elements to a socket_info list after "list"
1508  * each element is created  from addr_info_lst + port, protocol and flags
1509  * return 0 on succes, -1 on error
1510  */
1511 static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
1512                                                                 char proto, char *usename,
1513                                                                 unsigned short useport, char *sockname,
1514                                                                 enum si_flags flags,
1515                                                                 struct socket_info** list)
1516 {
1517         struct addr_info* ail;
1518
1519         for (ail=ai_lst; ail; ail=ail->next){
1520                 if(new_sock2list(ail->name.s, 0, port, proto, usename, useport, sockname,
1521                                         ail->flags | flags, list)==0)
1522                         return -1;
1523         }
1524         return 0;
1525 }
1526
1527
1528
1529 /* insert new elements to a socket_info list after "el",
1530  * each element is created from addr_info_lst + port, * protocol and flags
1531  * return 0 on succes, -1 on error
1532  */
1533 static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
1534                                                                                 unsigned short port,
1535                                                                                 char proto,
1536                                                                                 char *usename,
1537                                                                                 unsigned short useport,
1538                                                                                 char *sockname,
1539                                                                                 enum si_flags flags,
1540                                                                                 struct socket_info* el)
1541 {
1542         struct addr_info* ail;
1543         struct socket_info* new_si;
1544
1545         for (ail=ai_lst; ail; ail=ail->next){
1546                 if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
1547                                                                 usename, useport, sockname,
1548                                                                 ail->flags | flags, el))==0)
1549                         return -1;
1550                 el=new_si;
1551         }
1552         return 0;
1553 }
1554
1555
1556
1557 /* fixes a socket list => resolve addresses,
1558  * interface names, fills missing members, remove duplicates
1559  * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
1560 static int fix_socket_list(struct socket_info **list, int* type_flags)
1561 {
1562         struct socket_info* si;
1563         struct socket_info* new_si;
1564         struct socket_info* l;
1565         struct socket_info* next;
1566         struct socket_info* next_si;
1567         struct socket_info* del_si;
1568         struct socket_info* keep_si;
1569         char* tmp;
1570         int len;
1571         struct addr_info* ai_lst;
1572         struct addr_info* ail;
1573         struct addr_info* tmp_ail;
1574         struct addr_info* tmp_ail_next;
1575         struct addr_info* ail_next;
1576
1577         if (type_flags)
1578                 *type_flags=0;
1579         /* try to change all the interface names into addresses
1580          *  --ugly hack */
1581         for (si=*list;si;){
1582                 next=si->next;
1583                 ai_lst=0;
1584                 if (add_interfaces(si->name.s, auto_bind_ipv6 ? 0 : AF_INET,
1585                                                         si->port_no, si->proto, &ai_lst)!=-1){
1586                         if (si->flags & SI_IS_MHOMED){
1587                                 if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
1588                                                                                         si->proto, si->useinfo.name.s,
1589                                                                                         si->useinfo.port_no, si->sockname.s,
1590                                                                                         ai_lst->flags|si->flags, si))==0)
1591                                         break;
1592                                 ail=ai_lst;
1593                                 ai_lst=ai_lst->next;
1594                                 free_addr_info(ail); /* free the first elem. */
1595                                 if (ai_lst){
1596                                         ai_lst->prev=0;
1597                                         /* find the end */
1598                                         for (ail=ai_lst; ail->next; ail=ail->next);
1599                                         /* add the mh list after the last position in ai_lst */
1600                                         addr_info_list_ins_lst(si->addr_info_lst, ail);
1601                                         new_si->addr_info_lst=ai_lst;
1602                                         si->addr_info_lst=0; /* detached and moved to new_si */
1603                                         ail=ail->next; /* ail== old si->addr_info_lst */
1604                                 }else{
1605                                         ail=si->addr_info_lst;
1606                                         new_si->addr_info_lst=ail;
1607                                         si->addr_info_lst=0; /* detached and moved to new_si */
1608                                 }
1609                         }else{
1610                                 /* add all addr. as separate  interfaces */
1611                                 if (addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto,
1612                                                         si->useinfo.name.s, si->useinfo.port_no,
1613                                                         si->sockname.s, si->flags, si)!=0)
1614                                         goto error;
1615                                 /* ai_lst not needed anymore */
1616                                 free_addr_info_lst(&ai_lst);
1617                                 ail=0;
1618                                 new_si=0;
1619                         }
1620                         /* success => remove current entry (shift the entire array)*/
1621                         sock_listrm(list, si);
1622                         free_sock_info(si);
1623                 }else{
1624                         new_si=si;
1625                         ail=si->addr_info_lst;
1626                 }
1627
1628                 if (ail){
1629                         if (new_si && (new_si->flags & SI_IS_MHOMED)){
1630                                 ai_lst=0;
1631                                 for (; ail;){
1632                                         ail_next=ail->next;
1633                                         if (add_interfaces(ail->name.s, AF_INET, new_si->port_no,
1634                                                                                         new_si->proto, &ai_lst)!=-1){
1635                                                 /* add the resolved list after the current position */
1636                                                 addr_info_list_ins_lst(ai_lst, ail);
1637                                                 /* success, remove the current entity */
1638                                                 addr_info_listrm(&new_si->addr_info_lst, ail);
1639                                                 free_addr_info(ail);
1640                                                 ai_lst=0;
1641                                         }
1642                                         ail=ail_next;
1643                                 }
1644                         }
1645                 }
1646                 si=next;
1647         }
1648         /* get ips & fill the port numbers*/
1649 #ifdef EXTRA_DEBUG
1650         LM_DBG("Listening on\n");
1651 #endif
1652         for (si=*list;si;si=si->next){
1653                 /* fix port number, port_no should be !=0 here */
1654                 if (si->port_no==0){
1655 #ifdef USE_TLS
1656                         si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
1657 #else
1658                         si->port_no= port_no;
1659 #endif
1660                 }
1661                 tmp=int2str(si->port_no, &len);
1662                 if (len>=MAX_PORT_LEN){
1663                         LM_ERR("bad port number: %d\n", si->port_no);
1664                         goto error;
1665                 }
1666                 si->port_no_str.s=(char*)pkg_malloc(len+1);
1667                 if (si->port_no_str.s==0){
1668                         PKG_MEM_ERROR;
1669                         goto error;
1670                 }
1671                 strncpy(si->port_no_str.s, tmp, len+1);
1672                 si->port_no_str.len=len;
1673
1674                 if (fix_hostname(&si->name, &si->address, &si->address_str,
1675                                                 &si->flags, type_flags, si) !=0 )
1676                         goto error;
1677                 /* fix hostnames in mh addresses */
1678                 for (ail=si->addr_info_lst; ail; ail=ail->next){
1679                         if (fix_hostname(&ail->name, &ail->address, &ail->address_str,
1680                                                 &ail->flags, type_flags, si) !=0 )
1681                                 goto error;
1682                 }
1683
1684                 if (fix_sock_str(si) < 0) goto error;
1685
1686 #ifdef EXTRA_DEBUG
1687                 printf("              %.*s [%s]:%s%s\n", si->name.len,
1688                                 si->name.s, si->address_str.s, si->port_no_str.s,
1689                                 si->flags & SI_IS_MCAST ? " mcast" : "");
1690 #endif
1691         }
1692         /* removing duplicate addresses*/
1693         for (si=*list;si; ){
1694                 next_si=si->next;
1695                 for (l=si->next;l;){
1696                         next=l->next;
1697                         if ((si->port_no==l->port_no) &&
1698                                 (si->address.af==l->address.af) &&
1699                                 (memcmp(si->address.u.addr, l->address.u.addr,
1700                                                 si->address.len) == 0)
1701                                 ){
1702                                 /* remove the socket with no  extra addresses.,
1703                                  * if both of them have extra addresses, remove one of them
1704                                  * and merge the extra addresses into the other */
1705                                 if (l->addr_info_lst==0){
1706                                         del_si=l;
1707                                         keep_si=si;
1708                                 }else if (si->addr_info_lst==0){
1709                                         del_si=si;
1710                                         keep_si=l;
1711                                 }else{
1712                                         /* move l->addr_info_lst to si->addr_info_lst */
1713                                         /* find last elem */
1714                                         for (ail=si->addr_info_lst; ail->next; ail=ail->next);
1715                                         /* add the l list after the last position in si lst */
1716                                         addr_info_list_ins_lst(l->addr_info_lst, ail);
1717                                         l->addr_info_lst=0; /* detached */
1718                                         del_si=l; /* l will be removed */
1719                                         keep_si=l;
1720                                 }
1721 #ifdef EXTRA_DEBUG
1722                                 printf("removing duplicate %s [%s] ==  %s [%s]\n",
1723                                                 keep_si->name.s, keep_si->address_str.s,
1724                                                  del_si->name.s, del_si->address_str.s);
1725 #endif
1726                                 /* add the name to the alias list*/
1727                                 if ((!(del_si->flags& SI_IS_IP)) && (
1728                                                 (del_si->name.len!=keep_si->name.len)||
1729                                                 (strncmp(del_si->name.s, keep_si->name.s,
1730                                                                  del_si->name.len)!=0))
1731                                         )
1732                                         add_alias(del_si->name.s, del_si->name.len,
1733                                                                 l->port_no, l->proto);
1734                                 /* make sure next_si doesn't point to del_si */
1735                                 if (del_si==next_si)
1736                                         next_si=next_si->next;
1737                                 /* remove del_si*/
1738                                 sock_listrm(list, del_si);
1739                                 free_sock_info(del_si);
1740                         }
1741                         l=next;
1742                 }
1743                 si=next_si;
1744         }
1745         /* check for duplicates in extra_addresses */
1746         for (si=*list;si; si=si->next){
1747                 /* check  for & remove internal duplicates: */
1748                 for (ail=si->addr_info_lst; ail;){
1749                         ail_next=ail->next;
1750                         /* 1. check if the extra addresses contain a duplicate for the
1751                          * main  one */
1752                         if ((ail->address.af==si->address.af) &&
1753                                 (memcmp(ail->address.u.addr, si->address.u.addr,
1754                                                         ail->address.len) == 0)){
1755                                 /* add the name to the alias list*/
1756                                 if ((!(ail->flags& SI_IS_IP)) && (
1757                                         (ail->name.len!=si->name.len)||
1758                                         (strncmp(ail->name.s, si->name.s, ail->name.len)!=0)))
1759                                         add_alias(ail->name.s, ail->name.len, si->port_no,
1760                                                                 si->proto);
1761                                         /* remove ail*/
1762                                 addr_info_listrm(&si->addr_info_lst, ail);
1763                                 free_addr_info(ail);
1764                                 ail=ail_next;
1765                                 continue;
1766                         }
1767                         /* 2. check if the extra addresses contain a duplicates for
1768                          *  other addresses in the same list */
1769                         for (tmp_ail=ail->next; tmp_ail;){
1770                                 tmp_ail_next=tmp_ail->next;
1771                                 if ((ail->address.af==tmp_ail->address.af) &&
1772                                         (memcmp(ail->address.u.addr, tmp_ail->address.u.addr,
1773                                                         ail->address.len) == 0)){
1774                                         /* add the name to the alias list*/
1775                                         if ((!(tmp_ail->flags& SI_IS_IP)) && (
1776                                                 (ail->name.len!=tmp_ail->name.len)||
1777                                                 (strncmp(ail->name.s, tmp_ail->name.s,
1778                                                                                 tmp_ail->name.len)!=0))
1779                                                 )
1780                                                 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1781                                                                         si->port_no, si->proto);
1782                                                 /* remove tmp_ail*/
1783                                         addr_info_listrm(&si->addr_info_lst, tmp_ail);
1784                                         if(ail_next==tmp_ail) {
1785                                                 ail_next = tmp_ail_next;
1786                                         }
1787                                         free_addr_info(tmp_ail);
1788                                 }
1789                                 tmp_ail=tmp_ail_next;
1790                         }
1791                         ail=ail_next;
1792                 }
1793                 /* check for duplicates between extra addresses (e.g. sctp MH)
1794                  * and other main addresses, on conflict remove the corresponding
1795                  * extra addresses (another possible solution would be to join
1796                  * the 2 si entries into one). */
1797                 for (ail=si->addr_info_lst; ail;){
1798                         ail_next=ail->next;
1799                         for (l=*list;l; l=l->next){
1800                                 if (l==si) continue;
1801                                 if (si->port_no==l->port_no){
1802                                         if ((ail->address.af==l->address.af) &&
1803                                                 (memcmp(ail->address.u.addr, l->address.u.addr,
1804                                                                                 ail->address.len) == 0)){
1805                                                 /* add the name to the alias list*/
1806                                                 if ((!(ail->flags& SI_IS_IP)) && (
1807                                                         (ail->name.len!=l->name.len)||
1808                                                         (strncmp(ail->name.s, l->name.s, l->name.len)!=0))
1809                                                         )
1810                                                         add_alias(ail->name.s, ail->name.len,
1811                                                                                 l->port_no, l->proto);
1812                                                 /* remove ail*/
1813                                                 addr_info_listrm(&si->addr_info_lst, ail);
1814                                                 free_addr_info(ail);
1815                                                 break;
1816                                         }
1817                                         /* check for duplicates with other  extra addresses
1818                                          * lists */
1819                                         for (tmp_ail=l->addr_info_lst; tmp_ail; ){
1820                                                 tmp_ail_next=tmp_ail->next;
1821                                                 if ((ail->address.af==tmp_ail->address.af) &&
1822                                                         (memcmp(ail->address.u.addr,
1823                                                                         tmp_ail->address.u.addr,
1824                                                                         ail->address.len) == 0)){
1825                                                         /* add the name to the alias list*/
1826                                                         if ((!(tmp_ail->flags& SI_IS_IP)) && (
1827                                                                         (ail->name.len!=tmp_ail->name.len)||
1828                                                                         (strncmp(ail->name.s, tmp_ail->name.s,
1829                                                                                         tmp_ail->name.len)!=0))
1830                                                                 )
1831                                                                 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1832                                                                                 l->port_no, l->proto);
1833                                                         /* remove tmp_ail*/
1834                                                         addr_info_listrm(&l->addr_info_lst, tmp_ail);
1835                                                         free_addr_info(tmp_ail);
1836                                                 }
1837                                                 tmp_ail=tmp_ail_next;
1838                                         }
1839                                 }
1840                         }
1841                         ail=ail_next;
1842                 }
1843         }
1844
1845 #ifdef USE_MCAST
1846              /* Remove invalid multicast entries */
1847         si=*list;
1848         while(si){
1849                 if ((si->proto == PROTO_TCP)
1850 #ifdef USE_TLS
1851                     || (si->proto == PROTO_TLS)
1852 #endif /* USE_TLS */
1853 #ifdef USE_SCTP
1854                         || (si->proto == PROTO_SCTP)
1855 #endif
1856                         ){
1857                         if (si->flags & SI_IS_MCAST){
1858                                 LM_WARN("removing entry %s:%s [%s]:%s\n",
1859                                         get_valid_proto_name(si->proto), si->name.s,
1860                                         si->address_str.s, si->port_no_str.s);
1861                                 l = si;
1862                                 si=si->next;
1863                                 sock_listrm(list, l);
1864                                 free_sock_info(l);
1865                         }else{
1866                                 ail=si->addr_info_lst;
1867                                 while(ail){
1868                                         if (ail->flags & SI_IS_MCAST){
1869                                                 LM_WARN("removing mh entry %s:%s"
1870                                                                 " [%s]:%s\n",
1871                                                                 get_valid_proto_name(si->proto), ail->name.s,
1872                                                                 ail->address_str.s, si->port_no_str.s);
1873                                                 tmp_ail=ail;
1874                                                 ail=ail->next;
1875                                                 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1876                                                 free_addr_info(tmp_ail);
1877                                         }else{
1878                                                 ail=ail->next;
1879                                         }
1880                                 }
1881                                 si=si->next;
1882                         }
1883                 } else {
1884                         si=si->next;
1885                 }
1886         }
1887 #endif /* USE_MCAST */
1888
1889         return 0;
1890 error:
1891         return -1;
1892 }
1893
1894 int socket_types = 0;
1895
1896 /* fix all 3 socket lists, fills socket_types if non-null
1897  * return 0 on success, -1 on error */
1898 int fix_all_socket_lists()
1899 {
1900         struct utsname myname;
1901         int flags;
1902         struct addr_info* ai_lst;
1903
1904         ai_lst=0;
1905
1906         if ((udp_listen==0)
1907 #ifdef USE_TCP
1908                         && (tcp_listen==0)
1909 #ifdef USE_TLS
1910                         && (tls_listen==0)
1911 #endif
1912 #endif
1913 #ifdef USE_SCTP
1914                         && (sctp_listen==0)
1915 #endif
1916                 ){
1917                 /* get all listening ipv4/ipv6 interfaces */
1918                 if ( ( (add_interfaces(0, AF_INET, 0,  PROTO_UDP, &ai_lst)==0)
1919 #ifdef __OS_linux
1920                 &&  (!auto_bind_ipv6 || add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0)
1921 #else
1922                 && ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0,  PROTO_UDP, &ai_lst) ==0 ) /* add_interface does not work for IPv6 on Linux */
1923 #endif /* __OS_linux */
1924                          ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, &udp_listen)==0)){
1925                         free_addr_info_lst(&ai_lst);
1926                         ai_lst=0;
1927                         /* if ok, try to add the others too */
1928 #ifdef USE_TCP
1929                         if (!tcp_disable){
1930                                 if ( ((add_interfaces(0, AF_INET, 0,  PROTO_TCP, &ai_lst)!=0)
1931 #ifdef __OS_linux
1932                                 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TCP, &ai_lst) != 0)
1933 #else
1934                                 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TCP, &ai_lst) !=0 )
1935 #endif /* __OS_linux */
1936                                 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0, 0,
1937                                                                                                                 &tcp_listen)!=0))
1938                                         goto error;
1939                                 free_addr_info_lst(&ai_lst);
1940                                 ai_lst=0;
1941 #ifdef USE_TLS
1942                                 if (!tls_disable){
1943                                         if (((add_interfaces(0, AF_INET, 0, PROTO_TLS,
1944                                                                                 &ai_lst)!=0)
1945 #ifdef __OS_linux
1946                                 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TLS, &ai_lst) != 0)
1947 #else
1948                                 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TLS, &ai_lst)!=0)
1949 #endif /* __OS_linux */
1950                                         ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, 0, 0,
1951                                                                                                                 &tls_listen)!=0))
1952                                                 goto error;
1953                                 }
1954                                 free_addr_info_lst(&ai_lst);
1955                                 ai_lst=0;
1956 #endif
1957                         }
1958 #endif
1959 #ifdef USE_SCTP
1960                         if (!sctp_disable){
1961                                 if (((add_interfaces(0, AF_INET, 0,  PROTO_SCTP, &ai_lst)!=0)
1962 #ifdef __OS_linux
1963                                 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1964 #else
1965                                 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_SCTP, &ai_lst) != 0)
1966 #endif /* __OS_linux */
1967                                         ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0, 0,
1968                                                                                         &sctp_listen)!=0))
1969                                         goto error;
1970                                 free_addr_info_lst(&ai_lst);
1971                                 ai_lst=0;
1972                         }
1973 #endif /* USE_SCTP */
1974                 }else{
1975                         /* if error fall back to get hostname */
1976                         /* get our address, only the first one */
1977                         if (uname (&myname) <0){
1978                                 LM_ERR("cannot determine hostname, try -l address\n");
1979                                 goto error;
1980                         }
1981                         if (add_listen_iface(myname.nodename, 0, 0, 0, 0)!=0){
1982                                 LM_ERR("add_listen_iface failed \n");
1983                                 goto error;
1984                         }
1985                 }
1986         }
1987         flags=0;
1988         if (fix_socket_list(&udp_listen, &flags)!=0){
1989                 LM_ERR("fix_socket_list udp failed\n");
1990                 goto error;
1991         }
1992         if (flags){
1993                 socket_types|=flags|SOCKET_T_UDP;
1994         }
1995 #ifdef USE_TCP
1996         flags=0;
1997         if (!tcp_disable && (fix_socket_list(&tcp_listen, &flags)!=0)){
1998                 LM_ERR("fix_socket_list tcp failed\n");
1999                 goto error;
2000         }
2001         if (flags){
2002                 socket_types|=flags|SOCKET_T_TCP;
2003         }
2004 #ifdef USE_TLS
2005         flags=0;
2006         if (!tls_disable && (fix_socket_list(&tls_listen, &flags)!=0)){
2007                 LM_ERR("fix_socket_list tls failed\n");
2008                 goto error;
2009         }
2010         if (flags){
2011                 socket_types|=flags|SOCKET_T_TLS;
2012         }
2013 #endif
2014 #endif
2015 #ifdef USE_SCTP
2016         flags=0;
2017         if (!sctp_disable && (fix_socket_list(&sctp_listen, &flags)!=0)){
2018                 LM_ERR("fix_socket_list sctp failed\n");
2019                 goto error;
2020         }
2021         if (flags){
2022                 socket_types|=flags|SOCKET_T_SCTP;
2023         }
2024 #endif /* USE_SCTP */
2025         if ((udp_listen==0)
2026 #ifdef USE_TCP
2027                         && (tcp_listen==0)
2028 #ifdef USE_TLS
2029                         && (tls_listen==0)
2030 #endif
2031 #endif
2032 #ifdef USE_SCTP
2033                         && (sctp_listen==0)
2034 #endif
2035                 ){
2036                 LM_ERR("no listening sockets\n");
2037                 goto error;
2038         }
2039         return 0;
2040 error:
2041         if (ai_lst) free_addr_info_lst(&ai_lst);
2042         return -1;
2043 }
2044
2045
2046
2047 void print_all_socket_lists()
2048 {
2049         struct socket_info *si;
2050         struct socket_info** list;
2051         struct addr_info* ai;
2052         unsigned short proto;
2053
2054         proto=PROTO_UDP;
2055         do{
2056                 list=get_sock_info_list(proto);
2057                 for(si=list?*list:0; si; si=si->next){
2058                         if (si->addr_info_lst){
2059                                 printf("             %s: (%s",
2060                                                 get_valid_proto_name(proto),
2061                                                 si->address_str.s);
2062                                 for (ai=si->addr_info_lst; ai; ai=ai->next) {
2063                                         printf(", %s", ai->address_str.s);
2064                                 }
2065                                 printf("):%s%s%s\n",
2066                                                 si->port_no_str.s,
2067                                                 si->flags & SI_IS_MCAST ? " mcast" : "",
2068                                                 si->flags & SI_IS_MHOMED? " mhomed" : "");
2069                         }else{
2070                                 printf("             %s: %s",
2071                                                 get_valid_proto_name(proto),
2072                                                 si->name.s);
2073                                 if (!(si->flags & SI_IS_IP)) {
2074                                         printf(" [%s]", si->address_str.s);
2075                                 }
2076                                 printf( ":%s%s%s",
2077                                                 si->port_no_str.s,
2078                                                 si->flags & SI_IS_MCAST ? " mcast" : "",
2079                                                 si->flags & SI_IS_MHOMED? " mhomed" : "");
2080                                 if (si->sockname.s) {
2081                                         printf(" name %s", si->sockname.s);
2082                                 }
2083                                 if (si->useinfo.name.s) {
2084                                         printf(" advertise %s:%d", si->useinfo.name.s, si->useinfo.port_no);
2085                                 }
2086                                 printf("\n");
2087                         }
2088                 }
2089         }while((proto=next_proto(proto)));
2090 }
2091
2092
2093 void print_aliases()
2094 {
2095         struct host_alias* a;
2096
2097         for(a=aliases; a; a=a->next) {
2098                 if (a->port) {
2099                         printf("             %s: %.*s:%d\n", get_valid_proto_name(a->proto),
2100                                         a->alias.len, a->alias.s, a->port);
2101                 } else {
2102                         printf("             %s: %.*s:*\n", get_valid_proto_name(a->proto),
2103                                         a->alias.len, a->alias.s);
2104                 }
2105         }
2106 }
2107
2108
2109
2110 void init_proto_order()
2111 {
2112         int r;
2113
2114         /* fix proto list  (remove disabled protocols)*/
2115 #ifdef USE_TCP
2116         if (tcp_disable)
2117 #endif
2118                 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2119                         if (nxt_proto[r]==PROTO_TCP)
2120                                 nxt_proto[r]=nxt_proto[PROTO_TCP];
2121                 }
2122 #ifdef USE_TCP
2123 #ifdef USE_TLS
2124         if (tls_disable || tcp_disable)
2125 #endif
2126 #endif
2127                 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2128                         if (nxt_proto[r]==PROTO_TLS)
2129                                 nxt_proto[r]=nxt_proto[PROTO_TLS];
2130                 }
2131 #ifdef USE_SCTP
2132         if (sctp_disable)
2133 #endif
2134                 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2135                         if (nxt_proto[r]==PROTO_SCTP)
2136                                 nxt_proto[r]=nxt_proto[PROTO_SCTP];
2137                 }
2138
2139         /* Deliberately skipping PROTO_WS and PROTO_WSS here as these
2140            are just upgraded TCP and TLS connections */
2141 }
2142
2143
2144 /**
2145  * parse '[port:]host[:port]' string to a broken down structure
2146  */
2147 int parse_protohostport(str* ins, sr_phostp_t *r)
2148 {
2149         char* first; /* first ':' occurrence */
2150         char* second; /* second ':' occurrence */
2151         char* p;
2152         int bracket;
2153         str tmp=STR_NULL;
2154
2155         first=second=0;
2156         bracket=0;
2157         memset(r, 0, sizeof(sr_phostp_t));
2158
2159         /* find the first 2 ':', ignoring possible ipv6 addresses
2160          * (substrings between [])
2161          */
2162         for(p=ins->s; p<ins->s+ins->len; p++){
2163                 switch(*p){
2164                         case '[':
2165                                 bracket++;
2166                                 if (bracket>1) goto error_brackets;
2167                                 break;
2168                         case ']':
2169                                 bracket--;
2170                                 if (bracket<0) goto error_brackets;
2171                                 break;
2172                         case ':':
2173                                 if (bracket==0){
2174                                         if (first==0) first=p;
2175                                         else if( second==0) second=p;
2176                                         else goto error_colons;
2177                                 }
2178                                 break;
2179                 }
2180         }
2181         if (p==ins->s) return -1;
2182         if (*(p-1)==':') goto error_colons;
2183
2184         if (first==0) { /* no ':' => only host */
2185                 r->host.s=ins->s;
2186                 r->host.len=(int)(p-ins->s);
2187                 goto end;
2188         }
2189         if (second) { /* 2 ':' found => check if valid */
2190                 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2191                         goto error_proto;
2192
2193                 tmp.s=second+1;
2194                 tmp.len=(ins->s + ins->len) - tmp.s;
2195
2196                 if (str2int(&tmp, (unsigned int *)&(r->port))<0) goto error_port;
2197
2198                 r->host.s=first+1;
2199                 r->host.len=(int)(second-r->host.s);
2200                 goto end;
2201         }
2202         /* only 1 ':' found => it's either proto:host or host:port */
2203         tmp.s=first+1;
2204         tmp.len=(ins->s + ins->len) - tmp.s;
2205         if (str2int(&tmp, (unsigned int *)&(r->port))<0) {
2206                 /* invalid port => it's proto:host */
2207                 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2208                         goto error_proto;
2209                 r->host.s=first+1;
2210                 r->host.len=(int)(p-r->host.s);
2211         }else{
2212                 /* valid port => its host:port */
2213                 r->host.s=ins->s;
2214                 r->host.len=(int)(first-r->host.s);
2215         }
2216 end:
2217         return 0;
2218 error_brackets:
2219         LM_ERR("too many brackets in %.*s\n", ins->len, ins->s);
2220         return -1;
2221 error_colons:
2222         LM_ERR("too many colons in %.*s\n", ins->len, ins->s);
2223         return -1;
2224 error_proto:
2225         LM_ERR("bad protocol in %.*s\n", ins->len, ins->s);
2226         return -1;
2227 error_port:
2228         LM_ERR("bad port number in %.*s\n", ins->len, ins->s);
2229         return -1;
2230 }
2231
2232 /**
2233  * lookup a local socket by '[port:]host[:port]' string
2234  */
2235 struct socket_info* lookup_local_socket(str *phostp)
2236 {
2237         sr_phostp_t r;
2238         if(parse_protohostport(phostp, &r)<0)
2239                 return NULL;
2240         return grep_sock_info(&r.host, (unsigned short)r.port,
2241                         (unsigned short)r.proto);
2242 }