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