4 * find & manage listen addresses
6 * Copyright (C) 2001-2003 FhG Fokus
8 * This file is part of ser, a free SIP server.
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
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:
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.
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
30 * This file contains code that initializes and handles ser listen addresses
31 * lists (struct socket_info). It is used mainly on startup.
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)
48 * \brief SIP-router core ::
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <sys/utsname.h>
61 #include <sys/ioctl.h>
63 #ifdef HAVE_SYS_SOCKIO_H
64 #include <sys/sockio.h>
68 #include "socket_info.h"
73 #include "name_alias.h"
77 /* list manip. functions (internal use only) */
81 #define sock_listadd(head, el) \
83 if (*(head)==0) *(head)=(el); \
85 for((el)->next=*(head); (el)->next->next;\
86 (el)->next=(el)->next->next); \
87 (el)->next->next=(el); \
88 (el)->prev=(el)->next; \
94 /* insert after "after" */
95 #define sock_listins(el, 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 */ \
104 (el)->next=(el)->prev=0; \
109 #define sock_listrm(head, el) \
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; \
117 #define addr_info_listadd sock_listadd
118 #define addr_info_listins sock_listins
119 #define addr_info_listrm sock_listrm
121 inline static void addr_info_list_ins_lst(struct addr_info* lst,
122 struct addr_info* after)
132 for(l=lst; l->next; l=l->next);
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 };
146 /* another helper function, it just fills a struct addr_info
147 * returns: 0 on success, -1 on error*/
148 static int init_addr_info(struct addr_info* a,
149 char* name, enum si_flags flags)
152 memset(a, 0, sizeof(*a));
153 a->name.len=strlen(name);
154 a->name.s=pkg_malloc(a->name.len+1); /* include \0 */
155 if (a->name.s==0) goto error;
156 memcpy(a->name.s, name, a->name.len+1);
160 LOG(L_ERR, "ERROR: init_addr_info: memory allocation error\n");
166 /* returns 0 on error, new addr_info_lst element on success */
167 static inline struct addr_info* new_addr_info(char* name,
170 struct addr_info* al;
172 al=pkg_malloc(sizeof(*al));
173 if (al==0) goto error;
176 if (init_addr_info(al, name, gf)!=0) goto error;
179 LOG(L_ERR, "ERROR: new_addr_info: memory allocation error\n");
181 if (al->name.s) pkg_free(al->name.s);
189 static inline void free_addr_info(struct addr_info* a)
202 static inline void free_addr_info_lst(struct addr_info** lst)
205 struct addr_info* tmp;
217 /* adds a new add_info_lst element to the corresponding list
218 * returns 0 on success, -1 on error */
219 static int new_addr_info2list(char* name, enum si_flags f,
220 struct addr_info** l)
222 struct addr_info * al;
224 al=new_addr_info(name, f);
225 if (al==0) goto error;
226 addr_info_listadd(l, al);
234 /* another helper function, it just creates a socket_info struct */
235 static inline struct socket_info* new_sock_info( char* name,
236 struct name_lst* addr_l,
237 unsigned short port, unsigned short proto,
238 char *usename, unsigned short useport,
241 struct socket_info* si;
246 si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
247 if (si==0) goto error;
248 memset(si, 0, sizeof(struct socket_info));
250 si->name.len=strlen(name);
251 si->name.s=(char*)pkg_malloc(si->name.len+1); /* include \0 */
252 if (si->name.s==0) goto error;
253 memcpy(si->name.s, name, si->name.len+1);
254 /* set port & proto */
259 for (n=addr_l; n; n=n->next){
260 if (new_addr_info2list(n->name, n->flags, &si->addr_info_lst)!=0){
261 LOG(L_ERR, "ERROR: new_sockk_info:new_addr_info2list failed\n");
267 si->useinfo.name.len=strlen(usename);
268 si->useinfo.name.s=(char*)pkg_malloc(si->useinfo.name.len+1);
269 if (si->useinfo.name.s==0)
271 strcpy(si->useinfo.name.s, usename);
272 if(usename[0]=='[' && usename[si->useinfo.name.len-1]==']')
274 si->useinfo.address_str.len = si->useinfo.name.len - 2;
275 p = si->useinfo.name.s + 1;
277 si->useinfo.address_str.len = si->useinfo.name.len;
278 p = si->useinfo.name.s;
280 si->useinfo.address_str.s=(char*)pkg_malloc(si->useinfo.address_str.len+1);
281 if(si->useinfo.address_str.s==NULL)
283 strncpy(si->useinfo.address_str.s, p, si->useinfo.address_str.len);
284 si->useinfo.address_str.s[si->useinfo.address_str.len] = '\0';
286 p = int2str(useport, &si->useinfo.port_no_str.len);
289 si->useinfo.port_no_str.s=(char*)pkg_malloc(si->useinfo.port_no_str.len+1);
290 if(si->useinfo.port_no_str.s==NULL)
292 strcpy(si->useinfo.port_no_str.s, p);
293 si->useinfo.port_no = useport;
295 he=resolvehost(si->useinfo.name.s);
297 LM_ERR(" unable to resolve advertised name %s\n", si->useinfo.name.s);
300 hostent2ip_addr(&si->useinfo.address, he, 0);
304 LOG(L_ERR, "ERROR: new_sock_info: memory allocation error\n");
307 pkg_free(si->name.s);
315 /* delete a socket_info struct */
316 static void free_sock_info(struct socket_info* si)
319 if(si->name.s) pkg_free(si->name.s);
320 if(si->address_str.s) pkg_free(si->address_str.s);
321 if(si->port_no_str.s) pkg_free(si->port_no_str.s);
322 if(si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
323 if(si->sock_str.s) pkg_free(si->sock_str.s);
324 if(si->useinfo.name.s) pkg_free(si->useinfo.name.s);
325 if(si->useinfo.port_no_str.s) pkg_free(si->useinfo.port_no_str.s);
326 if(si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
332 static char* get_valid_proto_name(unsigned short proto)
356 /** Convert socket to its textual representation.
358 * This function converts the transport protocol, the IP address and the port
359 * number in a comma delimited string of form proto:ip:port. The resulting
360 * string is NOT zero terminated
362 * @param s is a pointer to the destination memory buffer
363 * @param len is a pointer to an integer variable. Initially the variable
364 * should contain the size of the buffer in s. The value of the variable
365 * will be changed to the length of the resulting string on success and
366 * to the desired size of the destination buffer if it is too small
367 * @param si is a pointer to the socket_info structure to be printed
368 * @return -1 on error and 0 on success
370 int socket2str(char* s, int* len, struct socket_info* si)
372 return socketinfo2str(s, len, si, 0);
375 int socketinfo2str(char* s, int* len, struct socket_info* si, int mode)
380 proto.s = get_valid_proto_name(si->proto);
381 proto.len = strlen(proto.s);
384 l = proto.len + si->useinfo.name.len + si->useinfo.port_no_str.len + 2;
386 l = proto.len + si->address_str.len + si->port_no_str.len + 2;
388 if(si->address.af==AF_INET6)
392 LM_ERR("Destionation buffer too short\n");
397 memcpy(s, proto.s, proto.len);
401 memcpy(s, si->useinfo.name.s, si->useinfo.name.len);
402 s += si->useinfo.name.len;
404 memcpy(s, si->useinfo.port_no_str.s, si->useinfo.port_no_str.len);
405 s += si->useinfo.port_no_str.len;
407 if(si->address.af==AF_INET6) {
410 memcpy(s, si->address_str.s, si->address_str.len);
411 s += si->address_str.len;
412 if(si->address.af==AF_INET6) {
416 memcpy(s, si->port_no_str.s, si->port_no_str.len);
417 s += si->port_no_str.len;
426 /* Fill si->sock_str with string representing the socket_info structure,
427 * format of the string is 'proto:address:port'. Returns 0 on success and
428 * negative number on failure.
430 static int fix_sock_str(struct socket_info* si)
432 int len = MAX_SOCKET_STR;
434 if (si->sock_str.s) pkg_free(si->sock_str.s);
436 si->sock_str.s = pkg_malloc(len + 1);
437 if (si->sock_str.s == NULL) {
438 ERR("fix_sock_str: No memory left\n");
441 if (socketinfo2str(si->sock_str.s, &len, si, 0) < 0) {
442 BUG("fix_sock_str: Error in socket to str\n");
445 si->sock_str.s[len] = '\0';
446 si->sock_str.len = len;
447 if(si->useinfo.name.s!=NULL)
449 len = MAX_SOCKET_STR;
451 if (si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
453 si->useinfo.sock_str.s = pkg_malloc(len + 1);
454 if (si->useinfo.sock_str.s == NULL) {
455 ERR("fix_sock_str: No memory left\n");
458 if (socketinfo2str(si->useinfo.sock_str.s, &len, si, 1) < 0) {
459 BUG("fix_sock_str: Error in socket to str\n");
462 si->useinfo.sock_str.s[len] = '\0';
463 si->useinfo.sock_str.len = len;
469 /* returns 0 if support for the protocol is not compiled or if proto is
471 struct socket_info** get_sock_info_list(unsigned short proto)
495 LOG(L_CRIT, "BUG: get_sock_info_list: invalid proto %d\n", proto);
501 /* helper function for grep_sock_info
503 * host - hostname to compare with
504 * name - official name
505 * addr_str - name's resolved ip address converted to string
506 * ip_addr - name's ip address
507 * flags - set to SI_IS_IP if name contains an IP
509 * returns 0 if host matches, -1 if not */
510 inline static int si_hname_cmp(str* host, str* name, str* addr_str,
511 struct ip_addr* ip_addr, int flags)
517 if ( (host->len==name->len) &&
518 (strncasecmp(host->s, name->s, name->len)==0) /*slower*/)
519 /* comp. must be case insensitive, host names
520 * can be written in mixed case, it will also match
521 * ipv6 addresses if we are lucky*/
523 /* check if host == ip address */
525 /* ipv6 case is uglier, host can be [3ffe::1] */
528 if (ip_addr_cmp(ip6, ip_addr))
529 goto found; /* match */
531 return -1; /* no match, but this is an ipv6 address
532 so no point in trying ipv4 */
536 if ( (!(flags&SI_IS_IP)) && (host->len==addr_str->len) &&
537 (memcmp(host->s, addr_str->s, addr_str->len)==0) )
545 /* checks if the proto: host:port is one of the address we listen on
546 * and returns the corresponding socket_info structure.
547 * if port==0, the port number is ignored
548 * if proto==0 (PROTO_NONE) the protocol is ignored
549 * returns 0 if not found
550 * WARNING: uses str2ip6 so it will overwrite any previous
551 * unsaved result of this function (static buffer)
553 struct socket_info* grep_sock_info(str* host, unsigned short port,
554 unsigned short proto)
557 struct socket_info* si;
558 struct socket_info** list;
559 struct addr_info* ai;
560 unsigned short c_proto;
564 if ((hname.len>2)&&((*hname.s)=='[')&&(hname.s[hname.len-1]==']')){
565 /* ipv6 reference, skip [] */
570 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
572 /* get the proper sock_list */
573 list=get_sock_info_list(c_proto);
575 if (list==0) /* disabled or unknown protocol */
577 for (si=*list; si; si=si->next){
578 DBG("grep_sock_info - checking if host==us: %d==%d &&"
579 " [%.*s] == [%.*s]\n",
583 si->name.len, si->name.s
586 DBG("grep_sock_info - checking if port %d (advertise %d)"
587 " matches port %d\n",
588 si->port_no, si->useinfo.port_no, port);
589 if (si->port_no!=port && si->useinfo.port_no!=port) {
593 if (si_hname_cmp(&hname, &si->name, &si->address_str,
594 &si->address, si->flags)==0)
596 if(si->useinfo.name.s!=NULL)
598 DBG("grep_sock_info - checking advertise if host==us:"
599 " %d==%d && [%.*s] == [%.*s]\n",
601 si->useinfo.name.len,
603 si->useinfo.name.len, si->useinfo.name.s
605 if (si_hname_cmp(&hname, &si->useinfo.name,
606 &si->useinfo.address_str, &si->useinfo.address,
610 /* try among the extra addresses */
611 for (ai=si->addr_info_lst; ai; ai=ai->next)
612 if (si_hname_cmp(&hname, &ai->name, &ai->address_str,
613 &ai->address, ai->flags)==0)
616 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
623 /* checks if the proto:port is one of the ports we listen on
624 * and returns the corresponding socket_info structure.
625 * if proto==0 (PROTO_NONE) the protocol is ignored
626 * returns 0 if not found
628 struct socket_info* grep_sock_info_by_port(unsigned short port,
629 unsigned short proto)
631 struct socket_info* si;
632 struct socket_info** list;
633 unsigned short c_proto;
638 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
640 /* get the proper sock_list */
641 list=get_sock_info_list(c_proto);
643 if (list==0) /* disabled or unknown protocol */
646 for (si=*list; si; si=si->next){
647 DBG("grep_sock_info_by_port - checking if port %d matches"
648 " port %d\n", si->port_no, port);
649 if (si->port_no==port) {
653 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
662 /* checks if the proto: ip:port is one of the address we listen on
663 * and returns the corresponding socket_info structure.
664 * (same as grep_socket_info, but use ip addr instead)
665 * if port==0, the port number is ignored
666 * if proto==0 (PROTO_NONE) the protocol is ignored
667 * returns 0 if not found
668 * WARNING: uses str2ip6 so it will overwrite any previous
669 * unsaved result of this function (static buffer)
671 struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
672 unsigned short proto)
674 struct socket_info* si;
675 struct socket_info** list;
676 struct addr_info* ai;
677 unsigned short c_proto;
679 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
681 /* get the proper sock_list */
682 list=get_sock_info_list(c_proto);
684 if (list==0) /* disabled or unknown protocol */
687 for (si=*list; si; si=si->next){
689 if (si->port_no!=port) {
693 if (ip_addr_cmp(ip, &si->address)
694 || ip_addr_cmp(ip, &si->useinfo.address))
696 for (ai=si->addr_info_lst; ai; ai=ai->next)
697 if (ip_addr_cmp(ip, &ai->address))
700 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
709 /* append a new sock_info structure to the corresponding list
710 * return new sock info on success, 0 on error */
711 static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
713 unsigned short proto,
714 char *usename, unsigned short useport,
716 struct socket_info** list)
718 struct socket_info* si;
720 si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
722 LOG(L_ERR, "ERROR: new_sock2list: new_sock_info failed\n");
725 if(socket_workers>0) {
726 si->workers = socket_workers;
729 sock_listadd(list, si);
737 /* adds a new sock_info structure immediately after "after"
738 * return new sock info on success, 0 on error */
739 static struct socket_info* new_sock2list_after(char* name,
740 struct name_lst* addr_l,
742 unsigned short proto,
744 unsigned short useport,
746 struct socket_info* after)
748 struct socket_info* si;
750 si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
752 LOG(L_ERR, "ERROR: new_sock2list_after: new_sock_info failed\n");
755 sock_listins(si, after);
763 /* adds a sock_info structure to the corresponding proto list
764 * return 0 on success, -1 on error */
765 int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
766 unsigned short port, unsigned short proto,
767 char *usename, unsigned short useport,
770 struct socket_info** list;
771 unsigned short c_proto;
772 struct name_lst* a_l;
773 unsigned short c_port;
775 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
777 list=get_sock_info_list(c_proto);
778 if (list==0) /* disabled or unknown protocol */
781 if (port==0){ /* use default port */
784 ((c_proto)==PROTO_TLS)?tls_port_no:
789 else if ((c_proto==PROTO_TLS) && (proto==0)){
790 /* -l ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1?*/
797 if (c_proto!=PROTO_SCTP){
798 if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
799 flags & ~SI_IS_MHOMED, list)==0){
800 LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
803 /* add the other addresses in the list as separate sockets
804 * since only SCTP can bind to multiple addresses */
805 for (a_l=addr_l; a_l; a_l=a_l->next){
806 if (new_sock2list(a_l->name, 0, c_port,
807 c_proto, usename, useport,
808 flags & ~SI_IS_MHOMED, list)==0){
809 LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list"
815 if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
817 LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
821 }while( (proto==0) && (c_proto=next_proto(c_proto)));
827 /* adds a sock_info structure to the corresponding proto list
828 * return 0 on success, -1 on error */
829 int add_listen_iface(char* name, struct name_lst* addr_l,
830 unsigned short port, unsigned short proto,
833 return add_listen_advertise_iface(name, addr_l, port, proto, 0, 0, flags);
837 #include "linux/netlink.h"
838 #include "linux/rtnetlink.h"
839 #include "arpa/inet.h"
842 #define MAX_IF_LEN 64
848 char addr[MAX_IF_LEN];
853 struct idx* addresses;
855 char name[MAX_IF_LEN];
859 #define MAX_IFACE_NO 32
861 static struct idxlist *ifaces = NULL;
864 #define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
866 #define NLMSG_TAIL(nmsg) \
867 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
869 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
872 int len = RTA_LENGTH(alen);
875 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
876 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
880 rta->rta_type = type;
882 memcpy(RTA_DATA(rta), data, alen);
883 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
889 static int nl_bound_sock(void)
892 struct sockaddr_nl la;
894 sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
896 LM_ERR("could not create NETLINK sock to get interface list");
900 /* bind NETLINK socket to pid */
901 bzero(&la, sizeof(la));
902 la.nl_family = AF_NETLINK;
904 la.nl_pid = getpid();
906 if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
907 LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
913 if(sock > 0) close(sock);
917 #define fill_nl_req(req, type, family) do {\
918 memset(&req, 0, sizeof(req));\
919 req.nlh.nlmsg_len = sizeof(req);\
920 req.nlh.nlmsg_type = type;\
921 req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP;\
922 req.nlh.nlmsg_pid = getpid();\
923 req.nlh.nlmsg_seq = seq++;\
924 req.g.rtgen_family = family;\
928 static int get_flags(int family){
934 struct nlmsghdr* nlp;
935 struct ifinfomsg *ifi;
941 fill_nl_req(req, RTM_GETLINK, AF_INET);
943 if((nl_sock = nl_bound_sock()) < 0) return -1;
945 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0)
947 LM_ERR("error sending NETLINK request\n");
952 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
953 nlp = (struct nlmsghdr *) p;
954 if(nlp->nlmsg_type == NLMSG_DONE){
958 if(nlp->nlmsg_type == NLMSG_ERROR){
959 LM_DBG("Error on message to netlink");
967 nlp = (struct nlmsghdr *) buf;
968 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
969 ifi = NLMSG_DATA(nlp);
971 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
974 LM_ERR("Interface with index %d has flags %d\n", ifi->ifi_index, ifi->ifi_flags);
976 LM_ERR("get_flags must not be called on empty interface list");
979 if(ifi->ifi_index >= MAX_IFACE_NO){
980 LM_ERR("invalid network interface index returned %d", ifi->ifi_index);
983 ifaces[ifi->ifi_index].flags = ifi->ifi_flags;
986 if(nl_sock>0) close(nl_sock);
990 if(nl_sock>0) close(nl_sock);
994 static int build_iface_list(void)
1003 struct nlmsghdr* nlp;
1004 struct ifaddrmsg *ifi;
1009 struct rtattr * rtap;
1014 int families[] = {AF_INET, AF_INET6};
1015 char name[MAX_IF_LEN];
1016 int is_link_local = 0;
1019 if((ifaces = (struct idxlist*)pkg_malloc(MAX_IFACE_NO*sizeof(struct idxlist))) == NULL){
1020 LM_ERR("No more pkg memory\n");
1023 memset(ifaces, 0, sizeof(struct idxlist)*MAX_IFACE_NO);
1026 /* bind netlink socket */
1027 if((nl_sock = nl_bound_sock()) < 0) return -1;
1029 for (i = 0 ; i < sizeof(families)/sizeof(int); i++) {
1030 fill_nl_req(req, RTM_GETADDR, families[i]);
1032 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0){
1033 LM_ERR("error sending NETLINK request\n");
1037 memset(buf, 0, sizeof(buf));
1041 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1042 LM_DBG("received %d byles \n", rtn);
1043 nlp = (struct nlmsghdr *) p;
1044 if(nlp->nlmsg_type == NLMSG_DONE){
1045 LM_DBG("done receiving netlink info \n");
1048 if(nlp->nlmsg_type == NLMSG_ERROR){
1049 LM_ERR("Error on message to netlink");
1057 nlp = (struct nlmsghdr *) buf;
1058 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1059 ifi = NLMSG_DATA(nlp);
1061 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1063 // init all the strings
1064 // inner loop: loop thru all the attributes of
1066 rtap = (struct rtattr *) IFA_RTA(ifi);
1068 rtl = IFA_PAYLOAD(nlp);
1070 index = ifi->ifa_index;
1071 if(index >= MAX_IFACE_NO){
1072 LM_ERR("Invalid interface index returned: %d\n", index);
1076 entry = (struct idx*)pkg_malloc(sizeof(struct idx));
1079 LM_ERR("could not allocate memory\n");
1084 entry->family = families[i];
1085 entry->ifa_flags = ifi->ifa_flags;
1088 for(;RTA_OK(rtap, rtl);rtap=RTA_NEXT(rtap,rtl)){
1089 switch(rtap->rta_type){
1091 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1092 LM_DBG("Link Local Address, ignoring ...\n");
1096 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1097 LM_DBG("iface <IFA_ADDRESS> addr is %s\n", entry->addr);
1100 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1101 LM_DBG("Link Local Address, ignoring ...\n");
1104 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1105 LM_DBG("iface <IFA_LOCAL> addr is %s\n", entry->addr);
1108 LM_DBG("iface name is %s\n", (char*)RTA_DATA(rtap));
1109 strncpy(name, (char*)RTA_DATA(rtap), MAX_IF_LEN);
1119 if(is_link_local) continue; /* link local addresses are not bindable */
1121 if(strlen(ifaces[index].name)==0)
1122 strncpy(ifaces[index].name, name, MAX_IF_LEN);
1124 ifaces[index].index = index;
1126 if(ifaces[index].addresses == 0 )
1127 ifaces[index].addresses = entry;
1129 for(tmp = ifaces[index].addresses; tmp->next ; tmp = tmp->next)/*empty*/;
1134 if(nl_sock>0) close(nl_sock);
1135 /* the socket should be closed so we can bind again */
1136 for(i = 0; i < sizeof(families)/sizeof(int); i++){
1137 /* get device flags */
1138 get_flags(families[i]); /* AF_INET or AF_INET6 */
1143 if(nl_sock>0) close(nl_sock);
1147 /* add all family type addresses of interface if_to the socket_info array
1148 * if if_name==0, adds all addresses on all interfaces
1149 * uses RTNETLINK sockets to get addresses on the present interface on LINUX
1150 * return: -1 on error, 0 on success
1152 int add_interfaces_via_netlink(char* if_name, int family, unsigned short port,
1153 unsigned short proto,
1154 struct addr_info** ai_l)
1158 enum si_flags flags;
1160 if(ifaces == NULL && (build_iface_list()!=0)){
1161 LM_ERR("Could not get network interface list\n");
1166 for(i=0; i< MAX_IFACE_NO; ++i){
1167 if(ifaces[i].addresses == NULL) continue; /* not present/configured */
1169 (strncmp(if_name, ifaces[i].name, strlen(ifaces[i].name))==0)){
1171 /* check if iface is up */
1172 //if(! (ifaces[i].flags & IFF_UP) ) continue;
1174 for(tmp = ifaces[i].addresses; tmp; tmp = tmp->next){
1175 LM_DBG("\t in add_iface_via_netlink Name %s Address %s\n", ifaces[i].name, tmp->addr);
1177 if (family == tmp->family){
1178 /* check if loopback */
1179 if (ifaces[i].flags & IFF_LOOPBACK){
1180 LM_DBG("INTERFACE %s is loopback", ifaces[i].name);
1184 if (new_addr_info2list(tmp->addr, flags, ai_l)!=0){
1185 LOG(L_ERR, "ERROR: add_interfaces: "
1186 "new_addr_info2list failed\n");
1197 #endif /* __OS_linux */
1199 /* add all family type addresses of interface if_name to the socket_info array
1200 * if if_name==0, adds all addresses on all interfaces
1201 * WARNING: it only works with ipv6 addresses on FreeBSD
1202 * return: -1 on error, 0 on success
1204 int add_interfaces(char* if_name, int family, unsigned short port,
1205 unsigned short proto,
1206 struct addr_info** ai_l)
1210 struct ifreq ifrcopy;
1217 struct ip_addr addr;
1219 enum si_flags flags;
1221 #ifdef HAVE_SOCKADDR_SA_LEN
1223 #define MAX(a,b) ( ((a)>(b))?(a):(b))
1226 /* ipv4 or ipv6 only*/
1228 s=socket(family, SOCK_DGRAM, 0);
1232 for (size=100; ; size*=2){
1233 ifc.ifc_len=size*sizeof(struct ifreq);
1234 ifc.ifc_req=(struct ifreq*) pkg_malloc(size*sizeof(struct ifreq));
1235 if (ifc.ifc_req==0){
1236 LOG(L_ERR, "ERROR: add_interfaces: memory allocation failure\n");
1239 if (ioctl(s, SIOCGIFCONF, &ifc)==-1){
1240 if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
1241 LOG(L_ERR, "ERROR: add_interfaces: ioctl failed: %s\n",
1245 if ((lastlen) && (ifc.ifc_len==lastlen)) break; /*success,
1247 lastlen=ifc.ifc_len;
1248 /* try a bigger array*/
1249 pkg_free(ifc.ifc_req);
1252 last=(char*)ifc.ifc_req+ifc.ifc_len;
1253 for(p=(char*)ifc.ifc_req; p<last;
1256 sizeof(ifr) /* works on x86_64 too */
1258 (sizeof(ifr.ifr_name)+
1259 #ifdef HAVE_SOCKADDR_SA_LEN
1260 MAX(ifr.ifr_addr.sa_len, sizeof(struct sockaddr))
1262 ( (ifr.ifr_addr.sa_family==AF_INET)?
1263 sizeof(struct sockaddr_in):
1265 ((ifr.ifr_addr.sa_family==AF_INET6)?
1266 sizeof(struct sockaddr_in6):sizeof(struct sockaddr)) )
1267 #else /* USE_IPV6 */
1268 sizeof(struct sockaddr) )
1269 #endif /* USE_IPV6 */
1275 /* copy contents into ifr structure
1276 * warning: it might be longer (e.g. ipv6 address) */
1277 memcpy(&ifr, p, sizeof(ifr));
1278 if (ifr.ifr_addr.sa_family!=family){
1279 /*printf("strange family %d skipping...\n",
1280 ifr->ifr_addr.sa_family);*/
1286 if (ioctl(s, SIOCGIFFLAGS, &ifrcopy)!=-1){ /* ignore errors */
1287 /* ignore down ifs only if listening on all of them*/
1289 /* if if not up, skip it*/
1290 if (!(ifrcopy.ifr_flags & IFF_UP)) continue;
1297 (strncmp(if_name, ifr.ifr_name, sizeof(ifr.ifr_name))==0)){
1300 sockaddr2ip_addr(&addr,
1301 (struct sockaddr*)(p+(long)&((struct ifreq*)0)->ifr_addr));
1302 if ((tmp=ip_addr2a(&addr))==0) goto error;
1303 /* check if loopback */
1304 if (ifrcopy.ifr_flags & IFF_LOOPBACK)
1307 if (new_addr_info2list(tmp, flags, ai_l)!=0){
1308 LOG(L_ERR, "ERROR: add_interfaces: "
1309 "new_addr_info2list failed\n");
1315 printf("%s:\n", ifr->ifr_name);
1317 print_sockaddr(&(ifr->ifr_addr));
1319 ls_ifflags(ifr->ifr_name, family, options);
1322 pkg_free(ifc.ifc_req); /*clean up*/
1326 if (ifc.ifc_req) pkg_free(ifc.ifc_req);
1333 /* internal helper function: resolve host names and add aliases
1334 * name is a value result parameter: it should contain the hostname that
1335 * will be used to fill all the other members, including name itself
1336 * in some situation (name->s should be a 0 terminated pkg_malloc'ed string)
1337 * return 0 on success and -1 on error */
1338 static int fix_hostname(str* name, struct ip_addr* address, str* address_str,
1339 enum si_flags* flags, int* type_flags,
1340 struct socket_info* s)
1346 /* get "official hostnames", all the aliases etc. */
1347 he=resolvehost(name->s);
1349 LOG(L_ERR, "ERROR: fix_hostname: could not resolve %s\n", name->s);
1352 /* check if we got the official name */
1353 if (strcasecmp(he->h_name, name->s)!=0){
1354 if (sr_auto_aliases &&
1355 add_alias(name->s, name->len, s->port_no, s->proto)<0){
1356 LOG(L_ERR, "ERROR: fix_hostname: add_alias failed\n");
1358 /* change the official name */
1360 name->s=(char*)pkg_malloc(strlen(he->h_name)+1);
1362 LOG(L_ERR, "ERROR: fix_hostname: out of memory.\n");
1365 name->len=strlen(he->h_name);
1366 strncpy(name->s, he->h_name, name->len+1);
1368 /* add the aliases*/
1369 for(h=he->h_aliases; sr_auto_aliases && h && *h; h++)
1370 if (add_alias(*h, strlen(*h), s->port_no, s->proto)<0){
1371 LOG(L_ERR, "ERROR: fix_hostname: add_alias failed\n");
1373 hostent2ip_addr(address, he, 0); /*convert to ip_addr format*/
1375 *type_flags|=(address->af==AF_INET)?SOCKET_T_IPV4:SOCKET_T_IPV6;
1377 if ((tmp=ip_addr2a(address))==0) goto error;
1378 address_str->s=pkg_malloc(strlen(tmp)+1);
1379 if (address_str->s==0){
1380 LOG(L_ERR, "ERROR: fix_hostname: out of memory.\n");
1383 strncpy(address_str->s, tmp, strlen(tmp)+1);
1384 /* set is_ip (1 if name is an ip address, 0 otherwise) */
1385 address_str->len=strlen(tmp);
1386 if (sr_auto_aliases && (address_str->len==name->len) &&
1387 (strncasecmp(address_str->s, name->s, address_str->len)==0)){
1389 /* do rev. DNS on it (for aliases)*/
1390 he=rev_resolvehost(address);
1392 LOG(L_WARN, "WARNING: fix_hostname: could not rev. resolve %s\n",
1395 /* add the aliases*/
1396 if (add_alias(he->h_name, strlen(he->h_name), s->port_no,
1398 LOG(L_ERR, "ERROR: fix_hostname: add_alias failed\n");
1400 for(h=he->h_aliases; h && *h; h++)
1401 if (add_alias(*h, strlen(*h), s->port_no, s->proto) < 0){
1402 LOG(L_ERR, "ERROR: fix_hostname: add_alias failed\n");
1408 /* Check if it is an multicast address and
1409 * set the flag if so
1411 if (is_mcast(address)){
1412 *flags |= SI_IS_MCAST;
1414 #endif /* USE_MCAST */
1416 /* check if INADDR_ANY */
1417 if (ip_addr_any(address))
1419 else if (ip_addr_loopback(address)) /* check for loopback */
1429 /* append new elements to a socket_info list after "list"
1430 * each element is created from addr_info_lst + port, protocol and flags
1431 * return 0 on succes, -1 on error
1433 static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
1434 char proto, enum si_flags flags,
1435 struct socket_info** list)
1437 struct addr_info* ail;
1439 for (ail=ai_lst; ail; ail=ail->next){
1440 if(new_sock2list(ail->name.s, 0, port, proto, 0, 0,
1441 ail->flags | flags, list)==0)
1449 /* insert new elements to a socket_info list after "el",
1450 * each element is created from addr_info_lst + port, * protocol and flags
1451 * return 0 on succes, -1 on error
1453 static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
1454 unsigned short port,
1455 char proto, enum si_flags flags,
1456 struct socket_info* el)
1458 struct addr_info* ail;
1459 struct socket_info* new_si;
1461 for (ail=ai_lst; ail; ail=ail->next){
1462 if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
1463 0, 0, ail->flags | flags, el))==0)
1472 /* fixes a socket list => resolve addresses,
1473 * interface names, fills missing members, remove duplicates
1474 * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
1475 static int fix_socket_list(struct socket_info **list, int* type_flags)
1477 struct socket_info* si;
1478 struct socket_info* new_si;
1479 struct socket_info* l;
1480 struct socket_info* next;
1481 struct socket_info* next_si;
1482 struct socket_info* del_si;
1483 struct socket_info* keep_si;
1486 struct addr_info* ai_lst;
1487 struct addr_info* ail;
1488 struct addr_info* tmp_ail;
1489 struct addr_info* tmp_ail_next;
1490 struct addr_info* ail_next;
1494 /* try to change all the interface names into addresses
1499 if (add_interfaces(si->name.s, AF_INET, si->port_no,
1500 si->proto, &ai_lst)!=-1){
1501 if (si->flags & SI_IS_MHOMED){
1502 if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
1503 si->proto, si->useinfo.name.s,
1504 si->useinfo.port_no,
1505 ai_lst->flags|si->flags, si))==0)
1508 ai_lst=ai_lst->next;
1509 free_addr_info(ail); /* free the first elem. */
1513 for (ail=ai_lst; ail->next; ail=ail->next);
1514 /* add the mh list after the last position in ai_lst */
1515 addr_info_list_ins_lst(si->addr_info_lst, ail);
1516 new_si->addr_info_lst=ai_lst;
1517 si->addr_info_lst=0; /* detached and moved to new_si */
1518 ail=ail->next; /* ail== old si->addr_info_lst */
1520 ail=si->addr_info_lst;
1521 new_si->addr_info_lst=ail;
1522 si->addr_info_lst=0; /* detached and moved to new_si */
1526 /* add all addr. as separate interfaces */
1527 if (addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto,
1530 /* ai_lst not needed anymore */
1531 free_addr_info_lst(&ai_lst);
1535 /* success => remove current entry (shift the entire array)*/
1536 sock_listrm(list, si);
1540 ail=si->addr_info_lst;
1544 if (new_si && (new_si->flags & SI_IS_MHOMED)){
1548 if (add_interfaces(ail->name.s, AF_INET, new_si->port_no,
1549 new_si->proto, &ai_lst)!=-1){
1550 /* add the resolved list after the current position */
1551 addr_info_list_ins_lst(ai_lst, ail);
1552 /* success, remove the current entity */
1553 addr_info_listrm(&new_si->addr_info_lst, ail);
1554 free_addr_info(ail);
1563 /* get ips & fill the port numbers*/
1565 DBG("Listening on \n");
1567 for (si=*list;si;si=si->next){
1568 /* fix port number, port_no should be !=0 here */
1569 if (si->port_no==0){
1571 si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
1573 si->port_no= port_no;
1576 tmp=int2str(si->port_no, &len);
1577 if (len>=MAX_PORT_LEN){
1578 LOG(L_ERR, "ERROR: fix_socket_list: bad port number: %d\n",
1582 si->port_no_str.s=(char*)pkg_malloc(len+1);
1583 if (si->port_no_str.s==0){
1584 LOG(L_ERR, "ERROR: fix_socket_list: out of memory.\n");
1587 strncpy(si->port_no_str.s, tmp, len+1);
1588 si->port_no_str.len=len;
1590 if (fix_hostname(&si->name, &si->address, &si->address_str,
1591 &si->flags, type_flags, si) !=0 )
1593 /* fix hostnames in mh addresses */
1594 for (ail=si->addr_info_lst; ail; ail=ail->next){
1595 if (fix_hostname(&ail->name, &ail->address, &ail->address_str,
1596 &ail->flags, type_flags, si) !=0 )
1600 if (fix_sock_str(si) < 0) goto error;
1603 printf(" %.*s [%s]:%s%s\n", si->name.len,
1604 si->name.s, si->address_str.s, si->port_no_str.s,
1605 si->flags & SI_IS_MCAST ? " mcast" : "");
1608 /* removing duplicate addresses*/
1609 for (si=*list;si; ){
1611 for (l=si->next;l;){
1613 if ((si->port_no==l->port_no) &&
1614 (si->address.af==l->address.af) &&
1615 (memcmp(si->address.u.addr, l->address.u.addr,
1616 si->address.len) == 0)
1618 /* remove the socket with no extra addresses.,
1619 * if both of them have extra addresses, remove one of them
1620 * and merge the extra addresses into the other */
1621 if (l->addr_info_lst==0){
1624 }else if (si->addr_info_lst==0){
1628 /* move l->addr_info_lst to si->addr_info_lst */
1629 /* find last elem */
1630 for (ail=si->addr_info_lst; ail->next; ail=ail->next);
1631 /* add the l list after the last position in si lst */
1632 addr_info_list_ins_lst(l->addr_info_lst, ail);
1633 l->addr_info_lst=0; /* detached */
1634 del_si=l; /* l will be removed */
1638 printf("removing duplicate %s [%s] == %s [%s]\n",
1639 keep_si->name.s, keep_si->address_str.s,
1640 del_si->name.s, del_si->address_str.s);
1642 /* add the name to the alias list*/
1643 if ((!(del_si->flags& SI_IS_IP)) && (
1644 (del_si->name.len!=keep_si->name.len)||
1645 (strncmp(del_si->name.s, keep_si->name.s,
1646 del_si->name.len)!=0))
1648 add_alias(del_si->name.s, del_si->name.len,
1649 l->port_no, l->proto);
1650 /* make sure next_si doesn't point to del_si */
1651 if (del_si==next_si)
1652 next_si=next_si->next;
1654 sock_listrm(list, del_si);
1655 free_sock_info(del_si);
1661 /* check for duplicates in extra_addresses */
1662 for (si=*list;si; si=si->next){
1663 /* check for & remove internal duplicates: */
1664 for (ail=si->addr_info_lst; ail;){
1666 /* 1. check if the extra addresses contain a duplicate for the
1668 if ((ail->address.af==si->address.af) &&
1669 (memcmp(ail->address.u.addr, si->address.u.addr,
1670 ail->address.len) == 0)){
1671 /* add the name to the alias list*/
1672 if ((!(ail->flags& SI_IS_IP)) && (
1673 (ail->name.len!=si->name.len)||
1674 (strncmp(ail->name.s, si->name.s, ail->name.len)!=0)))
1675 add_alias(ail->name.s, ail->name.len, si->port_no,
1678 addr_info_listrm(&si->addr_info_lst, ail);
1679 free_addr_info(ail);
1683 /* 2. check if the extra addresses contain a duplicates for
1684 * other addresses in the same list */
1685 for (tmp_ail=ail->next; tmp_ail;){
1686 tmp_ail_next=tmp_ail->next;
1687 if ((ail->address.af==tmp_ail->address.af) &&
1688 (memcmp(ail->address.u.addr, tmp_ail->address.u.addr,
1689 ail->address.len) == 0)){
1690 /* add the name to the alias list*/
1691 if ((!(tmp_ail->flags& SI_IS_IP)) && (
1692 (ail->name.len!=tmp_ail->name.len)||
1693 (strncmp(ail->name.s, tmp_ail->name.s,
1694 tmp_ail->name.len)!=0))
1696 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1697 si->port_no, si->proto);
1699 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1700 free_addr_info(tmp_ail);
1702 tmp_ail=tmp_ail_next;
1706 /* check for duplicates between extra addresses (e.g. sctp MH)
1707 * and other main addresses, on conflict remove the corresponding
1708 * extra addresses (another possible solution would be to join
1709 * the 2 si entries into one). */
1710 for (ail=si->addr_info_lst; ail;){
1712 for (l=*list;l; l=l->next){
1713 if (l==si) continue;
1714 if (si->port_no==l->port_no){
1715 if ((ail->address.af==l->address.af) &&
1716 (memcmp(ail->address.u.addr, l->address.u.addr,
1717 ail->address.len) == 0)){
1718 /* add the name to the alias list*/
1719 if ((!(ail->flags& SI_IS_IP)) && (
1720 (ail->name.len!=l->name.len)||
1721 (strncmp(ail->name.s, l->name.s, l->name.len)!=0))
1723 add_alias(ail->name.s, ail->name.len,
1724 l->port_no, l->proto);
1726 addr_info_listrm(&si->addr_info_lst, ail);
1727 free_addr_info(ail);
1730 /* check for duplicates with other extra addresses
1732 for (tmp_ail=l->addr_info_lst; tmp_ail; ){
1733 tmp_ail_next=tmp_ail->next;
1734 if ((ail->address.af==tmp_ail->address.af) &&
1735 (memcmp(ail->address.u.addr,
1736 tmp_ail->address.u.addr,
1737 ail->address.len) == 0)){
1738 /* add the name to the alias list*/
1739 if ((!(tmp_ail->flags& SI_IS_IP)) && (
1740 (ail->name.len!=tmp_ail->name.len)||
1741 (strncmp(ail->name.s, tmp_ail->name.s,
1742 tmp_ail->name.len)!=0))
1744 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1745 l->port_no, l->proto);
1747 addr_info_listrm(&l->addr_info_lst, tmp_ail);
1748 free_addr_info(tmp_ail);
1750 tmp_ail=tmp_ail_next;
1759 /* Remove invalid multicast entries */
1762 if ((si->proto == PROTO_TCP)
1764 || (si->proto == PROTO_TLS)
1765 #endif /* USE_TLS */
1767 || (si->proto == PROTO_SCTP)
1770 if (si->flags & SI_IS_MCAST){
1771 LOG(L_WARN, "WARNING: removing entry %s:%s [%s]:%s\n",
1772 get_valid_proto_name(si->proto), si->name.s,
1773 si->address_str.s, si->port_no_str.s);
1776 sock_listrm(list, l);
1779 ail=si->addr_info_lst;
1781 if (ail->flags & SI_IS_MCAST){
1782 LOG(L_WARN, "WARNING: removing mh entry %s:%s"
1784 get_valid_proto_name(si->proto), ail->name.s,
1785 ail->address_str.s, si->port_no_str.s);
1788 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1789 free_addr_info(tmp_ail);
1800 #endif /* USE_MCAST */
1807 int socket_types = 0;
1809 /* fix all 3 socket lists, fills socket_types if non-null
1810 * return 0 on success, -1 on error */
1811 int fix_all_socket_lists()
1813 struct utsname myname;
1815 struct addr_info* ai_lst;
1830 /* get all listening ipv4/ipv6 interfaces */
1831 if ( ( (add_interfaces(0, AF_INET, 0, PROTO_UDP, &ai_lst)==0)
1834 && (!auto_bind_ipv6 || add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0)
1836 && ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0, PROTO_UDP, &ai_lst) !=0 ) /* add_interface does not work for IPv6 on Linux */
1837 #endif /* __OS_linux */
1838 #endif /* USE_IPV6 */
1839 ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, &udp_listen)==0)){
1840 free_addr_info_lst(&ai_lst);
1842 /* if ok, try to add the others too */
1845 if ( ((add_interfaces(0, AF_INET, 0, PROTO_TCP, &ai_lst)!=0)
1848 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TCP, &ai_lst) != 0)
1850 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_TCP, &ai_lst) !=0 )
1851 #endif /* __OS_linux */
1852 #endif /* USE_IPV6 */
1853 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0,
1856 free_addr_info_lst(&ai_lst);
1860 if (((add_interfaces(0, AF_INET, 0, PROTO_TLS,
1864 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TLS, &ai_lst) != 0)
1866 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_TLS, &ai_lst)!=0)
1867 #endif /* __OS_linux */
1868 #endif /* USE_IPV6 */
1869 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0,
1873 free_addr_info_lst(&ai_lst);
1880 if (((add_interfaces(0, AF_INET, 0, PROTO_SCTP, &ai_lst)!=0)
1883 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1885 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1886 #endif /* __OS_linux */
1887 #endif /* USE_IPV6 */
1888 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0,
1891 free_addr_info_lst(&ai_lst);
1894 #endif /* USE_SCTP */
1896 /* if error fall back to get hostname */
1897 /* get our address, only the first one */
1898 if (uname (&myname) <0){
1899 LOG(L_ERR, "ERROR: fix_all_socket_lists: cannot determine"
1900 " hostname, try -l address\n");
1903 if (add_listen_iface(myname.nodename, 0, 0, 0, 0)!=0){
1904 LOG(L_ERR, "ERROR: fix_all_socket_lists: add_listen_iface "
1911 if (fix_socket_list(&udp_listen, &flags)!=0){
1912 LOG(L_ERR, "ERROR: fix_all_socket_lists: fix_socket_list"
1917 socket_types|=flags|SOCKET_T_UDP;
1921 if (!tcp_disable && (fix_socket_list(&tcp_listen, &flags)!=0)){
1922 LOG(L_ERR, "ERROR: fix_all_socket_lists: fix_socket_list"
1927 socket_types|=flags|SOCKET_T_TCP;
1931 if (!tls_disable && (fix_socket_list(&tls_listen, &flags)!=0)){
1932 LOG(L_ERR, "ERROR: fix_all_socket_lists: fix_socket_list"
1937 socket_types|=flags|SOCKET_T_TLS;
1943 if (!sctp_disable && (fix_socket_list(&sctp_listen, &flags)!=0)){
1944 LOG(L_ERR, "ERROR: fix_all_socket_lists: fix_socket_list"
1949 socket_types|=flags|SOCKET_T_SCTP;
1951 #endif /* USE_SCTP */
1963 LOG(L_ERR, "ERROR: fix_all_socket_lists: no listening sockets\n");
1968 if (ai_lst) free_addr_info_lst(&ai_lst);
1974 void print_all_socket_lists()
1976 struct socket_info *si;
1977 struct socket_info** list;
1978 struct addr_info* ai;
1979 unsigned short proto;
1984 list=get_sock_info_list(proto);
1985 for(si=list?*list:0; si; si=si->next){
1986 if (si->addr_info_lst){
1988 get_valid_proto_name(proto),
1990 for (ai=si->addr_info_lst; ai; ai=ai->next)
1991 printf(", %s", ai->address_str.s);
1992 printf("):%s%s%s\n",
1994 si->flags & SI_IS_MCAST ? " mcast" : "",
1995 si->flags & SI_IS_MHOMED? " mhomed" : "");
1998 get_valid_proto_name(proto),
2000 if (!si->flags & SI_IS_IP)
2001 printf(" [%s]", si->address_str.s);
2002 printf( ":%s%s%s\n",
2004 si->flags & SI_IS_MCAST ? " mcast" : "",
2005 si->flags & SI_IS_MHOMED? " mhomed" : "");
2008 }while((proto=next_proto(proto)));
2012 void print_aliases()
2014 struct host_alias* a;
2016 for(a=aliases; a; a=a->next)
2018 printf(" %s: %.*s:%d\n", get_valid_proto_name(a->proto),
2019 a->alias.len, a->alias.s, a->port);
2021 printf(" %s: %.*s:*\n", get_valid_proto_name(a->proto),
2022 a->alias.len, a->alias.s);
2027 void init_proto_order()
2031 /* fix proto list (remove disabled protocols)*/
2035 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2036 if (nxt_proto[r]==PROTO_TCP)
2037 nxt_proto[r]=nxt_proto[PROTO_TCP];
2041 if (tls_disable || tcp_disable)
2044 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2045 if (nxt_proto[r]==PROTO_TLS)
2046 nxt_proto[r]=nxt_proto[PROTO_TLS];
2051 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2052 if (nxt_proto[r]==PROTO_SCTP)
2053 nxt_proto[r]=nxt_proto[PROTO_SCTP];