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