3 * find & manage listen addresses
5 * Copyright (C) 2001-2003 FhG Fokus
7 * This file is part of Kamailio, a free SIP server.
9 * Kamailio is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version
14 * Kamailio is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 * \brief Kamailio core :: find & manage listen addresses
28 * This file contains code that initializes and handles Kamailio listen addresses
29 * lists (struct socket_info). It is used mainly on startup.
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <sys/utsname.h>
42 #include <sys/ioctl.h>
46 #ifdef HAVE_SYS_SOCKIO_H
47 #include <sys/sockio.h>
51 #include "socket_info.h"
56 #include "name_alias.h"
60 /* list manip. functions (internal use only) */
64 #define sock_listadd(head, el) \
66 if (*(head)==0) *(head)=(el); \
68 for((el)->next=*(head); (el)->next->next;\
69 (el)->next=(el)->next->next); \
70 (el)->next->next=(el); \
71 (el)->prev=(el)->next; \
77 /* insert after "after" */
78 #define sock_listins(el, after) \
81 (el)->next=(after)->next; \
82 if ((after)->next) (after)->next->prev=(el); \
85 }else{ /* after==0 = list head */ \
87 (el)->next=(el)->prev=0; \
92 #define sock_listrm(head, el) \
94 if (*(head)==(el)) *(head)=(el)->next; \
95 if ((el)->next) (el)->next->prev=(el)->prev; \
96 if ((el)->prev) (el)->prev->next=(el)->next; \
100 #define addr_info_listadd sock_listadd
101 #define addr_info_listins sock_listins
102 #define addr_info_listrm sock_listrm
105 * return the scope for IPv6 interface matching the ipval parameter
106 * - needed for binding to link local IPv6 addresses
108 unsigned int ipv6_get_netif_scope(char *ipval)
110 struct ifaddrs *netiflist = NULL;
111 struct ifaddrs *netif = NULL;
112 char ipaddr[NI_MAXHOST];
113 unsigned int iscope = 0;
116 ip_addr_t *ipa = NULL;
121 ips.len = strlen(ipval);
125 LM_ERR("could not parse ipv6 address: %s\n", ipval);
128 memcpy(&vaddr, ipa, sizeof(ip_addr_t));
131 /* walk over the list of all network interface addresses */
132 if(getifaddrs(&netiflist)!=0) {
133 LM_ERR("failed to get network interfaces - errno: %d\n", errno);
136 for(netif = netiflist; netif; netif = netif->ifa_next) {
137 /* only active and ipv6 */
138 if (netif->ifa_addr && (netif->ifa_flags & IFF_UP)
139 && netif->ifa_addr->sa_family==AF_INET6) {
140 r = getnameinfo(netif->ifa_addr, sizeof(struct sockaddr_in6),
141 ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST);
143 LM_ERR("failed to get the name info - ret: %d\n", r);
146 /* strip the interface name after */
147 for(i=0; ipaddr[i]; i++) {
154 ips.len = strlen(ipaddr);
157 /* if the ips match, get scope index from interface name */
158 if(ip_addr_cmp(&vaddr, ipa)) {
159 iscope=if_nametoindex(netif->ifa_name);
167 freeifaddrs(netiflist);
171 inline static void addr_info_list_ins_lst(struct addr_info* lst,
172 struct addr_info* after)
182 for(l=lst; l->next; l=l->next);
190 /* protocol order, filled by init_proto_order() */
191 enum sip_protos nxt_proto[PROTO_LAST+1]=
192 { PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, 0 };
193 /* Deliberately left PROTO_WS and PROTO_WSS out of this as they are just
194 upgraded TCP and TLS connections */
198 /* another helper function, it just fills a struct addr_info
199 * returns: 0 on success, -1 on error*/
200 static int init_addr_info(struct addr_info* a,
201 char* name, enum si_flags flags)
204 memset(a, 0, sizeof(*a));
205 a->name.len=strlen(name);
206 a->name.s=pkg_malloc(a->name.len+1); /* include \0 */
207 if (a->name.s==0) goto error;
208 memcpy(a->name.s, name, a->name.len+1);
218 /* returns 0 on error, new addr_info_lst element on success */
219 static inline struct addr_info* new_addr_info(char* name,
222 struct addr_info* al;
224 al=pkg_malloc(sizeof(*al));
225 if (al==0) goto error;
228 if (init_addr_info(al, name, gf)!=0) goto error;
233 if (al->name.s) pkg_free(al->name.s);
241 static inline void free_addr_info(struct addr_info* a)
254 static inline void free_addr_info_lst(struct addr_info** lst)
257 struct addr_info* tmp;
269 /* adds a new add_info_lst element to the corresponding list
270 * returns 0 on success, -1 on error */
271 static int new_addr_info2list(char* name, enum si_flags f,
272 struct addr_info** l)
274 struct addr_info * al;
276 al=new_addr_info(name, f);
277 if (al==0) goto error;
278 addr_info_listadd(l, al);
286 /* another helper function, it just creates a socket_info struct
287 * allocates a si and a si->name in new pkg memory */
288 static inline struct socket_info* new_sock_info( char* name,
289 struct name_lst* addr_l,
290 unsigned short port, unsigned short proto,
291 char *usename, unsigned short useport,
292 char *sockname, enum si_flags flags)
294 struct socket_info* si;
299 si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
300 if (si==0) goto error;
301 memset(si, 0, sizeof(struct socket_info));
303 si->name.len=strlen(name);
304 si->name.s=(char*)pkg_malloc(si->name.len+1); /* include \0 */
305 if (si->name.s==0) goto error;
306 memcpy(si->name.s, name, si->name.len+1);
307 /* set port & proto */
312 for (n=addr_l; n; n=n->next){
313 if (new_addr_info2list(n->name, n->flags, &si->addr_info_lst)!=0){
314 LM_ERR("new_addr_info2list failed\n");
319 si->sockname.len = strlen(sockname);
320 si->sockname.s=(char*)pkg_malloc(si->sockname.len+1); /* include \0 */
321 if (si->sockname.s==0) { goto error; }
322 memcpy(si->sockname.s, sockname, si->sockname.len+1);
326 si->useinfo.name.len=strlen(usename);
327 si->useinfo.name.s=(char*)pkg_malloc(si->useinfo.name.len+1);
328 if (si->useinfo.name.s==0)
330 strcpy(si->useinfo.name.s, usename);
331 if(usename[0]=='[' && usename[si->useinfo.name.len-1]==']')
333 si->useinfo.address_str.len = si->useinfo.name.len - 2;
334 p = si->useinfo.name.s + 1;
336 si->useinfo.address_str.len = si->useinfo.name.len;
337 p = si->useinfo.name.s;
339 si->useinfo.address_str.s=(char*)pkg_malloc(si->useinfo.address_str.len+1);
340 if(si->useinfo.address_str.s==NULL)
342 strncpy(si->useinfo.address_str.s, p, si->useinfo.address_str.len);
343 si->useinfo.address_str.s[si->useinfo.address_str.len] = '\0';
345 p = int2str(useport, &si->useinfo.port_no_str.len);
348 si->useinfo.port_no_str.s=(char*)pkg_malloc(si->useinfo.port_no_str.len+1);
349 if(si->useinfo.port_no_str.s==NULL)
351 strcpy(si->useinfo.port_no_str.s, p);
352 si->useinfo.port_no = useport;
354 he=resolvehost(si->useinfo.name.s);
356 LM_ERR("unable to resolve advertised name %s\n", si->useinfo.name.s);
359 hostent2ip_addr(&si->useinfo.address, he, 0);
366 pkg_free(si->name.s);
369 pkg_free(si->sockname.s);
378 /* delete a socket_info struct */
379 static void free_sock_info(struct socket_info* si)
382 if(si->name.s) pkg_free(si->name.s);
383 if(si->address_str.s) pkg_free(si->address_str.s);
384 if(si->port_no_str.s) pkg_free(si->port_no_str.s);
385 if(si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
386 if(si->sock_str.s) pkg_free(si->sock_str.s);
387 if(si->sockname.s) pkg_free(si->sockname.s);
388 if(si->useinfo.name.s) pkg_free(si->useinfo.name.s);
389 if(si->useinfo.port_no_str.s) pkg_free(si->useinfo.port_no_str.s);
390 if(si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
396 char* get_valid_proto_name(unsigned short proto)
420 /** Convert socket to its textual representation.
422 * This function converts the transport protocol, the IP address and the port
423 * number in a comma delimited string of form proto:ip:port. The resulting
424 * string is NOT zero terminated
426 * @param s is a pointer to the destination memory buffer
427 * @param len is a pointer to an integer variable. Initially the variable
428 * should contain the size of the buffer in s. The value of the variable
429 * will be changed to the length of the resulting string on success and
430 * to the desired size of the destination buffer if it is too small
431 * @param si is a pointer to the socket_info structure to be printed
432 * @return -1 on error and 0 on success
434 int socket2str(char* s, int* len, struct socket_info* si)
436 return socketinfo2str(s, len, si, 0);
439 int socketinfo2str(char* s, int* len, struct socket_info* si, int mode)
444 proto.s = get_valid_proto_name(si->proto);
445 proto.len = strlen(proto.s);
448 l = proto.len + si->useinfo.name.len + si->useinfo.port_no_str.len + 2;
450 l = proto.len + si->address_str.len + si->port_no_str.len + 2;
452 if(si->address.af==AF_INET6)
456 LM_ERR("Destionation buffer too short\n");
461 memcpy(s, proto.s, proto.len);
465 memcpy(s, si->useinfo.name.s, si->useinfo.name.len);
466 s += si->useinfo.name.len;
468 memcpy(s, si->useinfo.port_no_str.s, si->useinfo.port_no_str.len);
469 s += si->useinfo.port_no_str.len;
471 if(si->address.af==AF_INET6) {
474 memcpy(s, si->address_str.s, si->address_str.len);
475 s += si->address_str.len;
476 if(si->address.af==AF_INET6) {
480 memcpy(s, si->port_no_str.s, si->port_no_str.len);
481 s += si->port_no_str.len;
490 /* Fill si->sock_str with string representing the socket_info structure,
491 * format of the string is 'proto:address:port'. Returns 0 on success and
492 * negative number on failure.
494 static int fix_sock_str(struct socket_info* si)
496 int len = MAX_SOCKET_STR;
498 if (si->sock_str.s) pkg_free(si->sock_str.s);
500 si->sock_str.s = pkg_malloc(len + 1);
501 if (si->sock_str.s == NULL) {
505 if (socketinfo2str(si->sock_str.s, &len, si, 0) < 0) {
506 BUG("fix_sock_str: Error in socket to str\n");
509 si->sock_str.s[len] = '\0';
510 si->sock_str.len = len;
511 if(si->useinfo.name.s!=NULL)
513 len = MAX_SOCKET_ADVERTISE_STR;
515 if (si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
517 si->useinfo.sock_str.s = pkg_malloc(len + 1);
518 if (si->useinfo.sock_str.s == NULL) {
522 if (socketinfo2str(si->useinfo.sock_str.s, &len, si, 1) < 0) {
523 BUG("fix_sock_str: Error in socket to str\n");
526 si->useinfo.sock_str.s[len] = '\0';
527 si->useinfo.sock_str.len = len;
533 /* returns 0 if support for the protocol is not compiled or if proto is
535 struct socket_info** get_sock_info_list(unsigned short proto)
560 LM_CRIT("invalid proto %d\n", proto);
566 /* helper function for grep_sock_info
568 * host - hostname to compare with
569 * name - official name
570 * addr_str - name's resolved ip address converted to string
571 * ip_addr - name's ip address
572 * flags - set to SI_IS_IP if name contains an IP
574 * returns 0 if host matches, -1 if not */
575 inline static int si_hname_cmp(str* host, str* name, str* addr_str,
576 struct ip_addr* ip_addr, int flags)
580 if ( (host->len==name->len) &&
581 (strncasecmp(host->s, name->s, name->len)==0) /*slower*/)
582 /* comp. must be case insensitive, host names
583 * can be written in mixed case, it will also match
584 * ipv6 addresses if we are lucky*/
586 /* check if host == ip address */
587 /* ipv6 case is uglier, host can be [3ffe::1] */
590 if (ip_addr_cmp(ip6, ip_addr))
591 goto found; /* match */
593 return -1; /* no match, but this is an ipv6 address
594 so no point in trying ipv4 */
597 if ( (!(flags&SI_IS_IP)) && (host->len==addr_str->len) &&
598 (memcmp(host->s, addr_str->s, addr_str->len)==0) )
606 /* checks if the proto: host:port is one of the address we listen on
607 * and returns the corresponding socket_info structure.
608 * if port==0, the port number is ignored
609 * if proto==0 (PROTO_NONE) the protocol is ignored
610 * returns 0 if not found
611 * WARNING: uses str2ip6 so it will overwrite any previous
612 * unsaved result of this function (static buffer)
614 struct socket_info* grep_sock_info(str* host, unsigned short port,
615 unsigned short proto)
618 struct socket_info* si;
619 struct socket_info** list;
620 struct addr_info* ai;
621 unsigned short c_proto;
624 if ((hname.len>2)&&((*hname.s)=='[')&&(hname.s[hname.len-1]==']')){
625 /* ipv6 reference, skip [] */
630 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
633 /* get the proper sock_list */
634 list=get_sock_info_list(c_proto);
636 if (list==0) /* disabled or unknown protocol */
638 for (si=*list; si; si=si->next){
639 LM_DBG("checking if host==us: %d==%d && [%.*s] == [%.*s]\n",
643 si->name.len, si->name.s
646 LM_DBG("checking if port %d (advertise %d) matches port %d\n",
647 si->port_no, si->useinfo.port_no, port);
648 if (si->port_no!=port && si->useinfo.port_no!=port) {
652 if (si_hname_cmp(&hname, &si->name, &si->address_str,
653 &si->address, si->flags)==0)
655 if(si->useinfo.name.s!=NULL)
657 LM_DBG("checking advertise if host==us:"
658 " %d==%d && [%.*s] == [%.*s]\n",
660 si->useinfo.name.len,
662 si->useinfo.name.len, si->useinfo.name.s
664 if (si_hname_cmp(&hname, &si->useinfo.name,
665 &si->useinfo.address_str, &si->useinfo.address,
669 /* try among the extra addresses */
670 for (ai=si->addr_info_lst; ai; ai=ai->next)
671 if (si_hname_cmp(&hname, &ai->name, &ai->address_str,
672 &ai->address, ai->flags)==0)
676 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
679 if (unlikely(c_proto == PROTO_WS)) {
690 socket_info_t* ksr_get_socket_by_name(str *sockname)
692 socket_info_t *si = NULL;
693 struct socket_info** list;
694 unsigned short c_proto;
698 /* get the proper sock_list */
699 list=get_sock_info_list(c_proto);
702 /* disabled or unknown protocol */
706 for (si=*list; si; si=si->next) {
707 if(si->sockname.s == NULL) {
710 LM_DBG("checking if sockname %.*s matches %.*s\n",
711 sockname->len, sockname->s,
712 si->sockname.len, si->sockname.s);
713 if (sockname->len == si->sockname.len
714 && strncasecmp(sockname->s, si->sockname.s,
719 } while((c_proto = next_proto(c_proto))!=0);
724 /* checks if the proto:port is one of the ports we listen on
725 * and returns the corresponding socket_info structure.
726 * if proto==0 (PROTO_NONE) the protocol is ignored
727 * returns 0 if not found
729 struct socket_info* grep_sock_info_by_port(unsigned short port,
730 unsigned short proto)
732 struct socket_info* si;
733 struct socket_info** list;
734 unsigned short c_proto;
739 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
741 /* get the proper sock_list */
742 list=get_sock_info_list(c_proto);
744 if (list==0) /* disabled or unknown protocol */
747 for (si=*list; si; si=si->next){
748 LM_DBG("checking if port %d matches port %d\n", si->port_no, port);
749 if (si->port_no==port) {
753 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
762 /* checks if the proto: ip:port is one of the address we listen on
763 * and returns the corresponding socket_info structure.
764 * (same as grep_socket_info, but use ip addr instead)
765 * if port==0, the port number is ignored
766 * if proto==0 (PROTO_NONE) the protocol is ignored
767 * returns 0 if not found
768 * WARNING: uses str2ip6 so it will overwrite any previous
769 * unsaved result of this function (static buffer)
771 struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
772 unsigned short proto)
774 struct socket_info* si;
775 struct socket_info** list;
776 struct addr_info* ai;
777 unsigned short c_proto;
779 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
781 /* get the proper sock_list */
782 list=get_sock_info_list(c_proto);
784 if (list==0) /* disabled or unknown protocol */
787 for (si=*list; si; si=si->next){
789 if (si->port_no!=port) {
793 if (ip_addr_cmp(ip, &si->address)
794 || ip_addr_cmp(ip, &si->useinfo.address))
796 for (ai=si->addr_info_lst; ai; ai=ai->next)
797 if (ip_addr_cmp(ip, &ai->address))
800 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
809 /* append a new sock_info structure to the corresponding list
810 * return new sock info on success, 0 on error */
811 static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
813 unsigned short proto,
814 char *usename, unsigned short useport,
817 struct socket_info** list)
819 struct socket_info* si;
820 /* allocates si and si->name in new pkg memory */
821 si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
823 LM_ERR("new_sock_info failed\n");
826 if(socket_workers>0) {
827 si->workers = socket_workers;
832 si->mcast.len=strlen(mcast);
833 si->mcast.s=(char*)pkg_malloc(si->mcast.len+1);
834 if (si->mcast.s==0) {
836 pkg_free(si->name.s);
840 strcpy(si->mcast.s, mcast);
843 #endif /* USE_MCAST */
844 sock_listadd(list, si);
852 /* adds a new sock_info structure immediately after "after"
853 * return new sock info on success, 0 on error */
854 static struct socket_info* new_sock2list_after(char* name,
855 struct name_lst* addr_l,
857 unsigned short proto,
859 unsigned short useport,
862 struct socket_info* after)
864 struct socket_info* si;
866 si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
868 LM_ERR("new_sock_info failed\n");
871 sock_listins(si, after);
879 /* adds a sock_info structure to the corresponding proto list
880 * return 0 on success, -1 on error */
881 int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
882 unsigned short port, unsigned short proto,
883 char *usename, unsigned short useport, char *sockname,
886 struct socket_info** list;
887 unsigned short c_proto;
888 struct name_lst* a_l;
889 unsigned short c_port;
891 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
893 list=get_sock_info_list(c_proto);
894 if (list==0) /* disabled or unknown protocol */
897 if (port==0){ /* use default port */
900 ((c_proto)==PROTO_TLS)?tls_port_no:
905 else if ((c_proto==PROTO_TLS) && (proto==0)){
906 /* -l ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1?*/
913 if (c_proto!=PROTO_SCTP){
914 if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
915 sockname, flags & ~SI_IS_MHOMED, list)==0){
916 LM_ERR("new_sock2list failed\n");
919 /* add the other addresses in the list as separate sockets
920 * since only SCTP can bind to multiple addresses */
921 for (a_l=addr_l; a_l; a_l=a_l->next){
922 if (new_sock2list(a_l->name, 0, c_port,
923 c_proto, usename, useport, sockname,
924 flags & ~SI_IS_MHOMED, list)==0){
925 LM_ERR("new_sock2list failed\n");
930 if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
931 sockname, flags, list)==0){
932 LM_ERR("new_sock2list failed\n");
936 }while( (proto==0) && (c_proto=next_proto(c_proto)));
942 /* adds a sock_info structure to the corresponding proto list
943 * return 0 on success, -1 on error */
944 int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
945 unsigned short port, unsigned short proto,
946 char *usename, unsigned short useport,
949 return add_listen_advertise_iface_name(name, addr_l, port, proto,
950 usename, useport, NULL, flags);
953 /* adds a sock_info structure to the corresponding proto list
954 * return 0 on success, -1 on error */
955 int add_listen_iface(char* name, struct name_lst* addr_l,
956 unsigned short port, unsigned short proto,
959 return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0, 0,
963 /* adds a sock_info structure to the corresponding proto list
964 * return 0 on success, -1 on error */
965 int add_listen_iface_name(char* name, struct name_lst* addr_l,
966 unsigned short port, unsigned short proto, char *sockname,
969 return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0,
975 #include "linux/types.h"
976 #include "linux/netlink.h"
977 #include "linux/rtnetlink.h"
978 #include "arpa/inet.h"
981 #define MAX_IF_LEN 64
987 char addr[MAX_IF_LEN];
992 struct idx* addresses;
994 char name[MAX_IF_LEN];
998 #define MAX_IFACE_NO 32
1000 static struct idxlist *ifaces = NULL;
1003 #define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
1005 #define NLMSG_TAIL(nmsg) \
1006 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
1008 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
1011 int len = RTA_LENGTH(alen);
1014 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
1015 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
1018 rta = NLMSG_TAIL(n);
1019 rta->rta_type = type;
1021 memcpy(RTA_DATA(rta), data, alen);
1022 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
1028 static int nl_bound_sock(void)
1031 struct sockaddr_nl la;
1033 sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1035 LM_ERR("could not create NETLINK sock to get interface list\n");
1039 /* bind NETLINK socket to pid */
1040 bzero(&la, sizeof(la));
1041 la.nl_family = AF_NETLINK;
1043 la.nl_pid = getpid();
1045 if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
1046 LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
1052 if(sock >= 0) close(sock);
1056 #define fill_nl_req(req, type, family) do {\
1057 memset(&req, 0, sizeof(req));\
1058 req.nlh.nlmsg_len = sizeof(req);\
1059 req.nlh.nlmsg_type = type;\
1060 req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP;\
1061 req.nlh.nlmsg_pid = getpid();\
1062 req.nlh.nlmsg_seq = seq++;\
1063 req.g.rtgen_family = family;\
1067 static int get_flags(int family){
1069 struct nlmsghdr nlh;
1073 struct nlmsghdr* nlp;
1074 struct ifinfomsg *ifi;
1080 fill_nl_req(req, RTM_GETLINK, AF_INET);
1082 if((nl_sock = nl_bound_sock()) < 0) return -1;
1084 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0)
1086 LM_ERR("error sending NETLINK request\n");
1091 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1092 nlp = (struct nlmsghdr *) p;
1093 if(nlp->nlmsg_type == NLMSG_DONE){
1097 if(nlp->nlmsg_type == NLMSG_ERROR){
1098 LM_DBG("Error on message to netlink");
1106 nlp = (struct nlmsghdr *) buf;
1107 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1108 ifi = NLMSG_DATA(nlp);
1110 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1113 LM_ERR("Interface with index %d has flags %d\n", ifi->ifi_index, ifi->ifi_flags);
1115 LM_ERR("get_flags must not be called on empty interface list");
1118 if(ifi->ifi_index >= MAX_IFACE_NO){
1119 LM_ERR("invalid network interface index returned %d", ifi->ifi_index);
1122 ifaces[ifi->ifi_index].flags = ifi->ifi_flags;
1125 if(nl_sock>=0) close(nl_sock);
1129 if(nl_sock>=0) close(nl_sock);
1133 static int build_iface_list(void)
1136 struct nlmsghdr nlh;
1141 struct nlmsghdr* nlp;
1142 struct ifaddrmsg *ifi;
1147 struct rtattr * rtap;
1152 int families[] = {AF_INET, AF_INET6};
1153 char name[MAX_IF_LEN];
1154 int is_link_local = 0;
1157 if((ifaces = (struct idxlist*)pkg_malloc(MAX_IFACE_NO
1158 *sizeof(struct idxlist))) == NULL){
1162 memset(ifaces, 0, sizeof(struct idxlist)*MAX_IFACE_NO);
1165 /* bind netlink socket */
1166 if((nl_sock = nl_bound_sock()) < 0) return -1;
1168 for (i = 0 ; i < sizeof(families)/sizeof(int); i++) {
1169 fill_nl_req(req, RTM_GETADDR, families[i]);
1171 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0){
1172 LM_ERR("error sending NETLINK request\n");
1176 memset(buf, 0, sizeof(buf));
1180 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1181 LM_DBG("received %d byles \n", rtn);
1182 nlp = (struct nlmsghdr *) p;
1183 if(nlp->nlmsg_type == NLMSG_DONE){
1184 LM_DBG("done receiving netlink info \n");
1187 if(nlp->nlmsg_type == NLMSG_ERROR){
1188 LM_ERR("Error on message to netlink");
1196 nlp = (struct nlmsghdr *) buf;
1197 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1198 ifi = NLMSG_DATA(nlp);
1200 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1202 // init all the strings
1203 // inner loop: loop thru all the attributes of
1205 rtap = (struct rtattr *) IFA_RTA(ifi);
1207 rtl = IFA_PAYLOAD(nlp);
1209 index = ifi->ifa_index;
1210 if(index >= MAX_IFACE_NO){
1211 LM_ERR("Invalid interface index returned: %d\n", index);
1215 entry = (struct idx*)pkg_malloc(sizeof(struct idx));
1223 entry->family = families[i];
1224 entry->ifa_flags = ifi->ifa_flags;
1228 for(;RTA_OK(rtap, rtl);rtap=RTA_NEXT(rtap,rtl)){
1229 switch(rtap->rta_type){
1231 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1232 LM_DBG("Link Local Address, ignoring ...\n");
1236 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1237 LM_DBG("iface <IFA_ADDRESS> addr is %s\n", entry->addr);
1240 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1241 LM_DBG("Link Local Address, ignoring ...\n");
1244 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1245 LM_DBG("iface <IFA_LOCAL> addr is %s\n", entry->addr);
1248 LM_DBG("iface name is %s\n", (char*)RTA_DATA(rtap));
1249 strncpy(name, (char*)RTA_DATA(rtap), MAX_IF_LEN-1);
1260 if(sr_bind_ipv6_link_local==0) {
1261 /* skip - link local addresses are not bindable without scope */
1267 if(strlen(ifaces[index].name)==0 && strlen(name)>0) {
1268 strncpy(ifaces[index].name, name, MAX_IF_LEN-1);
1271 ifaces[index].index = index;
1273 if(ifaces[index].addresses == 0 )
1274 ifaces[index].addresses = entry;
1276 for(tmp = ifaces[index].addresses; tmp->next ; tmp = tmp->next)/*empty*/;
1281 if(nl_sock>0) close(nl_sock);
1282 /* the socket should be closed so we can bind again */
1283 for(i = 0; i < sizeof(families)/sizeof(int); i++){
1284 /* get device flags */
1285 get_flags(families[i]); /* AF_INET or AF_INET6 */
1290 if(nl_sock>=0) close(nl_sock);
1294 /* add all family type addresses of interface if_name to the socket_info array
1295 * if family ==0, uses all families
1296 * if if_name==0, adds all addresses on all interfaces
1297 * uses RTNETLINK sockets to get addresses on the present interface on LINUX
1298 * return: -1 on error, 0 on success
1300 int add_interfaces_via_netlink(char* if_name, int family, unsigned short port,
1301 unsigned short proto,
1302 struct addr_info** ai_l)
1306 enum si_flags flags;
1308 if(ifaces == NULL && (build_iface_list()!=0)){
1309 LM_ERR("Could not get network interface list\n");
1314 for(i=0; i< MAX_IFACE_NO; ++i){
1315 if(ifaces[i].addresses == NULL) continue; /* not present/configured */
1317 (strncmp(if_name, ifaces[i].name, strlen(ifaces[i].name))==0)){
1319 /* check if iface is up */
1320 //if(! (ifaces[i].flags & IFF_UP) ) continue;
1322 for(tmp = ifaces[i].addresses; tmp; tmp = tmp->next){
1323 LM_DBG("in add_iface_via_netlink Name %s Address %s\n",
1324 ifaces[i].name, tmp->addr);
1326 if (family && family == tmp->family){
1327 /* check if loopback */
1328 if (ifaces[i].flags & IFF_LOOPBACK){
1329 LM_DBG("INTERFACE %s is loopback", ifaces[i].name);
1333 if (new_addr_info2list(tmp->addr, flags, ai_l)!=0){
1334 LM_ERR("new_addr_info2list failed\n");
1345 #endif /* __OS_linux */
1347 /* add all family type addresses of interface if_name to the socket_info array
1348 * if family ==0, uses all families
1349 * if if_name==0, adds all addresses on all interfaces
1350 * return: -1 on error, 0 on success
1352 int add_interfaces(char* if_name, int family, unsigned short port,
1353 unsigned short proto,
1354 struct addr_info** ai_l)
1357 struct ip_addr addr;
1359 enum si_flags flags;
1360 struct ifaddrs *ifap, *ifa;
1362 if (getifaddrs (&ifap) != 0) {
1363 LM_ERR("getifaddrs failed\n");
1367 for (ifa = ifap; ifa; ifa = ifa->ifa_next)
1369 /* skip if no IP addr associated with the interface */
1370 if (ifa->ifa_addr==0)
1373 /* skip AF_PACKET addr family since it is of no use later on */
1374 if (ifa->ifa_addr->sa_family == AF_PACKET)
1377 if (if_name && strcmp(if_name, ifa->ifa_name))
1379 if (family && family != ifa->ifa_addr->sa_family)
1381 sockaddr2ip_addr(&addr, (struct sockaddr*)ifa->ifa_addr);
1382 tmp=ip_addr2a(&addr);
1383 if (ifa->ifa_flags & IFF_LOOPBACK)
1387 if (new_addr_info2list(tmp, flags, ai_l)!=0)
1389 LM_ERR("new_addr_info2list failed\n");
1393 LM_DBG("If: %8s Fam: %8x Flg: %16lx Adr: %s\n",
1394 ifa->ifa_name, ifa->ifa_addr->sa_family,
1395 (unsigned long)ifa->ifa_flags, tmp);
1405 /* internal helper function: resolve host names and add aliases
1406 * name is a value result parameter: it should contain the hostname that
1407 * will be used to fill all the other members, including name itself
1408 * in some situation (name->s should be a 0 terminated pkg_malloc'ed string)
1409 * return 0 on success and -1 on error */
1410 static int fix_hostname(str* name, struct ip_addr* address, str* address_str,
1411 enum si_flags* flags, int* type_flags,
1412 struct socket_info* s)
1418 /* get "official hostnames", all the aliases etc. */
1419 he=resolvehost(name->s);
1421 LM_ERR("could not resolve %s\n", name->s);
1424 /* check if we got the official name */
1425 if (strcasecmp(he->h_name, name->s)!=0){
1426 if (sr_auto_aliases &&
1427 add_alias(name->s, name->len, s->port_no, s->proto)<0){
1428 LM_ERR("add_alias failed\n");
1430 /* change the official name */
1432 name->s=(char*)pkg_malloc(strlen(he->h_name)+1);
1437 name->len=strlen(he->h_name);
1438 strncpy(name->s, he->h_name, name->len+1);
1440 /* add the aliases*/
1441 for(h=he->h_aliases; sr_auto_aliases && h && *h; h++)
1442 if (add_alias(*h, strlen(*h), s->port_no, s->proto)<0){
1443 LM_ERR("add_alias failed\n");
1445 hostent2ip_addr(address, he, 0); /*convert to ip_addr format*/
1447 *type_flags|=(address->af==AF_INET)?SOCKET_T_IPV4:SOCKET_T_IPV6;
1449 if ((tmp=ip_addr2a(address))==0) goto error;
1450 address_str->s=pkg_malloc(strlen(tmp)+1);
1451 if (address_str->s==0){
1455 strncpy(address_str->s, tmp, strlen(tmp)+1);
1456 /* set is_ip (1 if name is an ip address, 0 otherwise) */
1457 address_str->len=strlen(tmp);
1458 if (sr_auto_aliases && (address_str->len==name->len) &&
1459 (strncasecmp(address_str->s, name->s, address_str->len)==0)){
1461 /* do rev. DNS on it (for aliases)*/
1462 he=rev_resolvehost(address);
1464 LM_WARN("could not rev. resolve %s\n", name->s);
1466 /* add the aliases*/
1467 if (add_alias(he->h_name, strlen(he->h_name), s->port_no,
1469 LM_ERR("add_alias failed\n");
1471 for(h=he->h_aliases; h && *h; h++)
1472 if (add_alias(*h, strlen(*h), s->port_no, s->proto) < 0){
1473 LM_ERR("add_alias failed\n");
1479 /* Check if it is an multicast address and
1480 * set the flag if so
1482 if (is_mcast(address)){
1483 *flags |= SI_IS_MCAST;
1485 #endif /* USE_MCAST */
1487 /* check if INADDR_ANY */
1488 if (ip_addr_any(address))
1490 else if (ip_addr_loopback(address)) /* check for loopback */
1500 /* append new elements to a socket_info list after "list"
1501 * each element is created from addr_info_lst + port, protocol and flags
1502 * return 0 on succes, -1 on error
1504 static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
1505 char proto, char *usename,
1506 unsigned short useport, char *sockname,
1507 enum si_flags flags,
1508 struct socket_info** list)
1510 struct addr_info* ail;
1512 for (ail=ai_lst; ail; ail=ail->next){
1513 if(new_sock2list(ail->name.s, 0, port, proto, usename, useport, sockname,
1514 ail->flags | flags, list)==0)
1522 /* insert new elements to a socket_info list after "el",
1523 * each element is created from addr_info_lst + port, * protocol and flags
1524 * return 0 on succes, -1 on error
1526 static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
1527 unsigned short port,
1530 unsigned short useport,
1532 enum si_flags flags,
1533 struct socket_info* el)
1535 struct addr_info* ail;
1536 struct socket_info* new_si;
1538 for (ail=ai_lst; ail; ail=ail->next){
1539 if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
1540 usename, useport, sockname,
1541 ail->flags | flags, el))==0)
1550 /* fixes a socket list => resolve addresses,
1551 * interface names, fills missing members, remove duplicates
1552 * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
1553 static int fix_socket_list(struct socket_info **list, int* type_flags)
1555 struct socket_info* si;
1556 struct socket_info* new_si;
1557 struct socket_info* l;
1558 struct socket_info* next;
1559 struct socket_info* next_si;
1560 struct socket_info* del_si;
1561 struct socket_info* keep_si;
1564 struct addr_info* ai_lst;
1565 struct addr_info* ail;
1566 struct addr_info* tmp_ail;
1567 struct addr_info* tmp_ail_next;
1568 struct addr_info* ail_next;
1572 /* try to change all the interface names into addresses
1577 if (add_interfaces(si->name.s, auto_bind_ipv6 ? 0 : AF_INET,
1578 si->port_no, si->proto, &ai_lst)!=-1){
1579 if (si->flags & SI_IS_MHOMED){
1580 if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
1581 si->proto, si->useinfo.name.s,
1582 si->useinfo.port_no, si->sockname.s,
1583 ai_lst->flags|si->flags, si))==0)
1586 ai_lst=ai_lst->next;
1587 free_addr_info(ail); /* free the first elem. */
1591 for (ail=ai_lst; ail->next; ail=ail->next);
1592 /* add the mh list after the last position in ai_lst */
1593 addr_info_list_ins_lst(si->addr_info_lst, ail);
1594 new_si->addr_info_lst=ai_lst;
1595 si->addr_info_lst=0; /* detached and moved to new_si */
1596 ail=ail->next; /* ail== old si->addr_info_lst */
1598 ail=si->addr_info_lst;
1599 new_si->addr_info_lst=ail;
1600 si->addr_info_lst=0; /* detached and moved to new_si */
1603 /* add all addr. as separate interfaces */
1604 if (addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto,
1605 si->useinfo.name.s, si->useinfo.port_no,
1606 si->sockname.s, si->flags, si)!=0)
1608 /* ai_lst not needed anymore */
1609 free_addr_info_lst(&ai_lst);
1613 /* success => remove current entry (shift the entire array)*/
1614 sock_listrm(list, si);
1618 ail=si->addr_info_lst;
1622 if (new_si && (new_si->flags & SI_IS_MHOMED)){
1626 if (add_interfaces(ail->name.s, AF_INET, new_si->port_no,
1627 new_si->proto, &ai_lst)!=-1){
1628 /* add the resolved list after the current position */
1629 addr_info_list_ins_lst(ai_lst, ail);
1630 /* success, remove the current entity */
1631 addr_info_listrm(&new_si->addr_info_lst, ail);
1632 free_addr_info(ail);
1641 /* get ips & fill the port numbers*/
1643 LM_DBG("Listening on\n");
1645 for (si=*list;si;si=si->next){
1646 /* fix port number, port_no should be !=0 here */
1647 if (si->port_no==0){
1649 si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
1651 si->port_no= port_no;
1654 tmp=int2str(si->port_no, &len);
1655 if (len>=MAX_PORT_LEN){
1656 LM_ERR("bad port number: %d\n", si->port_no);
1659 si->port_no_str.s=(char*)pkg_malloc(len+1);
1660 if (si->port_no_str.s==0){
1664 strncpy(si->port_no_str.s, tmp, len+1);
1665 si->port_no_str.len=len;
1667 if (fix_hostname(&si->name, &si->address, &si->address_str,
1668 &si->flags, type_flags, si) !=0 )
1670 /* fix hostnames in mh addresses */
1671 for (ail=si->addr_info_lst; ail; ail=ail->next){
1672 if (fix_hostname(&ail->name, &ail->address, &ail->address_str,
1673 &ail->flags, type_flags, si) !=0 )
1677 if (fix_sock_str(si) < 0) goto error;
1680 printf(" %.*s [%s]:%s%s\n", si->name.len,
1681 si->name.s, si->address_str.s, si->port_no_str.s,
1682 si->flags & SI_IS_MCAST ? " mcast" : "");
1685 /* removing duplicate addresses*/
1686 for (si=*list;si; ){
1688 for (l=si->next;l;){
1690 if ((si->port_no==l->port_no) &&
1691 (si->address.af==l->address.af) &&
1692 (memcmp(si->address.u.addr, l->address.u.addr,
1693 si->address.len) == 0)
1695 /* remove the socket with no extra addresses.,
1696 * if both of them have extra addresses, remove one of them
1697 * and merge the extra addresses into the other */
1698 if (l->addr_info_lst==0){
1701 }else if (si->addr_info_lst==0){
1705 /* move l->addr_info_lst to si->addr_info_lst */
1706 /* find last elem */
1707 for (ail=si->addr_info_lst; ail->next; ail=ail->next);
1708 /* add the l list after the last position in si lst */
1709 addr_info_list_ins_lst(l->addr_info_lst, ail);
1710 l->addr_info_lst=0; /* detached */
1711 del_si=l; /* l will be removed */
1715 printf("removing duplicate %s [%s] == %s [%s]\n",
1716 keep_si->name.s, keep_si->address_str.s,
1717 del_si->name.s, del_si->address_str.s);
1719 /* add the name to the alias list*/
1720 if ((!(del_si->flags& SI_IS_IP)) && (
1721 (del_si->name.len!=keep_si->name.len)||
1722 (strncmp(del_si->name.s, keep_si->name.s,
1723 del_si->name.len)!=0))
1725 add_alias(del_si->name.s, del_si->name.len,
1726 l->port_no, l->proto);
1727 /* make sure next_si doesn't point to del_si */
1728 if (del_si==next_si)
1729 next_si=next_si->next;
1731 sock_listrm(list, del_si);
1732 free_sock_info(del_si);
1738 /* check for duplicates in extra_addresses */
1739 for (si=*list;si; si=si->next){
1740 /* check for & remove internal duplicates: */
1741 for (ail=si->addr_info_lst; ail;){
1743 /* 1. check if the extra addresses contain a duplicate for the
1745 if ((ail->address.af==si->address.af) &&
1746 (memcmp(ail->address.u.addr, si->address.u.addr,
1747 ail->address.len) == 0)){
1748 /* add the name to the alias list*/
1749 if ((!(ail->flags& SI_IS_IP)) && (
1750 (ail->name.len!=si->name.len)||
1751 (strncmp(ail->name.s, si->name.s, ail->name.len)!=0)))
1752 add_alias(ail->name.s, ail->name.len, si->port_no,
1755 addr_info_listrm(&si->addr_info_lst, ail);
1756 free_addr_info(ail);
1760 /* 2. check if the extra addresses contain a duplicates for
1761 * other addresses in the same list */
1762 for (tmp_ail=ail->next; tmp_ail;){
1763 tmp_ail_next=tmp_ail->next;
1764 if ((ail->address.af==tmp_ail->address.af) &&
1765 (memcmp(ail->address.u.addr, tmp_ail->address.u.addr,
1766 ail->address.len) == 0)){
1767 /* add the name to the alias list*/
1768 if ((!(tmp_ail->flags& SI_IS_IP)) && (
1769 (ail->name.len!=tmp_ail->name.len)||
1770 (strncmp(ail->name.s, tmp_ail->name.s,
1771 tmp_ail->name.len)!=0))
1773 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1774 si->port_no, si->proto);
1776 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1777 if(ail_next==tmp_ail) {
1778 ail_next = tmp_ail_next;
1780 free_addr_info(tmp_ail);
1782 tmp_ail=tmp_ail_next;
1786 /* check for duplicates between extra addresses (e.g. sctp MH)
1787 * and other main addresses, on conflict remove the corresponding
1788 * extra addresses (another possible solution would be to join
1789 * the 2 si entries into one). */
1790 for (ail=si->addr_info_lst; ail;){
1792 for (l=*list;l; l=l->next){
1793 if (l==si) continue;
1794 if (si->port_no==l->port_no){
1795 if ((ail->address.af==l->address.af) &&
1796 (memcmp(ail->address.u.addr, l->address.u.addr,
1797 ail->address.len) == 0)){
1798 /* add the name to the alias list*/
1799 if ((!(ail->flags& SI_IS_IP)) && (
1800 (ail->name.len!=l->name.len)||
1801 (strncmp(ail->name.s, l->name.s, l->name.len)!=0))
1803 add_alias(ail->name.s, ail->name.len,
1804 l->port_no, l->proto);
1806 addr_info_listrm(&si->addr_info_lst, ail);
1807 free_addr_info(ail);
1810 /* check for duplicates with other extra addresses
1812 for (tmp_ail=l->addr_info_lst; tmp_ail; ){
1813 tmp_ail_next=tmp_ail->next;
1814 if ((ail->address.af==tmp_ail->address.af) &&
1815 (memcmp(ail->address.u.addr,
1816 tmp_ail->address.u.addr,
1817 ail->address.len) == 0)){
1818 /* add the name to the alias list*/
1819 if ((!(tmp_ail->flags& SI_IS_IP)) && (
1820 (ail->name.len!=tmp_ail->name.len)||
1821 (strncmp(ail->name.s, tmp_ail->name.s,
1822 tmp_ail->name.len)!=0))
1824 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1825 l->port_no, l->proto);
1827 addr_info_listrm(&l->addr_info_lst, tmp_ail);
1828 free_addr_info(tmp_ail);
1830 tmp_ail=tmp_ail_next;
1839 /* Remove invalid multicast entries */
1842 if ((si->proto == PROTO_TCP)
1844 || (si->proto == PROTO_TLS)
1845 #endif /* USE_TLS */
1847 || (si->proto == PROTO_SCTP)
1850 if (si->flags & SI_IS_MCAST){
1851 LM_WARN("removing entry %s:%s [%s]:%s\n",
1852 get_valid_proto_name(si->proto), si->name.s,
1853 si->address_str.s, si->port_no_str.s);
1856 sock_listrm(list, l);
1859 ail=si->addr_info_lst;
1861 if (ail->flags & SI_IS_MCAST){
1862 LM_WARN("removing mh entry %s:%s"
1864 get_valid_proto_name(si->proto), ail->name.s,
1865 ail->address_str.s, si->port_no_str.s);
1868 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1869 free_addr_info(tmp_ail);
1880 #endif /* USE_MCAST */
1887 int socket_types = 0;
1889 /* fix all 3 socket lists, fills socket_types if non-null
1890 * return 0 on success, -1 on error */
1891 int fix_all_socket_lists()
1893 struct utsname myname;
1895 struct addr_info* ai_lst;
1910 /* get all listening ipv4/ipv6 interfaces */
1911 if ( ( (add_interfaces(0, AF_INET, 0, PROTO_UDP, &ai_lst)==0)
1913 && (!auto_bind_ipv6 || add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0)
1915 && ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0, PROTO_UDP, &ai_lst) ==0 ) /* add_interface does not work for IPv6 on Linux */
1916 #endif /* __OS_linux */
1917 ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, &udp_listen)==0)){
1918 free_addr_info_lst(&ai_lst);
1920 /* if ok, try to add the others too */
1923 if ( ((add_interfaces(0, AF_INET, 0, PROTO_TCP, &ai_lst)!=0)
1925 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TCP, &ai_lst) != 0)
1927 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_TCP, &ai_lst) !=0 )
1928 #endif /* __OS_linux */
1929 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0, 0,
1932 free_addr_info_lst(&ai_lst);
1936 if (((add_interfaces(0, AF_INET, 0, PROTO_TLS,
1939 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TLS, &ai_lst) != 0)
1941 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_TLS, &ai_lst)!=0)
1942 #endif /* __OS_linux */
1943 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, 0, 0,
1947 free_addr_info_lst(&ai_lst);
1954 if (((add_interfaces(0, AF_INET, 0, PROTO_SCTP, &ai_lst)!=0)
1956 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1958 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1959 #endif /* __OS_linux */
1960 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0, 0,
1963 free_addr_info_lst(&ai_lst);
1966 #endif /* USE_SCTP */
1968 /* if error fall back to get hostname */
1969 /* get our address, only the first one */
1970 if (uname (&myname) <0){
1971 LM_ERR("cannot determine hostname, try -l address\n");
1974 if (add_listen_iface(myname.nodename, 0, 0, 0, 0)!=0){
1975 LM_ERR("add_listen_iface failed \n");
1981 if (fix_socket_list(&udp_listen, &flags)!=0){
1982 LM_ERR("fix_socket_list udp failed\n");
1986 socket_types|=flags|SOCKET_T_UDP;
1990 if (!tcp_disable && (fix_socket_list(&tcp_listen, &flags)!=0)){
1991 LM_ERR("fix_socket_list tcp failed\n");
1995 socket_types|=flags|SOCKET_T_TCP;
1999 if (!tls_disable && (fix_socket_list(&tls_listen, &flags)!=0)){
2000 LM_ERR("fix_socket_list tls failed\n");
2004 socket_types|=flags|SOCKET_T_TLS;
2010 if (!sctp_disable && (fix_socket_list(&sctp_listen, &flags)!=0)){
2011 LM_ERR("fix_socket_list sctp failed\n");
2015 socket_types|=flags|SOCKET_T_SCTP;
2017 #endif /* USE_SCTP */
2029 LM_ERR("no listening sockets\n");
2034 if (ai_lst) free_addr_info_lst(&ai_lst);
2040 void print_all_socket_lists()
2042 struct socket_info *si;
2043 struct socket_info** list;
2044 struct addr_info* ai;
2045 unsigned short proto;
2049 list=get_sock_info_list(proto);
2050 for(si=list?*list:0; si; si=si->next){
2051 if (si->addr_info_lst){
2053 get_valid_proto_name(proto),
2055 for (ai=si->addr_info_lst; ai; ai=ai->next) {
2056 printf(", %s", ai->address_str.s);
2058 printf("):%s%s%s\n",
2060 si->flags & SI_IS_MCAST ? " mcast" : "",
2061 si->flags & SI_IS_MHOMED? " mhomed" : "");
2064 get_valid_proto_name(proto),
2066 if (!(si->flags & SI_IS_IP)) {
2067 printf(" [%s]", si->address_str.s);
2071 si->flags & SI_IS_MCAST ? " mcast" : "",
2072 si->flags & SI_IS_MHOMED? " mhomed" : "");
2073 if (si->sockname.s) {
2074 printf(" name %s", si->sockname.s);
2076 if (si->useinfo.name.s) {
2077 printf(" advertise %s:%d", si->useinfo.name.s, si->useinfo.port_no);
2082 }while((proto=next_proto(proto)));
2086 void print_aliases()
2088 struct host_alias* a;
2090 for(a=aliases; a; a=a->next) {
2092 printf(" %s: %.*s:%d\n", get_valid_proto_name(a->proto),
2093 a->alias.len, a->alias.s, a->port);
2095 printf(" %s: %.*s:*\n", get_valid_proto_name(a->proto),
2096 a->alias.len, a->alias.s);
2103 void init_proto_order()
2107 /* fix proto list (remove disabled protocols)*/
2111 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2112 if (nxt_proto[r]==PROTO_TCP)
2113 nxt_proto[r]=nxt_proto[PROTO_TCP];
2117 if (tls_disable || tcp_disable)
2120 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2121 if (nxt_proto[r]==PROTO_TLS)
2122 nxt_proto[r]=nxt_proto[PROTO_TLS];
2127 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2128 if (nxt_proto[r]==PROTO_SCTP)
2129 nxt_proto[r]=nxt_proto[PROTO_SCTP];
2132 /* Deliberately skipping PROTO_WS and PROTO_WSS here as these
2133 are just upgraded TCP and TLS connections */
2138 * parse '[port:]host[:port]' string to a broken down structure
2140 int parse_protohostport(str* ins, sr_phostp_t *r)
2142 char* first; /* first ':' occurrence */
2143 char* second; /* second ':' occurrence */
2150 memset(r, 0, sizeof(sr_phostp_t));
2152 /* find the first 2 ':', ignoring possible ipv6 addresses
2153 * (substrings between [])
2155 for(p=ins->s; p<ins->s+ins->len; p++){
2159 if (bracket>1) goto error_brackets;
2163 if (bracket<0) goto error_brackets;
2167 if (first==0) first=p;
2168 else if( second==0) second=p;
2169 else goto error_colons;
2174 if (p==ins->s) return -1;
2175 if (*(p-1)==':') goto error_colons;
2177 if (first==0) { /* no ':' => only host */
2179 r->host.len=(int)(p-ins->s);
2182 if (second) { /* 2 ':' found => check if valid */
2183 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2187 tmp.len=(ins->s + ins->len) - tmp.s;
2189 if (str2int(&tmp, (unsigned int *)&(r->port))<0) goto error_port;
2192 r->host.len=(int)(second-r->host.s);
2195 /* only 1 ':' found => it's either proto:host or host:port */
2197 tmp.len=(ins->s + ins->len) - tmp.s;
2198 if (str2int(&tmp, (unsigned int *)&(r->port))<0) {
2199 /* invalid port => it's proto:host */
2200 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2203 r->host.len=(int)(p-r->host.s);
2205 /* valid port => its host:port */
2207 r->host.len=(int)(first-r->host.s);
2212 LM_ERR("too many brackets in %.*s\n", ins->len, ins->s);
2215 LM_ERR("too many colons in %.*s\n", ins->len, ins->s);
2218 LM_ERR("bad protocol in %.*s\n", ins->len, ins->s);
2221 LM_ERR("bad port number in %.*s\n", ins->len, ins->s);
2226 * lookup a local socket by '[port:]host[:port]' string
2228 struct socket_info* lookup_local_socket(str *phostp)
2231 if(parse_protohostport(phostp, &r)<0)
2233 return grep_sock_info(&r.host, (unsigned short)r.port,
2234 (unsigned short)r.proto);