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