Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,2060 +0,0 @@
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
-#ifdef HAVE_SYS_SOCKIO_H
46
-#include <sys/sockio.h>
47
-#endif
48
-
49
-#include "globals.h"
50
-#include "socket_info.h"
51
-#include "dprint.h"
52
-#include "mem/mem.h"
53
-#include "ut.h"
54
-#include "resolve.h"
55
-#include "name_alias.h"
56
-
57
-
58
-
59
-/* list manip. functions (internal use only) */
60
-
61
-
62
-/* append */
63
-#define sock_listadd(head, el) \
64
-	do{\
65
-		if (*(head)==0) *(head)=(el); \
66
-		else{ \
67
-			for((el)->next=*(head); (el)->next->next;\
68
-					(el)->next=(el)->next->next); \
69
-			(el)->next->next=(el); \
70
-			(el)->prev=(el)->next; \
71
-			(el)->next=0; \
72
-		}\
73
-	}while(0)
74
-
75
-
76
-/* insert after "after" */
77
-#define sock_listins(el, after) \
78
-	do{ \
79
-		if ((after)){\
80
-			(el)->next=(after)->next; \
81
-			if ((after)->next) (after)->next->prev=(el); \
82
-			(after)->next=(el); \
83
-			(el)->prev=(after); \
84
-		}else{ /* after==0 = list head */ \
85
-			(after)=(el); \
86
-			(el)->next=(el)->prev=0; \
87
-		}\
88
-	}while(0)
89
-
90
-
91
-#define sock_listrm(head, el) \
92
-	do {\
93
-		if (*(head)==(el)) *(head)=(el)->next; \
94
-		if ((el)->next) (el)->next->prev=(el)->prev; \
95
-		if ((el)->prev) (el)->prev->next=(el)->next; \
96
-	}while(0)
97
-
98
-
99
-#define addr_info_listadd sock_listadd
100
-#define addr_info_listins sock_listins
101
-#define addr_info_listrm sock_listrm
102
-
103
-inline static void addr_info_list_ins_lst(struct addr_info* lst,
104
-										struct addr_info* after)
105
-{
106
-	struct addr_info* l;
107
-	struct addr_info* n;
108
-	
109
-	if (lst){
110
-		n=after->next;
111
-		after->next=lst;
112
-		lst->prev=after;
113
-		if (n){
114
-			for(l=lst; l->next; l=l->next);
115
-			l->next=n;
116
-			n->prev=l;
117
-		}
118
-	}
119
-}
120
-
121
-
122
-/* protocol order, filled by init_proto_order() */
123
-enum sip_protos nxt_proto[PROTO_LAST+1]=
124
-{ PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP, 0 };
125
-/* Deliberately left PROTO_WS and PROTO_WSS out of this as they are just
126
-   upgraded TCP and TLS connections */
127
-
128
-
129
-
130
-/* another helper function, it just fills a struct addr_info
131
- * returns: 0 on success, -1 on error*/
132
-static int init_addr_info(struct addr_info* a,
133
-								char* name, enum si_flags flags)
134
-{
135
-
136
-	memset(a, 0, sizeof(*a));
137
-	a->name.len=strlen(name);
138
-	a->name.s=pkg_malloc(a->name.len+1); /* include \0 */
139
-	if (a->name.s==0) goto error;
140
-	memcpy(a->name.s, name, a->name.len+1);
141
-	a->flags=flags;
142
-	return 0;
143
-error:
144
-	LM_ERR("memory allocation error\n");
145
-	return -1;
146
-}
147
-
148
-
149
-
150
-/* returns 0 on error, new addr_info_lst element on success */
151
-static inline struct addr_info* new_addr_info(char* name, 
152
-													enum si_flags gf)
153
-{
154
-	struct addr_info* al;
155
-	
156
-	al=pkg_malloc(sizeof(*al));
157
-	if (al==0) goto error;
158
-	al->next=0;
159
-	al->prev=0;
160
-	if (init_addr_info(al, name, gf)!=0) goto error;
161
-	return al;
162
-error:
163
-	LM_ERR("memory allocation error\n");
164
-	if (al){
165
-		if (al->name.s) pkg_free(al->name.s);
166
-		pkg_free(al);
167
-	}
168
-	return 0;
169
-}
170
-
171
-
172
-
173
-static inline void free_addr_info(struct addr_info* a)
174
-{
175
-	if (a){
176
-		if (a->name.s){
177
-			pkg_free(a->name.s);
178
-			a->name.s=0;
179
-		}
180
-		pkg_free(a);
181
-	}
182
-}
183
-
184
-
185
-
186
-static inline void free_addr_info_lst(struct addr_info** lst)
187
-{
188
-	struct addr_info* a;
189
-	struct addr_info* tmp;
190
-	
191
-	a=*lst;
192
-	while(a){
193
-		tmp=a;
194
-		a=a->next;
195
-		free_addr_info(tmp);
196
-	}
197
-}
198
-
199
-
200
-
201
-/* adds a new add_info_lst element to the corresponding list
202
- * returns 0 on success, -1 on error */
203
-static int new_addr_info2list(char* name, enum si_flags f,
204
-								struct addr_info** l)
205
-{
206
-	struct addr_info * al;
207
-	
208
-	al=new_addr_info(name, f);
209
-	if (al==0) goto error;
210
-	addr_info_listadd(l, al);
211
-	return 0;
212
-error:
213
-	return -1;
214
-}
215
-
216
-
217
-
218
-/* another helper function, it just creates a socket_info struct */
219
-static inline struct socket_info* new_sock_info(	char* name,
220
-								struct name_lst* addr_l,
221
-								unsigned short port, unsigned short proto,
222
-								char *usename, unsigned short useport,
223
-								enum si_flags flags)
224
-{
225
-	struct socket_info* si;
226
-	struct name_lst* n;
227
-	struct hostent* he;
228
-	char *p;
229
-	
230
-	si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
231
-	if (si==0) goto error;
232
-	memset(si, 0, sizeof(struct socket_info));
233
-	si->socket=-1;
234
-	si->name.len=strlen(name);
235
-	si->name.s=(char*)pkg_malloc(si->name.len+1); /* include \0 */
236
-	if (si->name.s==0) goto error;
237
-	memcpy(si->name.s, name, si->name.len+1);
238
-	/* set port & proto */
239
-	si->port_no=port;
240
-	si->proto=proto;
241
-	si->flags=flags;
242
-	si->addr_info_lst=0;
243
-	for (n=addr_l; n; n=n->next){
244
-		if (new_addr_info2list(n->name, n->flags, &si->addr_info_lst)!=0){
245
-			LM_ERR("new_addr_info2list failed\n");
246
-			goto error;
247
-		}
248
-	}
249
-	if(usename!=NULL)
250
-	{
251
-		si->useinfo.name.len=strlen(usename);
252
-		si->useinfo.name.s=(char*)pkg_malloc(si->useinfo.name.len+1);
253
-		if (si->useinfo.name.s==0)
254
-			goto error;
255
-		strcpy(si->useinfo.name.s, usename);
256
-		if(usename[0]=='[' && usename[si->useinfo.name.len-1]==']')
257
-		{
258
-			si->useinfo.address_str.len = si->useinfo.name.len - 2;
259
-			p = si->useinfo.name.s + 1;
260
-		} else {
261
-			si->useinfo.address_str.len = si->useinfo.name.len;
262
-			p = si->useinfo.name.s;
263
-		}
264
-		si->useinfo.address_str.s=(char*)pkg_malloc(si->useinfo.address_str.len+1);
265
-		if(si->useinfo.address_str.s==NULL)
266
-			goto error;
267
-		strncpy(si->useinfo.address_str.s, p, si->useinfo.address_str.len);
268
-		si->useinfo.address_str.s[si->useinfo.address_str.len] = '\0';
269
-
270
-		p = int2str(useport, &si->useinfo.port_no_str.len);
271
-		if(p==NULL)
272
-			goto error;
273
-		si->useinfo.port_no_str.s=(char*)pkg_malloc(si->useinfo.port_no_str.len+1);
274
-		if(si->useinfo.port_no_str.s==NULL)
275
-			goto error;
276
-		strcpy(si->useinfo.port_no_str.s, p);
277
-		si->useinfo.port_no = useport;
278
-
279
-		he=resolvehost(si->useinfo.name.s);
280
-		if (he==0){
281
-			LM_ERR("unable to resolve advertised name %s\n", si->useinfo.name.s);
282
-			goto error;
283
-		}
284
-		hostent2ip_addr(&si->useinfo.address, he, 0);
285
-	}
286
-	return si;
287
-error:
288
-	LM_ERR("memory allocation error\n");
289
-	if (si) {
290
-		if(si->name.s)
291
-			pkg_free(si->name.s);
292
-		pkg_free(si);
293
-	}
294
-	return 0;
295
-}
296
-
297
-
298
-
299
-/*  delete a socket_info struct */
300
-static void free_sock_info(struct socket_info* si)
301
-{
302
-	if(si){
303
-		if(si->name.s) pkg_free(si->name.s);
304
-		if(si->address_str.s) pkg_free(si->address_str.s);
305
-		if(si->port_no_str.s) pkg_free(si->port_no_str.s);
306
-		if(si->addr_info_lst) free_addr_info_lst(&si->addr_info_lst);
307
-		if(si->sock_str.s) pkg_free(si->sock_str.s);
308
-		if(si->useinfo.name.s) pkg_free(si->useinfo.name.s);
309
-		if(si->useinfo.port_no_str.s) pkg_free(si->useinfo.port_no_str.s);
310
-		if(si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
311
-	}
312
-}
313
-
314
-
315
-
316
-char* get_valid_proto_name(unsigned short proto)
317
-{
318
-	switch(proto){
319
-		case PROTO_NONE:
320
-			return "*";
321
-		case PROTO_UDP:
322
-			return "udp";
323
-#ifdef USE_TCP
324
-		case PROTO_TCP:
325
-			return "tcp";
326
-#endif
327
-#ifdef USE_TLS
328
-		case PROTO_TLS:
329
-			return "tls";
330
-#endif
331
-#ifdef USE_SCTP
332
-		case PROTO_SCTP:
333
-			return "sctp";
334
-#endif
335
-		default:
336
-			return "unknown";
337
-	}
338
-}
339
-
340
-/** Convert socket to its textual representation.
341
- *
342
- * This function converts the transport protocol, the IP address and the port
343
- * number in a comma delimited string of form proto:ip:port. The resulting
344
- * string is NOT zero terminated
345
- *
346
- * @param s is a pointer to the destination memory buffer
347
- * @param len is a pointer to an integer variable. Initially the variable
348
- *        should contain the size of the buffer in s. The value of the variable
349
- *        will be changed to the length of the resulting string on success and
350
- *        to the desired size of the destination buffer if it is too small
351
- * @param si is a pointer to the socket_info structure to be printed
352
- * @return -1 on error and 0 on success
353
- */
354
-int socket2str(char* s, int* len, struct socket_info* si)
355
-{
356
-	return socketinfo2str(s, len, si, 0);
357
-}
358
-
359
-int socketinfo2str(char* s, int* len, struct socket_info* si, int mode)
360
-{
361
-	str proto;
362
-	int l;
363
-	
364
-	proto.s = get_valid_proto_name(si->proto);
365
-	proto.len = strlen(proto.s);
366
-	
367
-	if(mode==1)
368
-		l = proto.len + si->useinfo.name.len + si->useinfo.port_no_str.len + 2;
369
-	else
370
-		l = proto.len + si->address_str.len + si->port_no_str.len + 2;
371
-
372
-	if(si->address.af==AF_INET6)
373
-		l += 2;
374
-	
375
-	if (*len < l) {
376
-		LM_ERR("Destionation buffer too short\n");
377
-		*len = l;
378
-		return -1;
379
-	}
380
-	
381
-	memcpy(s, proto.s, proto.len);
382
-	s += proto.len;
383
-	*s = ':'; s++;
384
-	if(mode==1){
385
-		memcpy(s, si->useinfo.name.s, si->useinfo.name.len);
386
-		s += si->useinfo.name.len;
387
-		*s = ':'; s++;
388
-		memcpy(s, si->useinfo.port_no_str.s, si->useinfo.port_no_str.len);
389
-		s += si->useinfo.port_no_str.len;
390
-	} else {
391
-		if(si->address.af==AF_INET6) {
392
-			*s = '['; s++;
393
-		}
394
-		memcpy(s, si->address_str.s, si->address_str.len);
395
-		s += si->address_str.len;
396
-		if(si->address.af==AF_INET6) {
397
-			*s = ']'; s++;
398
-		}
399
-		*s = ':'; s++;
400
-		memcpy(s, si->port_no_str.s, si->port_no_str.len);
401
-		s += si->port_no_str.len;
402
-	}
403
-
404
-	*len = l;
405
-	return 0;
406
-}
407
-
408
-
409
-
410
-/* Fill si->sock_str with string representing the socket_info structure,
411
- * format of the string is 'proto:address:port'. Returns 0 on success and
412
- * negative number on failure.
413
- */
414
-static int fix_sock_str(struct socket_info* si)
415
-{
416
-	int len = MAX_SOCKET_STR;
417
-
418
-	if (si->sock_str.s) pkg_free(si->sock_str.s);
419
-	
420
-	si->sock_str.s = pkg_malloc(len + 1);
421
-	if (si->sock_str.s == NULL) {
422
-		LM_ERR("No memory left\n");
423
-		return -1;
424
-	}
425
-	if (socketinfo2str(si->sock_str.s, &len, si, 0) < 0) {
426
-		BUG("fix_sock_str: Error in socket to str\n");
427
-		return -1;
428
-	}
429
-	si->sock_str.s[len] = '\0';
430
-	si->sock_str.len = len;
431
-	if(si->useinfo.name.s!=NULL)
432
-	{
433
-		len = MAX_SOCKET_STR;
434
-
435
-		if (si->useinfo.sock_str.s) pkg_free(si->useinfo.sock_str.s);
436
-
437
-		si->useinfo.sock_str.s = pkg_malloc(len + 1);
438
-		if (si->useinfo.sock_str.s == NULL) {
439
-			LM_ERR("No memory left\n");
440
-			return -1;
441
-		}
442
-		if (socketinfo2str(si->useinfo.sock_str.s, &len, si, 1) < 0) {
443
-			BUG("fix_sock_str: Error in socket to str\n");
444
-			return -1;
445
-		}
446
-		si->useinfo.sock_str.s[len] = '\0';
447
-		si->useinfo.sock_str.len = len;
448
-	}
449
-	return 0;
450
-}
451
-
452
-
453
-/* returns 0 if support for the protocol is not compiled or if proto is 
454
-   invalid */
455
-struct socket_info** get_sock_info_list(unsigned short proto)
456
-{
457
-	
458
-	switch(proto){
459
-		case PROTO_UDP:
460
-			return &udp_listen;
461
-			break;
462
-		case PROTO_TCP:
463
-		case PROTO_WS:
464
-#ifdef USE_TCP
465
-			return &tcp_listen;
466
-#endif
467
-			break;
468
-		case PROTO_TLS:
469
-		case PROTO_WSS:
470
-#ifdef USE_TLS
471
-			return &tls_listen;
472
-#endif
473
-			break;
474
-		case PROTO_SCTP:
475
-#ifdef USE_SCTP
476
-			return &sctp_listen;
477
-#endif
478
-			break;
479
-		default:
480
-			LM_CRIT("invalid proto %d\n", proto);
481
-	}
482
-	return 0;
483
-}
484
-
485
-
486
-/* helper function for grep_sock_info
487
- * params:
488
- *  host - hostname to compare with
489
- *  name - official name
490
- *  addr_str - name's resolved ip address converted to string
491
- *  ip_addr - name's ip address 
492
- *  flags - set to SI_IS_IP if name contains an IP
493
- *
494
- * returns 0 if host matches, -1 if not */
495
-inline static int si_hname_cmp(str* host, str* name, str* addr_str, 
496
-								struct ip_addr* ip_addr, int flags)
497
-{
498
-	struct ip_addr* ip6;
499
-	
500
-	if ( (host->len==name->len) && 
501
-		(strncasecmp(host->s, name->s, name->len)==0) /*slower*/)
502
-		/* comp. must be case insensitive, host names
503
-		 * can be written in mixed case, it will also match
504
-		 * ipv6 addresses if we are lucky*/
505
-		goto found;
506
-	/* check if host == ip address */
507
-	/* ipv6 case is uglier, host can be [3ffe::1] */
508
-	ip6=str2ip6(host);
509
-	if (ip6){
510
-		if (ip_addr_cmp(ip6, ip_addr))
511
-			goto found; /* match */
512
-		else
513
-			return -1; /* no match, but this is an ipv6 address
514
-						 so no point in trying ipv4 */
515
-	}
516
-	/* ipv4 */
517
-	if ( (!(flags&SI_IS_IP)) && (host->len==addr_str->len) && 
518
-			(memcmp(host->s, addr_str->s, addr_str->len)==0) )
519
-		goto found;
520
-	return -1;
521
-found:
522
-	return 0;
523
-}
524
-
525
-
526
-/* checks if the proto: host:port is one of the address we listen on
527
- * and returns the corresponding socket_info structure.
528
- * if port==0, the  port number is ignored
529
- * if proto==0 (PROTO_NONE) the protocol is ignored
530
- * returns  0 if not found
531
- * WARNING: uses str2ip6 so it will overwrite any previous
532
- *  unsaved result of this function (static buffer)
533
- */
534
-struct socket_info* grep_sock_info(str* host, unsigned short port,
535
-												unsigned short proto)
536
-{
537
-	str hname;
538
-	struct socket_info* si;
539
-	struct socket_info** list;
540
-	struct addr_info* ai;
541
-	unsigned short c_proto;
542
-	
543
-	hname=*host;
544
-	if ((hname.len>2)&&((*hname.s)=='[')&&(hname.s[hname.len-1]==']')){
545
-		/* ipv6 reference, skip [] */
546
-		hname.s++;
547
-		hname.len-=2;
548
-	}
549
-
550
-	c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
551
-retry:
552
-	do{
553
-		/* get the proper sock_list */
554
-		list=get_sock_info_list(c_proto);
555
-	
556
-		if (list==0) /* disabled or unknown protocol */
557
-			continue;
558
-		for (si=*list; si; si=si->next){
559
-			LM_DBG("checking if host==us: %d==%d && [%.*s] == [%.*s]\n",
560
-						hname.len,
561
-						si->name.len,
562
-						hname.len, hname.s,
563
-						si->name.len, si->name.s
564
-				);
565
-			if (port) {
566
-				LM_DBG("checking if port %d (advertise %d) matches port %d\n",
567
-						si->port_no, si->useinfo.port_no, port);
568
-				if (si->port_no!=port && si->useinfo.port_no!=port) {
569
-					continue;
570
-				}
571
-			}
572
-			if (si_hname_cmp(&hname, &si->name, &si->address_str, 
573
-								&si->address, si->flags)==0)
574
-				goto found;
575
-			if(si->useinfo.name.s!=NULL)
576
-			{
577
-				LM_DBG("checking advertise if host==us:"
578
-						" %d==%d && [%.*s] == [%.*s]\n",
579
-						hname.len,
580
-						si->useinfo.name.len,
581
-						hname.len, hname.s,
582
-						si->useinfo.name.len, si->useinfo.name.s
583
-				);
584
-				if (si_hname_cmp(&hname, &si->useinfo.name,
585
-							&si->useinfo.address_str, &si->useinfo.address,
586
-							si->flags)==0)
587
-					goto found;
588
-			}
589
-			/* try among the extra addresses */
590
-			for (ai=si->addr_info_lst; ai; ai=ai->next)
591
-				if (si_hname_cmp(&hname, &ai->name, &ai->address_str, 
592
-									&ai->address, ai->flags)==0)
593
-					goto found;
594
-		}
595
-
596
-	}while( (proto==0) && (c_proto=next_proto(c_proto)) );
597
-
598
-#ifdef USE_TLS
599
-	if (unlikely(c_proto == PROTO_WS)) {
600
-		c_proto = PROTO_WSS;
601
-		goto retry;
602
-	}
603
-#endif
604
-/* not_found: */
605
-	return 0;
606
-found:
607
-	return si;
608
-}
609
-
610
-/* checks if the proto:port is one of the ports we listen on
611
- * and returns the corresponding socket_info structure.
612
- * if proto==0 (PROTO_NONE) the protocol is ignored
613
- * returns  0 if not found
614
- */
615
-struct socket_info* grep_sock_info_by_port(unsigned short port, 
616
-											unsigned short proto)
617
-{
618
-	struct socket_info* si;
619
-	struct socket_info** list;
620
-	unsigned short c_proto;
621
-
622
-	if (!port) {
623
-		goto not_found;
624
-	}
625
-	c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
626
-	do{
627
-		/* get the proper sock_list */
628
-		list=get_sock_info_list(c_proto);
629
-	
630
-		if (list==0) /* disabled or unknown protocol */
631
-			continue;
632
-		
633
-		for (si=*list; si; si=si->next){
634
-			LM_DBG("checking if port %d matches port %d\n", si->port_no, port);
635
-			if (si->port_no==port) {
636
-				goto found;
637
-			}
638
-		}
639
-	}while( (proto==0) && (c_proto=next_proto(c_proto)) );
640
-not_found:
641
-	return 0;
642
-found:
643
-	return si;
644
-}
645
-
646
-
647
-
648
-/* checks if the proto: ip:port is one of the address we listen on
649
- * and returns the corresponding socket_info structure.
650
- * (same as grep_socket_info, but use ip addr instead)
651
- * if port==0, the  port number is ignored
652
- * if proto==0 (PROTO_NONE) the protocol is ignored
653
- * returns  0 if not found
654
- * WARNING: uses str2ip6 so it will overwrite any previous
655
- *  unsaved result of this function (static buffer)
656
- */
657
-struct socket_info* find_si(struct ip_addr* ip, unsigned short port,
658
-												unsigned short proto)
659
-{
660
-	struct socket_info* si;
661
-	struct socket_info** list;
662
-	struct addr_info* ai;
663
-	unsigned short c_proto;
664
-	
665
-	c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
666
-	do{
667
-		/* get the proper sock_list */
668
-		list=get_sock_info_list(c_proto);
669
-	
670
-		if (list==0) /* disabled or unknown protocol */
671
-			continue;
672
-		
673
-		for (si=*list; si; si=si->next){
674
-			if (port) {
675
-				if (si->port_no!=port) {
676
-					continue;
677
-				}
678
-			}
679
-			if (ip_addr_cmp(ip, &si->address)
680
-					|| ip_addr_cmp(ip, &si->useinfo.address))
681
-				goto found;
682
-			for (ai=si->addr_info_lst; ai; ai=ai->next)
683
-				if (ip_addr_cmp(ip, &ai->address))
684
-					goto found;
685
-		}
686
-	}while( (proto==0) && (c_proto=next_proto(c_proto)) );
687
-/* not_found: */
688
-	return 0;
689
-found:
690
-	return si;
691
-}
692
-
693
-
694
-
695
-/* append a new sock_info structure to the corresponding list
696
- * return  new sock info on success, 0 on error */
697
-static struct socket_info* new_sock2list(char* name, struct name_lst* addr_l,
698
-									unsigned short port,
699
-									unsigned short proto,
700
-									char *usename, unsigned short useport,
701
-									enum si_flags flags,
702
-									struct socket_info** list)
703
-{
704
-	struct socket_info* si;
705
-	
706
-	si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
707
-	if (si==0){
708
-		LM_ERR("new_sock_info failed\n");
709
-		goto error;
710
-	}
711
-	if(socket_workers>0) {
712
-		si->workers = socket_workers;
713
-		socket_workers = 0;
714
-	}
715
-#ifdef USE_MCAST
716
-	if (mcast!=0) {
717
-		si->mcast.len=strlen(mcast);
718
-		si->mcast.s=(char*)pkg_malloc(si->mcast.len+1);
719
-		strcpy(si->mcast.s, mcast);
720
-		mcast = 0;
721
-	}
722
-#endif /* USE_MCAST */
723
-	sock_listadd(list, si);
724
-	return si;
725
-error:
726
-	return 0;
727
-}
728
-
729
-
730
-
731
-/* adds a new sock_info structure immediately after "after"
732
- * return  new sock info on success, 0 on error */
733
-static struct socket_info* new_sock2list_after(char* name,
734
-									struct name_lst* addr_l,
735
-									unsigned short port,
736
-									unsigned short proto,
737
-									char *usename,
738
-									unsigned short useport,
739
-									enum si_flags flags,
740
-									struct socket_info* after)
741
-{
742
-	struct socket_info* si;
743
-	
744
-	si=new_sock_info(name, addr_l, port, proto, usename, useport, flags);
745
-	if (si==0){
746
-		LM_ERR("new_sock_info failed\n");
747
-		goto error;
748
-	}
749
-	sock_listins(si, after);
750
-	return si;
751
-error:
752
-	return 0;
753
-}
754
-
755
-
756
-
757
-/* adds a sock_info structure to the corresponding proto list
758
- * return  0 on success, -1 on error */
759
-int add_listen_advertise_iface(char* name, struct name_lst* addr_l,
760
-						unsigned short port, unsigned short proto,
761
-						char *usename, unsigned short useport,
762
-						enum si_flags flags)
763
-{
764
-	struct socket_info** list;
765
-	unsigned short c_proto;
766
-	struct name_lst* a_l;
767
-	unsigned short c_port;
768
-	
769
-	c_proto=(proto!=PROTO_NONE)?proto:PROTO_UDP;
770
-	do{
771
-		list=get_sock_info_list(c_proto);
772
-		if (list==0) /* disabled or unknown protocol */
773
-			continue;
774
-		
775
-		if (port==0){ /* use default port */
776
-			c_port=
777
-#ifdef USE_TLS
778
-				((c_proto)==PROTO_TLS)?tls_port_no:
779
-#endif
780
-				port_no;
781
-		}
782
-#ifdef USE_TLS
783
-		else if ((c_proto==PROTO_TLS) && (proto==0)){
784
-			/* -l  ip:port => on udp:ip:port; tcp:ip:port and tls:ip:port+1?*/
785
-			c_port=port+1;
786
-		}
787
-#endif
788
-		else{
789
-			c_port=port;
790
-		}
791
-		if (c_proto!=PROTO_SCTP){
792
-			if (new_sock2list(name, 0, c_port, c_proto, usename, useport,
793
-								flags & ~SI_IS_MHOMED, list)==0){
794
-				LM_ERR("new_sock2list failed\n");
795
-				goto error;
796
-			}
797
-			/* add the other addresses in the list as separate sockets
798
-			 * since only SCTP can bind to multiple addresses */
799
-			for (a_l=addr_l; a_l; a_l=a_l->next){
800
-				if (new_sock2list(a_l->name, 0, c_port, 
801
-									c_proto, usename, useport,
802
-									flags & ~SI_IS_MHOMED, list)==0){
803
-					LM_ERR("new_sock2list failed\n");
804
-					goto error;
805
-				}
806
-			}
807
-		}else{
808
-			if (new_sock2list(name, addr_l, c_port, c_proto, usename, useport,
809
-						flags, list)==0){
810
-				LM_ERR("new_sock2list failed\n");
811
-				goto error;
812
-			}
813
-		}
814
-	}while( (proto==0) && (c_proto=next_proto(c_proto)));
815
-	return 0;
816
-error:
817
-	return -1;
818
-}
819
-
820
-/* adds a sock_info structure to the corresponding proto list
821
- * return  0 on success, -1 on error */
822
-int add_listen_iface(char* name, struct name_lst* addr_l,
823
-						unsigned short port, unsigned short proto,
824
-						enum si_flags flags)
825
-{
826
-	return add_listen_advertise_iface(name, addr_l, port, proto, 0, 0, flags);
827
-}
828
-#ifdef __OS_linux
829
-
830
-#include "linux/types.h"
831
-#include "linux/netlink.h"
832
-#include "linux/rtnetlink.h"
833
-#include "arpa/inet.h"
834
-
835
-
836
-#define MAX_IF_LEN 64
837
-struct idx
838
-{
839
-	struct idx * 	next;
840
-	int 		family;
841
-	unsigned	ifa_flags;
842
-	char		addr[MAX_IF_LEN];
843
-
844
-};
845
-
846
-struct idxlist{
847
-	struct idx* 	addresses;
848
-	int 		index;
849
-	char 		name[MAX_IF_LEN];
850
-	unsigned 	flags;
851
-};
852
-
853
-#define MAX_IFACE_NO 32
854
-
855
-static struct idxlist *ifaces = NULL;
856
-static int seq = 0;
857
-
858
-#define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
859
-
860
-#define NLMSG_TAIL(nmsg) \
861
-	((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
862
-
863
-int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
864
-	      int alen)
865
-{
866
-	int len = RTA_LENGTH(alen);
867
-	struct rtattr *rta;
868
-
869
-	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
870
-		fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
871
-		return -1;
872
-	}
873
-	rta = NLMSG_TAIL(n);
874
-	rta->rta_type = type;
875
-	rta->rta_len = len;
876
-	memcpy(RTA_DATA(rta), data, alen);
877
-	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
878
-	return 0;
879
-}
880
-
881
-
882
-
883
-static int nl_bound_sock(void)
884
-{
885
-	int sock;
886
-	struct sockaddr_nl la;
887
-
888
-	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
889
-	if(sock <= 0){
890
-		LM_ERR("could not create NETLINK sock to get interface list");
891
-		goto error;
892
-	}
893
-
894
-	/* bind NETLINK socket to pid */
895
-	bzero(&la, sizeof(la));
896
-	la.nl_family = AF_NETLINK;
897
-	la.nl_pad = 0;
898
-	la.nl_pid = getpid();
899
-	la.nl_groups = 0;
900
-	if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
901
-		LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
902
-		goto error;
903
-	}
904
-
905
-	return sock;
906
-error:
</