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 /* checks if the proto:port is one of the ports we listen on
691 * and returns the corresponding socket_info structure.
692 * if proto==0 (PROTO_NONE) the protocol is ignored
693 * returns 0 if not found
695 struct socket_info* grep_sock_info_by_port(unsigned short port,
696 unsigned short proto)
698 struct socket_info* si;
699 struct socket_info** list;
700 unsigned short c_proto;
705 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
707 /* get the proper sock_list */
708 list=get_sock_info_list(c_proto);
710 if (list==0) /* disabled or unknown protocol */
713 for (si=*list; si; si=si->next){
714 LM_DBG("checking if port %d matches port %d\n", si->port_no, port);
715 if (si->port_no==port) {
719 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
728 /* checks if the proto: ip:port is one of the address we listen on
729 * and returns the corresponding socket_info structure.
730 * (same as grep_socket_info, but use ip addr instead)
731 * if port==0, the port number is ignored
732 * if proto==0 (PROTO_NONE) the protocol is ignored
733 * returns 0 if not found
734 * WARNING: uses str2ip6 so it will overwrite any previous
735 * unsaved result of this function (static buffer)
737 struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
738 unsigned short proto)
740 struct socket_info* si;
741 struct socket_info** list;
742 struct addr_info* ai;
743 unsigned short c_proto;
745 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
747 /* get the proper sock_list */
748 list=get_sock_info_list(c_proto);
750 if (list==0) /* disabled or unknown protocol */
753 for (si=*list; si; si=si->next){
755 if (si->port_no!=port) {
759 if (ip_addr_cmp(ip, &si->address)
760 || ip_addr_cmp(ip, &si->useinfo.address))
762 for (ai=si->addr_info_lst; ai; ai=ai->next)
763 if (ip_addr_cmp(ip, &ai->address))
766 }while( (proto==0) && (c_proto=next_proto(c_proto)) );
775 /* append a new sock_info structure to the corresponding list
776 * return new sock info on success, 0 on error */
777 static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
779 unsigned short proto,
780 char *usename, unsigned short useport,
783 struct socket_info** list)
785 struct socket_info* si;
786 /* allocates si and si->name in new pkg memory */
787 si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
789 LM_ERR("new_sock_info failed\n");
792 if(socket_workers>0) {
793 si->workers = socket_workers;
798 si->mcast.len=strlen(mcast);
799 si->mcast.s=(char*)pkg_malloc(si->mcast.len+1);
800 if (si->mcast.s==0) {
802 pkg_free(si->name.s);
806 strcpy(si->mcast.s, mcast);
809 #endif /* USE_MCAST */
810 sock_listadd(list, si);
818 /* adds a new sock_info structure immediately after "after"
819 * return new sock info on success, 0 on error */
820 static struct socket_info* new_sock2list_after(char* name,
821 struct name_lst* addr_l,
823 unsigned short proto,
825 unsigned short useport,
828 struct socket_info* after)
830 struct socket_info* si;
832 si=new_sock_info(name, addr_l, port, proto, usename, useport, sockname, flags);
834 LM_ERR("new_sock_info failed\n");
837 sock_listins(si, after);
845 /* adds a sock_info structure to the corresponding proto list
846 * return 0 on success, -1 on error */
847 int add_listen_advertise_iface_name(char* name, struct name_lst* addr_l,
848 unsigned short port, unsigned short proto,
849 char *usename, unsigned short useport, char *sockname,
852 struct socket_info** list;
853 unsigned short c_proto;
854 struct name_lst* a_l;
855 unsigned short c_port;
857 c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
859 list=get_sock_info_list(c_proto);
860 if (list==0) /* disabled or unknown protocol */
863 if (port==0){ /* use default port */
866 ((c_proto)==PROTO_TLS)?tls_port_no:
871 else if ((c_proto==PROTO_TLS) && (proto==0)){
872 /* -l ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1?*/
879 if (c_proto!=PROTO_SCTP){
880 if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
881 sockname, flags & ~SI_IS_MHOMED, list)==0){
882 LM_ERR("new_sock2list failed\n");
885 /* add the other addresses in the list as separate sockets
886 * since only SCTP can bind to multiple addresses */
887 for (a_l=addr_l; a_l; a_l=a_l->next){
888 if (new_sock2list(a_l->name, 0, c_port,
889 c_proto, usename, useport, sockname,
890 flags & ~SI_IS_MHOMED, list)==0){
891 LM_ERR("new_sock2list failed\n");
896 if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
897 sockname, flags, list)==0){
898 LM_ERR("new_sock2list failed\n");
902 }while( (proto==0) && (c_proto=next_proto(c_proto)));
908 /* adds a sock_info structure to the corresponding proto list
909 * return 0 on success, -1 on error */
910 int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
911 unsigned short port, unsigned short proto,
912 char *usename, unsigned short useport,
915 return add_listen_advertise_iface_name(name, addr_l, port, proto,
916 usename, useport, NULL, flags);
919 /* adds a sock_info structure to the corresponding proto list
920 * return 0 on success, -1 on error */
921 int add_listen_iface(char* name, struct name_lst* addr_l,
922 unsigned short port, unsigned short proto,
925 return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0, 0,
929 /* adds a sock_info structure to the corresponding proto list
930 * return 0 on success, -1 on error */
931 int add_listen_iface_name(char* name, struct name_lst* addr_l,
932 unsigned short port, unsigned short proto, char *sockname,
935 return add_listen_advertise_iface_name(name, addr_l, port, proto, 0, 0,
941 #include "linux/types.h"
942 #include "linux/netlink.h"
943 #include "linux/rtnetlink.h"
944 #include "arpa/inet.h"
947 #define MAX_IF_LEN 64
953 char addr[MAX_IF_LEN];
958 struct idx* addresses;
960 char name[MAX_IF_LEN];
964 #define MAX_IFACE_NO 32
966 static struct idxlist *ifaces = NULL;
969 #define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
971 #define NLMSG_TAIL(nmsg) \
972 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
974 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
977 int len = RTA_LENGTH(alen);
980 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
981 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
985 rta->rta_type = type;
987 memcpy(RTA_DATA(rta), data, alen);
988 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
994 static int nl_bound_sock(void)
997 struct sockaddr_nl la;
999 sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1001 LM_ERR("could not create NETLINK sock to get interface list\n");
1005 /* bind NETLINK socket to pid */
1006 bzero(&la, sizeof(la));
1007 la.nl_family = AF_NETLINK;
1009 la.nl_pid = getpid();
1011 if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
1012 LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
1018 if(sock >= 0) close(sock);
1022 #define fill_nl_req(req, type, family) do {\
1023 memset(&req, 0, sizeof(req));\
1024 req.nlh.nlmsg_len = sizeof(req);\
1025 req.nlh.nlmsg_type = type;\
1026 req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP;\
1027 req.nlh.nlmsg_pid = getpid();\
1028 req.nlh.nlmsg_seq = seq++;\
1029 req.g.rtgen_family = family;\
1033 static int get_flags(int family){
1035 struct nlmsghdr nlh;
1039 struct nlmsghdr* nlp;
1040 struct ifinfomsg *ifi;
1046 fill_nl_req(req, RTM_GETLINK, AF_INET);
1048 if((nl_sock = nl_bound_sock()) < 0) return -1;
1050 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0)
1052 LM_ERR("error sending NETLINK request\n");
1057 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1058 nlp = (struct nlmsghdr *) p;
1059 if(nlp->nlmsg_type == NLMSG_DONE){
1063 if(nlp->nlmsg_type == NLMSG_ERROR){
1064 LM_DBG("Error on message to netlink");
1072 nlp = (struct nlmsghdr *) buf;
1073 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1074 ifi = NLMSG_DATA(nlp);
1076 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1079 LM_ERR("Interface with index %d has flags %d\n", ifi->ifi_index, ifi->ifi_flags);
1081 LM_ERR("get_flags must not be called on empty interface list");
1084 if(ifi->ifi_index >= MAX_IFACE_NO){
1085 LM_ERR("invalid network interface index returned %d", ifi->ifi_index);
1088 ifaces[ifi->ifi_index].flags = ifi->ifi_flags;
1091 if(nl_sock>=0) close(nl_sock);
1095 if(nl_sock>=0) close(nl_sock);
1099 static int build_iface_list(void)
1102 struct nlmsghdr nlh;
1107 struct nlmsghdr* nlp;
1108 struct ifaddrmsg *ifi;
1113 struct rtattr * rtap;
1118 int families[] = {AF_INET, AF_INET6};
1119 char name[MAX_IF_LEN];
1120 int is_link_local = 0;
1123 if((ifaces = (struct idxlist*)pkg_malloc(MAX_IFACE_NO
1124 *sizeof(struct idxlist))) == NULL){
1128 memset(ifaces, 0, sizeof(struct idxlist)*MAX_IFACE_NO);
1131 /* bind netlink socket */
1132 if((nl_sock = nl_bound_sock()) < 0) return -1;
1134 for (i = 0 ; i < sizeof(families)/sizeof(int); i++) {
1135 fill_nl_req(req, RTM_GETADDR, families[i]);
1137 if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0){
1138 LM_ERR("error sending NETLINK request\n");
1142 memset(buf, 0, sizeof(buf));
1146 rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
1147 LM_DBG("received %d byles \n", rtn);
1148 nlp = (struct nlmsghdr *) p;
1149 if(nlp->nlmsg_type == NLMSG_DONE){
1150 LM_DBG("done receiving netlink info \n");
1153 if(nlp->nlmsg_type == NLMSG_ERROR){
1154 LM_ERR("Error on message to netlink");
1162 nlp = (struct nlmsghdr *) buf;
1163 for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
1164 ifi = NLMSG_DATA(nlp);
1166 if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
1168 // init all the strings
1169 // inner loop: loop thru all the attributes of
1171 rtap = (struct rtattr *) IFA_RTA(ifi);
1173 rtl = IFA_PAYLOAD(nlp);
1175 index = ifi->ifa_index;
1176 if(index >= MAX_IFACE_NO){
1177 LM_ERR("Invalid interface index returned: %d\n", index);
1181 entry = (struct idx*)pkg_malloc(sizeof(struct idx));
1189 entry->family = families[i];
1190 entry->ifa_flags = ifi->ifa_flags;
1194 for(;RTA_OK(rtap, rtl);rtap=RTA_NEXT(rtap,rtl)){
1195 switch(rtap->rta_type){
1197 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1198 LM_DBG("Link Local Address, ignoring ...\n");
1202 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1203 LM_DBG("iface <IFA_ADDRESS> addr is %s\n", entry->addr);
1206 if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
1207 LM_DBG("Link Local Address, ignoring ...\n");
1210 inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
1211 LM_DBG("iface <IFA_LOCAL> addr is %s\n", entry->addr);
1214 LM_DBG("iface name is %s\n", (char*)RTA_DATA(rtap));
1215 strncpy(name, (char*)RTA_DATA(rtap), MAX_IF_LEN-1);
1226 if(sr_bind_ipv6_link_local==0) {
1227 /* skip - link local addresses are not bindable without scope */
1233 if(strlen(ifaces[index].name)==0 && strlen(name)>0) {
1234 strncpy(ifaces[index].name, name, MAX_IF_LEN-1);
1237 ifaces[index].index = index;
1239 if(ifaces[index].addresses == 0 )
1240 ifaces[index].addresses = entry;
1242 for(tmp = ifaces[index].addresses; tmp->next ; tmp = tmp->next)/*empty*/;
1247 if(nl_sock>0) close(nl_sock);
1248 /* the socket should be closed so we can bind again */
1249 for(i = 0; i < sizeof(families)/sizeof(int); i++){
1250 /* get device flags */
1251 get_flags(families[i]); /* AF_INET or AF_INET6 */
1256 if(nl_sock>=0) close(nl_sock);
1260 /* add all family type addresses of interface if_name to the socket_info array
1261 * if family ==0, uses all families
1262 * if if_name==0, adds all addresses on all interfaces
1263 * uses RTNETLINK sockets to get addresses on the present interface on LINUX
1264 * return: -1 on error, 0 on success
1266 int add_interfaces_via_netlink(char* if_name, int family, unsigned short port,
1267 unsigned short proto,
1268 struct addr_info** ai_l)
1272 enum si_flags flags;
1274 if(ifaces == NULL && (build_iface_list()!=0)){
1275 LM_ERR("Could not get network interface list\n");
1280 for(i=0; i< MAX_IFACE_NO; ++i){
1281 if(ifaces[i].addresses == NULL) continue; /* not present/configured */
1283 (strncmp(if_name, ifaces[i].name, strlen(ifaces[i].name))==0)){
1285 /* check if iface is up */
1286 //if(! (ifaces[i].flags & IFF_UP) ) continue;
1288 for(tmp = ifaces[i].addresses; tmp; tmp = tmp->next){
1289 LM_DBG("in add_iface_via_netlink Name %s Address %s\n",
1290 ifaces[i].name, tmp->addr);
1292 if (family && family == tmp->family){
1293 /* check if loopback */
1294 if (ifaces[i].flags & IFF_LOOPBACK){
1295 LM_DBG("INTERFACE %s is loopback", ifaces[i].name);
1299 if (new_addr_info2list(tmp->addr, flags, ai_l)!=0){
1300 LM_ERR("new_addr_info2list failed\n");
1311 #endif /* __OS_linux */
1313 /* add all family type addresses of interface if_name to the socket_info array
1314 * if family ==0, uses all families
1315 * if if_name==0, adds all addresses on all interfaces
1316 * return: -1 on error, 0 on success
1318 int add_interfaces(char* if_name, int family, unsigned short port,
1319 unsigned short proto,
1320 struct addr_info** ai_l)
1323 struct ip_addr addr;
1325 enum si_flags flags;
1326 struct ifaddrs *ifap, *ifa;
1328 if (getifaddrs (&ifap) != 0) {
1329 LM_ERR("getifaddrs failed\n");
1333 for (ifa = ifap; ifa; ifa = ifa->ifa_next)
1335 /* skip if no IP addr associated with the interface */
1336 if (ifa->ifa_addr==0)
1339 /* skip AF_PACKET addr family since it is of no use later on */
1340 if (ifa->ifa_addr->sa_family == AF_PACKET)
1343 if (if_name && strcmp(if_name, ifa->ifa_name))
1345 if (family && family != ifa->ifa_addr->sa_family)
1347 sockaddr2ip_addr(&addr, (struct sockaddr*)ifa->ifa_addr);
1348 tmp=ip_addr2a(&addr);
1349 if (ifa->ifa_flags & IFF_LOOPBACK)
1353 if (new_addr_info2list(tmp, flags, ai_l)!=0)
1355 LM_ERR("new_addr_info2list failed\n");
1359 LM_DBG("If: %8s Fam: %8x Flg: %16lx Adr: %s\n",
1360 ifa->ifa_name, ifa->ifa_addr->sa_family,
1361 (unsigned long)ifa->ifa_flags, tmp);
1371 /* internal helper function: resolve host names and add aliases
1372 * name is a value result parameter: it should contain the hostname that
1373 * will be used to fill all the other members, including name itself
1374 * in some situation (name->s should be a 0 terminated pkg_malloc'ed string)
1375 * return 0 on success and -1 on error */
1376 static int fix_hostname(str* name, struct ip_addr* address, str* address_str,
1377 enum si_flags* flags, int* type_flags,
1378 struct socket_info* s)
1384 /* get "official hostnames", all the aliases etc. */
1385 he=resolvehost(name->s);
1387 LM_ERR("could not resolve %s\n", name->s);
1390 /* check if we got the official name */
1391 if (strcasecmp(he->h_name, name->s)!=0){
1392 if (sr_auto_aliases &&
1393 add_alias(name->s, name->len, s->port_no, s->proto)<0){
1394 LM_ERR("add_alias failed\n");
1396 /* change the official name */
1398 name->s=(char*)pkg_malloc(strlen(he->h_name)+1);
1403 name->len=strlen(he->h_name);
1404 strncpy(name->s, he->h_name, name->len+1);
1406 /* add the aliases*/
1407 for(h=he->h_aliases; sr_auto_aliases && h && *h; h++)
1408 if (add_alias(*h, strlen(*h), s->port_no, s->proto)<0){
1409 LM_ERR("add_alias failed\n");
1411 hostent2ip_addr(address, he, 0); /*convert to ip_addr format*/
1413 *type_flags|=(address->af==AF_INET)?SOCKET_T_IPV4:SOCKET_T_IPV6;
1415 if ((tmp=ip_addr2a(address))==0) goto error;
1416 address_str->s=pkg_malloc(strlen(tmp)+1);
1417 if (address_str->s==0){
1421 strncpy(address_str->s, tmp, strlen(tmp)+1);
1422 /* set is_ip (1 if name is an ip address, 0 otherwise) */
1423 address_str->len=strlen(tmp);
1424 if (sr_auto_aliases && (address_str->len==name->len) &&
1425 (strncasecmp(address_str->s, name->s, address_str->len)==0)){
1427 /* do rev. DNS on it (for aliases)*/
1428 he=rev_resolvehost(address);
1430 LM_WARN("could not rev. resolve %s\n", name->s);
1432 /* add the aliases*/
1433 if (add_alias(he->h_name, strlen(he->h_name), s->port_no,
1435 LM_ERR("add_alias failed\n");
1437 for(h=he->h_aliases; h && *h; h++)
1438 if (add_alias(*h, strlen(*h), s->port_no, s->proto) < 0){
1439 LM_ERR("add_alias failed\n");
1445 /* Check if it is an multicast address and
1446 * set the flag if so
1448 if (is_mcast(address)){
1449 *flags |= SI_IS_MCAST;
1451 #endif /* USE_MCAST */
1453 /* check if INADDR_ANY */
1454 if (ip_addr_any(address))
1456 else if (ip_addr_loopback(address)) /* check for loopback */
1466 /* append new elements to a socket_info list after "list"
1467 * each element is created from addr_info_lst + port, protocol and flags
1468 * return 0 on succes, -1 on error
1470 static int addr_info_to_si_lst(struct addr_info* ai_lst, unsigned short port,
1471 char proto, char *usename,
1472 unsigned short useport, char *sockname,
1473 enum si_flags flags,
1474 struct socket_info** list)
1476 struct addr_info* ail;
1478 for (ail=ai_lst; ail; ail=ail->next){
1479 if(new_sock2list(ail->name.s, 0, port, proto, usename, useport, sockname,
1480 ail->flags | flags, list)==0)
1488 /* insert new elements to a socket_info list after "el",
1489 * each element is created from addr_info_lst + port, * protocol and flags
1490 * return 0 on succes, -1 on error
1492 static int addr_info_to_si_lst_after(struct addr_info* ai_lst,
1493 unsigned short port,
1496 unsigned short useport,
1498 enum si_flags flags,
1499 struct socket_info* el)
1501 struct addr_info* ail;
1502 struct socket_info* new_si;
1504 for (ail=ai_lst; ail; ail=ail->next){
1505 if((new_si=new_sock2list_after(ail->name.s, 0, port, proto,
1506 usename, useport, sockname,
1507 ail->flags | flags, el))==0)
1516 /* fixes a socket list => resolve addresses,
1517 * interface names, fills missing members, remove duplicates
1518 * fills type_flags if not null with SOCKET_T_IPV4 and/or SOCKET_T_IPV6*/
1519 static int fix_socket_list(struct socket_info **list, int* type_flags)
1521 struct socket_info* si;
1522 struct socket_info* new_si;
1523 struct socket_info* l;
1524 struct socket_info* next;
1525 struct socket_info* next_si;
1526 struct socket_info* del_si;
1527 struct socket_info* keep_si;
1530 struct addr_info* ai_lst;
1531 struct addr_info* ail;
1532 struct addr_info* tmp_ail;
1533 struct addr_info* tmp_ail_next;
1534 struct addr_info* ail_next;
1538 /* try to change all the interface names into addresses
1543 if (add_interfaces(si->name.s, auto_bind_ipv6 ? 0 : AF_INET,
1544 si->port_no, si->proto, &ai_lst)!=-1){
1545 if (si->flags & SI_IS_MHOMED){
1546 if((new_si=new_sock2list_after(ai_lst->name.s, 0, si->port_no,
1547 si->proto, si->useinfo.name.s,
1548 si->useinfo.port_no, si->sockname.s,
1549 ai_lst->flags|si->flags, si))==0)
1552 ai_lst=ai_lst->next;
1553 free_addr_info(ail); /* free the first elem. */
1557 for (ail=ai_lst; ail->next; ail=ail->next);
1558 /* add the mh list after the last position in ai_lst */
1559 addr_info_list_ins_lst(si->addr_info_lst, ail);
1560 new_si->addr_info_lst=ai_lst;
1561 si->addr_info_lst=0; /* detached and moved to new_si */
1562 ail=ail->next; /* ail== old si->addr_info_lst */
1564 ail=si->addr_info_lst;
1565 new_si->addr_info_lst=ail;
1566 si->addr_info_lst=0; /* detached and moved to new_si */
1569 /* add all addr. as separate interfaces */
1570 if (addr_info_to_si_lst_after(ai_lst, si->port_no, si->proto,
1571 si->useinfo.name.s, si->useinfo.port_no,
1572 si->sockname.s, si->flags, si)!=0)
1574 /* ai_lst not needed anymore */
1575 free_addr_info_lst(&ai_lst);
1579 /* success => remove current entry (shift the entire array)*/
1580 sock_listrm(list, si);
1584 ail=si->addr_info_lst;
1588 if (new_si && (new_si->flags & SI_IS_MHOMED)){
1592 if (add_interfaces(ail->name.s, AF_INET, new_si->port_no,
1593 new_si->proto, &ai_lst)!=-1){
1594 /* add the resolved list after the current position */
1595 addr_info_list_ins_lst(ai_lst, ail);
1596 /* success, remove the current entity */
1597 addr_info_listrm(&new_si->addr_info_lst, ail);
1598 free_addr_info(ail);
1607 /* get ips & fill the port numbers*/
1609 LM_DBG("Listening on\n");
1611 for (si=*list;si;si=si->next){
1612 /* fix port number, port_no should be !=0 here */
1613 if (si->port_no==0){
1615 si->port_no= (si->proto==PROTO_TLS)?tls_port_no:port_no;
1617 si->port_no= port_no;
1620 tmp=int2str(si->port_no, &len);
1621 if (len>=MAX_PORT_LEN){
1622 LM_ERR("bad port number: %d\n", si->port_no);
1625 si->port_no_str.s=(char*)pkg_malloc(len+1);
1626 if (si->port_no_str.s==0){
1630 strncpy(si->port_no_str.s, tmp, len+1);
1631 si->port_no_str.len=len;
1633 if (fix_hostname(&si->name, &si->address, &si->address_str,
1634 &si->flags, type_flags, si) !=0 )
1636 /* fix hostnames in mh addresses */
1637 for (ail=si->addr_info_lst; ail; ail=ail->next){
1638 if (fix_hostname(&ail->name, &ail->address, &ail->address_str,
1639 &ail->flags, type_flags, si) !=0 )
1643 if (fix_sock_str(si) < 0) goto error;
1646 printf(" %.*s [%s]:%s%s\n", si->name.len,
1647 si->name.s, si->address_str.s, si->port_no_str.s,
1648 si->flags & SI_IS_MCAST ? " mcast" : "");
1651 /* removing duplicate addresses*/
1652 for (si=*list;si; ){
1654 for (l=si->next;l;){
1656 if ((si->port_no==l->port_no) &&
1657 (si->address.af==l->address.af) &&
1658 (memcmp(si->address.u.addr, l->address.u.addr,
1659 si->address.len) == 0)
1661 /* remove the socket with no extra addresses.,
1662 * if both of them have extra addresses, remove one of them
1663 * and merge the extra addresses into the other */
1664 if (l->addr_info_lst==0){
1667 }else if (si->addr_info_lst==0){
1671 /* move l->addr_info_lst to si->addr_info_lst */
1672 /* find last elem */
1673 for (ail=si->addr_info_lst; ail->next; ail=ail->next);
1674 /* add the l list after the last position in si lst */
1675 addr_info_list_ins_lst(l->addr_info_lst, ail);
1676 l->addr_info_lst=0; /* detached */
1677 del_si=l; /* l will be removed */
1681 printf("removing duplicate %s [%s] == %s [%s]\n",
1682 keep_si->name.s, keep_si->address_str.s,
1683 del_si->name.s, del_si->address_str.s);
1685 /* add the name to the alias list*/
1686 if ((!(del_si->flags& SI_IS_IP)) && (
1687 (del_si->name.len!=keep_si->name.len)||
1688 (strncmp(del_si->name.s, keep_si->name.s,
1689 del_si->name.len)!=0))
1691 add_alias(del_si->name.s, del_si->name.len,
1692 l->port_no, l->proto);
1693 /* make sure next_si doesn't point to del_si */
1694 if (del_si==next_si)
1695 next_si=next_si->next;
1697 sock_listrm(list, del_si);
1698 free_sock_info(del_si);
1704 /* check for duplicates in extra_addresses */
1705 for (si=*list;si; si=si->next){
1706 /* check for & remove internal duplicates: */
1707 for (ail=si->addr_info_lst; ail;){
1709 /* 1. check if the extra addresses contain a duplicate for the
1711 if ((ail->address.af==si->address.af) &&
1712 (memcmp(ail->address.u.addr, si->address.u.addr,
1713 ail->address.len) == 0)){
1714 /* add the name to the alias list*/
1715 if ((!(ail->flags& SI_IS_IP)) && (
1716 (ail->name.len!=si->name.len)||
1717 (strncmp(ail->name.s, si->name.s, ail->name.len)!=0)))
1718 add_alias(ail->name.s, ail->name.len, si->port_no,
1721 addr_info_listrm(&si->addr_info_lst, ail);
1722 free_addr_info(ail);
1726 /* 2. check if the extra addresses contain a duplicates for
1727 * other addresses in the same list */
1728 for (tmp_ail=ail->next; tmp_ail;){
1729 tmp_ail_next=tmp_ail->next;
1730 if ((ail->address.af==tmp_ail->address.af) &&
1731 (memcmp(ail->address.u.addr, tmp_ail->address.u.addr,
1732 ail->address.len) == 0)){
1733 /* add the name to the alias list*/
1734 if ((!(tmp_ail->flags& SI_IS_IP)) && (
1735 (ail->name.len!=tmp_ail->name.len)||
1736 (strncmp(ail->name.s, tmp_ail->name.s,
1737 tmp_ail->name.len)!=0))
1739 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1740 si->port_no, si->proto);
1742 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1743 if(ail_next==tmp_ail) {
1744 ail_next = tmp_ail_next;
1746 free_addr_info(tmp_ail);
1748 tmp_ail=tmp_ail_next;
1752 /* check for duplicates between extra addresses (e.g. sctp MH)
1753 * and other main addresses, on conflict remove the corresponding
1754 * extra addresses (another possible solution would be to join
1755 * the 2 si entries into one). */
1756 for (ail=si->addr_info_lst; ail;){
1758 for (l=*list;l; l=l->next){
1759 if (l==si) continue;
1760 if (si->port_no==l->port_no){
1761 if ((ail->address.af==l->address.af) &&
1762 (memcmp(ail->address.u.addr, l->address.u.addr,
1763 ail->address.len) == 0)){
1764 /* add the name to the alias list*/
1765 if ((!(ail->flags& SI_IS_IP)) && (
1766 (ail->name.len!=l->name.len)||
1767 (strncmp(ail->name.s, l->name.s, l->name.len)!=0))
1769 add_alias(ail->name.s, ail->name.len,
1770 l->port_no, l->proto);
1772 addr_info_listrm(&si->addr_info_lst, ail);
1773 free_addr_info(ail);
1776 /* check for duplicates with other extra addresses
1778 for (tmp_ail=l->addr_info_lst; tmp_ail; ){
1779 tmp_ail_next=tmp_ail->next;
1780 if ((ail->address.af==tmp_ail->address.af) &&
1781 (memcmp(ail->address.u.addr,
1782 tmp_ail->address.u.addr,
1783 ail->address.len) == 0)){
1784 /* add the name to the alias list*/
1785 if ((!(tmp_ail->flags& SI_IS_IP)) && (
1786 (ail->name.len!=tmp_ail->name.len)||
1787 (strncmp(ail->name.s, tmp_ail->name.s,
1788 tmp_ail->name.len)!=0))
1790 add_alias(tmp_ail->name.s, tmp_ail->name.len,
1791 l->port_no, l->proto);
1793 addr_info_listrm(&l->addr_info_lst, tmp_ail);
1794 free_addr_info(tmp_ail);
1796 tmp_ail=tmp_ail_next;
1805 /* Remove invalid multicast entries */
1808 if ((si->proto == PROTO_TCP)
1810 || (si->proto == PROTO_TLS)
1811 #endif /* USE_TLS */
1813 || (si->proto == PROTO_SCTP)
1816 if (si->flags & SI_IS_MCAST){
1817 LM_WARN("removing entry %s:%s [%s]:%s\n",
1818 get_valid_proto_name(si->proto), si->name.s,
1819 si->address_str.s, si->port_no_str.s);
1822 sock_listrm(list, l);
1825 ail=si->addr_info_lst;
1827 if (ail->flags & SI_IS_MCAST){
1828 LM_WARN("removing mh entry %s:%s"
1830 get_valid_proto_name(si->proto), ail->name.s,
1831 ail->address_str.s, si->port_no_str.s);
1834 addr_info_listrm(&si->addr_info_lst, tmp_ail);
1835 free_addr_info(tmp_ail);
1846 #endif /* USE_MCAST */
1853 int socket_types = 0;
1855 /* fix all 3 socket lists, fills socket_types if non-null
1856 * return 0 on success, -1 on error */
1857 int fix_all_socket_lists()
1859 struct utsname myname;
1861 struct addr_info* ai_lst;
1876 /* get all listening ipv4/ipv6 interfaces */
1877 if ( ( (add_interfaces(0, AF_INET, 0, PROTO_UDP, &ai_lst)==0)
1879 && (!auto_bind_ipv6 || add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0)
1881 && ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0, PROTO_UDP, &ai_lst) ==0 ) /* add_interface does not work for IPv6 on Linux */
1882 #endif /* __OS_linux */
1883 ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, 0, 0, 0, &udp_listen)==0)){
1884 free_addr_info_lst(&ai_lst);
1886 /* if ok, try to add the others too */
1889 if ( ((add_interfaces(0, AF_INET, 0, PROTO_TCP, &ai_lst)!=0)
1891 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TCP, &ai_lst) != 0)
1893 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_TCP, &ai_lst) !=0 )
1894 #endif /* __OS_linux */
1895 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0, 0, 0, 0,
1898 free_addr_info_lst(&ai_lst);
1902 if (((add_interfaces(0, AF_INET, 0, PROTO_TLS,
1905 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TLS, &ai_lst) != 0)
1907 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_TLS, &ai_lst)!=0)
1908 #endif /* __OS_linux */
1909 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0, 0, 0, 0,
1913 free_addr_info_lst(&ai_lst);
1920 if (((add_interfaces(0, AF_INET, 0, PROTO_SCTP, &ai_lst)!=0)
1922 || (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1924 || (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
1925 #endif /* __OS_linux */
1926 ) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0, 0, 0, 0,
1929 free_addr_info_lst(&ai_lst);
1932 #endif /* USE_SCTP */
1934 /* if error fall back to get hostname */
1935 /* get our address, only the first one */
1936 if (uname (&myname) <0){
1937 LM_ERR("cannot determine hostname, try -l address\n");
1940 if (add_listen_iface(myname.nodename, 0, 0, 0, 0)!=0){
1941 LM_ERR("add_listen_iface failed \n");
1947 if (fix_socket_list(&udp_listen, &flags)!=0){
1948 LM_ERR("fix_socket_list udp failed\n");
1952 socket_types|=flags|SOCKET_T_UDP;
1956 if (!tcp_disable && (fix_socket_list(&tcp_listen, &flags)!=0)){
1957 LM_ERR("fix_socket_list tcp failed\n");
1961 socket_types|=flags|SOCKET_T_TCP;
1965 if (!tls_disable && (fix_socket_list(&tls_listen, &flags)!=0)){
1966 LM_ERR("fix_socket_list tls failed\n");
1970 socket_types|=flags|SOCKET_T_TLS;
1976 if (!sctp_disable && (fix_socket_list(&sctp_listen, &flags)!=0)){
1977 LM_ERR("fix_socket_list sctp failed\n");
1981 socket_types|=flags|SOCKET_T_SCTP;
1983 #endif /* USE_SCTP */
1995 LM_ERR("no listening sockets\n");
2000 if (ai_lst) free_addr_info_lst(&ai_lst);
2006 void print_all_socket_lists()
2008 struct socket_info *si;
2009 struct socket_info** list;
2010 struct addr_info* ai;
2011 unsigned short proto;
2015 list=get_sock_info_list(proto);
2016 for(si=list?*list:0; si; si=si->next){
2017 if (si->addr_info_lst){
2019 get_valid_proto_name(proto),
2021 for (ai=si->addr_info_lst; ai; ai=ai->next) {
2022 printf(", %s", ai->address_str.s);
2024 printf("):%s%s%s\n",
2026 si->flags & SI_IS_MCAST ? " mcast" : "",
2027 si->flags & SI_IS_MHOMED? " mhomed" : "");
2030 get_valid_proto_name(proto),
2032 if (!(si->flags & SI_IS_IP)) {
2033 printf(" [%s]", si->address_str.s);
2037 si->flags & SI_IS_MCAST ? " mcast" : "",
2038 si->flags & SI_IS_MHOMED? " mhomed" : "");
2039 if (si->sockname.s) {
2040 printf(" name %s", si->sockname.s);
2042 if (si->useinfo.name.s) {
2043 printf(" advertise %s:%d", si->useinfo.name.s, si->useinfo.port_no);
2048 }while((proto=next_proto(proto)));
2052 void print_aliases()
2054 struct host_alias* a;
2056 for(a=aliases; a; a=a->next) {
2058 printf(" %s: %.*s:%d\n", get_valid_proto_name(a->proto),
2059 a->alias.len, a->alias.s, a->port);
2061 printf(" %s: %.*s:*\n", get_valid_proto_name(a->proto),
2062 a->alias.len, a->alias.s);
2069 void init_proto_order()
2073 /* fix proto list (remove disabled protocols)*/
2077 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2078 if (nxt_proto[r]==PROTO_TCP)
2079 nxt_proto[r]=nxt_proto[PROTO_TCP];
2083 if (tls_disable || tcp_disable)
2086 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2087 if (nxt_proto[r]==PROTO_TLS)
2088 nxt_proto[r]=nxt_proto[PROTO_TLS];
2093 for(r=PROTO_NONE; r<=PROTO_LAST; r++){
2094 if (nxt_proto[r]==PROTO_SCTP)
2095 nxt_proto[r]=nxt_proto[PROTO_SCTP];
2098 /* Deliberately skipping PROTO_WS and PROTO_WSS here as these
2099 are just upgraded TCP and TLS connections */
2104 * parse '[port:]host[:port]' string to a broken down structure
2106 int parse_protohostport(str* ins, sr_phostp_t *r)
2108 char* first; /* first ':' occurrence */
2109 char* second; /* second ':' occurrence */
2116 memset(r, 0, sizeof(sr_phostp_t));
2118 /* find the first 2 ':', ignoring possible ipv6 addresses
2119 * (substrings between [])
2121 for(p=ins->s; p<ins->s+ins->len; p++){
2125 if (bracket>1) goto error_brackets;
2129 if (bracket<0) goto error_brackets;
2133 if (first==0) first=p;
2134 else if( second==0) second=p;
2135 else goto error_colons;
2140 if (p==ins->s) return -1;
2141 if (*(p-1)==':') goto error_colons;
2143 if (first==0) { /* no ':' => only host */
2145 r->host.len=(int)(p-ins->s);
2148 if (second) { /* 2 ':' found => check if valid */
2149 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2153 tmp.len=(ins->s + ins->len) - tmp.s;
2155 if (str2int(&tmp, (unsigned int *)&(r->port))<0) goto error_port;
2158 r->host.len=(int)(second-r->host.s);
2161 /* only 1 ':' found => it's either proto:host or host:port */
2163 tmp.len=(ins->s + ins->len) - tmp.s;
2164 if (str2int(&tmp, (unsigned int *)&(r->port))<0) {
2165 /* invalid port => it's proto:host */
2166 if (parse_proto((unsigned char*)ins->s, first-ins->s, &r->proto)<0)
2169 r->host.len=(int)(p-r->host.s);
2171 /* valid port => its host:port */
2173 r->host.len=(int)(first-r->host.s);
2178 LM_ERR("too many brackets in %.*s\n", ins->len, ins->s);
2181 LM_ERR("too many colons in %.*s\n", ins->len, ins->s);
2184 LM_ERR("bad protocol in %.*s\n", ins->len, ins->s);
2187 LM_ERR("bad port number in %.*s\n", ins->len, ins->s);
2192 * lookup a local socket by '[port:]host[:port]' string
2194 struct socket_info* lookup_local_socket(str *phostp)
2197 if(parse_protohostport(phostp, &r)<0)
2199 return grep_sock_info(&r.host, (unsigned short)r.port,
2200 (unsigned short)r.proto);