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,1705 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License 
17
- * along with this program; if not, write to the Free Software 
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- */
20
-
21
-/*!
22
- * \file
23
- * \brief Kamailio core :: DNS resolver
24
- * \ingroup core
25
- * Module: \ref core
26
- */
27
-
28
-
29
-#include <sys/types.h>
30
-#include <netinet/in.h>
31
-#include <arpa/nameser.h>
32
-#include <resolv.h>
33
-#include <string.h>
34
-
35
-#include "resolve.h"
36
-#include "compiler_opt.h"
37
-#include "dprint.h"
38
-#include "mem/mem.h"
39
-#include "ip_addr.h"
40
-#include "error.h"
41
-#include "globals.h" /* tcp_disable, tls_disable a.s.o */
42
-#include "cfg_core.h"
43
-#include "socket_info.h"
44
-
45
-#ifdef USE_DNS_CACHE
46
-#include "dns_cache.h"
47
-#endif
48
-
49
-/* counters framework */
50
-struct dns_counters_h dns_cnts_h;
51
-counter_def_t dns_cnt_defs[] =  {
52
-	{&dns_cnts_h.failed_dns_req, "failed_dns_request", 0, 0, 0,
53
-		"incremented each time a DNS request has failed."},
54
-	{0, 0, 0, 0, 0, 0 }
55
-};
56
-
57
-/* mallocs for local stuff */
58
-#define local_malloc pkg_malloc
59
-#define local_free   pkg_free
60
-
61
-#ifdef USE_NAPTR
62
-static int naptr_proto_pref[PROTO_LAST+1];
63
-#endif
64
-static int srv_proto_pref[PROTO_LAST+1];
65
-
66
-#ifdef USE_NAPTR
67
-static void init_naptr_proto_prefs()
68
-{
69
-	int ignore_rfc, udp, tcp, tls, sctp;
70
-
71
-	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
72
-		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
73
-		BUG("init_naptr_proto_prefs: array too small \n");
74
-		return;
75
-	}
76
-
77
-	ignore_rfc = cfg_get(core, core_cfg, dns_naptr_ignore_rfc);
78
-	udp = cfg_get(core, core_cfg, dns_udp_pref);
79
-	tcp = cfg_get(core, core_cfg, dns_tcp_pref);
80
-	tls = cfg_get(core, core_cfg, dns_tls_pref);
81
-	sctp = cfg_get(core, core_cfg, dns_sctp_pref);
82
-
83
-	/* Old implementation ignored the Order field in the NAPTR RR and
84
-	 * thus violated a MUST in RFC 2915. Currently still the default. */
85
-	if (ignore_rfc) {
86
-		naptr_proto_pref[PROTO_UDP] = udp;
87
-		naptr_proto_pref[PROTO_TCP] = tcp;
88
-		naptr_proto_pref[PROTO_TLS] = tls;
89
-		naptr_proto_pref[PROTO_SCTP] = sctp;
90
-	} else {
91
-		/* If value is less than 0, proto is disabled, otherwise
92
-		 * ignored. */
93
-		naptr_proto_pref[PROTO_UDP] = udp < 0 ? udp : 1;
94
-		naptr_proto_pref[PROTO_TCP] = tcp < 0 ? tcp : 1;
95
-		naptr_proto_pref[PROTO_TLS] = tls < 0 ? tls : 1;
96
-		naptr_proto_pref[PROTO_SCTP] = sctp < 0 ? sctp : 1;
97
-	}
98
-}
99
-
100
-#endif /* USE_NAPTR */
101
-
102
-static void init_srv_proto_prefs()
103
-{
104
-	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
105
-		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
106
-		BUG("init_srv_proto_prefs: array too small \n");
107
-		return;
108
-	}
109
-
110
-	srv_proto_pref[PROTO_UDP] = cfg_get(core, core_cfg, dns_udp_pref);
111
-	srv_proto_pref[PROTO_TCP] = cfg_get(core, core_cfg, dns_tcp_pref);
112
-	srv_proto_pref[PROTO_TLS] = cfg_get(core, core_cfg, dns_tls_pref);
113
-	srv_proto_pref[PROTO_SCTP] = cfg_get(core, core_cfg, dns_sctp_pref);
114
-}
115
-
116
-#ifdef DNS_WATCHDOG_SUPPORT
117
-static on_resolv_reinit	on_resolv_reinit_cb = NULL;
118
-
119
-/* register the callback function */
120
-int register_resolv_reinit_cb(on_resolv_reinit cb)
121
-{
122
-	if (on_resolv_reinit_cb) {
123
-		LM_ERR("callback function has been already registered\n");
124
-		return -1;
125
-	}
126
-	on_resolv_reinit_cb = cb;
127
-	return 0;
128
-}
129
-#endif
130
-
131
-/* counter init function
132
-  must be called before fork
133
-*/
134
-static int stat_init(void)
135
-{
136
-	if (counter_register_array("dns", dns_cnt_defs) < 0)
137
-		goto error;
138
-	return 0;
139
-error:
140
-	return -1;
141
-}
142
-
143
-/** init. the resolver
144
- * params: retr_time  - time before retransmitting (must be >0)
145
- *         retr_no    - retransmissions number
146
- *         servers_no - how many dns servers will be used
147
- *                      (from the one listed in /etc/resolv.conf)
148
- *         search     - if 0 the search list in /etc/resolv.conf will
149
- *                      be ignored (HINT: even if you don't have a
150
- *                      search list in resolv.conf, it's still better
151
- *                      to set search to 0, because an empty seachlist
152
- *                      means in fact search "" => it takes more time)
153
- * If any of the parameters <0, the default (system specific) value
154
- * will be used. See also resolv.conf(5).
155
- * returns: 0 on success, -1 on error
156
- */
157
-static int _resolv_init(void)
158
-{
159
-	dns_func.sr_res_init();
160
-#ifdef HAVE_RESOLV_RES
161
-	if (cfg_get(core, core_cfg, dns_retr_time)>0)
162
-		_res.retrans=cfg_get(core, core_cfg, dns_retr_time);
163
-	if (cfg_get(core, core_cfg, dns_retr_no)>0)
164
-		_res.retry=cfg_get(core, core_cfg, dns_retr_no);
165
-	if ((cfg_get(core, core_cfg, dns_servers_no)>=0)
166
-		&& (cfg_get(core, core_cfg, dns_servers_no)<_res.nscount))
167
-			_res.nscount=cfg_get(core, core_cfg, dns_servers_no);
168
-	if (cfg_get(core, core_cfg, dns_search_list)==0)
169
-		_res.options&=~(RES_DEFNAMES|RES_DNSRCH);
170
-#else
171
-#warning "no resolv timeout support"
172
-	LM_WARN("no resolv options support - resolv options will be ignored\n");
173
-#endif
174
-	return 0;
175
-}
176
-
177
-/** wrapper function to initialize the resolver at startup */
178
-int resolv_init(void)
179
-{
180
-	int res = -1;
181
-	_resolv_init();
182
-
183
-	reinit_proto_prefs(NULL,NULL);
184
-	/* init counter API only at startup
185
-	 * This function must be called before DNS cache init method (if available)
186
-	 */
187
-	res = stat_init();
188
-	return res;
189
-}
190
-
191
-/** wrapper function to reinitialize the resolver
192
- * This function must be called by each child process whenever
193
- * a resolver option changes
194
- */
195
-void resolv_reinit(str *gname, str *name)
196
-{
197
-	_resolv_init();
198
-
199
-#ifdef DNS_WATCHDOG_SUPPORT
200
-	if (on_resolv_reinit_cb) on_resolv_reinit_cb(name);
201
-#endif
202
-	LM_DBG("DNS resolver has been reinitialized\n");
203
-}
204
-
205
-/** fixup function for dns_reinit variable
206
- * (resets the variable to 0)
207
- */
208
-int dns_reinit_fixup(void *handle, str *gname, str *name, void **val)
209
-{
210
-	*val = (void *)(long)0;
211
-	return 0;
212
-}
213
-
214
-/** wrapper function to recalculate the naptr and srv protocol preferences */
215
-void reinit_proto_prefs(str *gname, str *name)
216
-{
217
-#ifdef USE_NAPTR
218
-	init_naptr_proto_prefs();
219
-#endif
220
-	init_srv_proto_prefs();
221
-}
222
-
223
-/** fixup function for dns_try_ipv6
224
- * verifies that Kamailio really listens on an ipv6 interface
225
- */
226
-int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val)
227
-{
228
-	if ((int)(long)(*val) && !(socket_types & SOCKET_T_IPV6)) {
229
-		LM_ERR("SER does not listen on any ipv6 interface, "
230
-			"there is no point in resolving ipv6 addresses\n");
231
-		return -1;
232
-	}
233
-	return 0;
234
-}
235
-
236
-/**  skips over a domain name in a dns message
237
- *  (it can be  a sequence of labels ending in \0, a pointer or
238
- *   a sequence of labels ending in a pointer -- see rfc1035
239
- *   returns pointer after the domain name or null on error*/
240
-unsigned char* dns_skipname(unsigned char* p, unsigned char* end)
241
-{
242
-	while(p<end){
243
-		/* check if \0 (root label length) */
244
-		if (*p==0){
245
-			p+=1;
246
-			break;
247
-		}
248
-		/* check if we found a pointer */
249
-		if (((*p)&0xc0)==0xc0){
250
-			/* if pointer skip over it (2 bytes) & we found the end */
251
-			p+=2;
252
-			break;
253
-		}
254
-		/* normal label */
255
-		p+=*p+1;
256
-	}
257
-	return (p>end)?0:p;
258
-}
259
-
260
-
261
-
262
-/** parses the srv record into a srv_rdata structure
263
- *   msg   - pointer to the dns message
264
- *   end   - pointer to the end of the message
265
- *   eor   - pointer to the end of the record/rdata
266
- *   rdata - pointer  to the rdata part of the srv answer
267
- * returns 0 on error, or a dyn. alloc'ed srv_rdata structure 
268
- *
269
- * SRV rdata format:
270
- *            111111
271
- *  0123456789012345
272
- * +----------------+
273
- * |     priority   |
274
- * |----------------|
275
- * |     weight     |
276
- * |----------------|
277
- * |   port number  |
278
- * |----------------|
279
- * |                |
280
- * ~      name      ~
281
- * |                |
282
- * +----------------+
283
- */
284
-struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end,
285
-								  unsigned char* eor,
286
-								  unsigned char* rdata)
287
-{
288
-	struct srv_rdata* srv;
289
-	unsigned short priority;
290
-	unsigned short weight;
291
-	unsigned short port;
292
-	int len;
293
-	char name[MAX_DNS_NAME];
294
-	
295
-	srv=0;
296
-	if ((rdata+6+1)>eor) goto error;
297
-	
298
-	memcpy((void*)&priority, rdata, 2);
299
-	memcpy((void*)&weight,   rdata+2, 2);
300
-	memcpy((void*)&port,     rdata+4, 2);
301
-	rdata+=6;
302
-	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)<0)
303
-		goto error;
304
-	len=strlen(name);
305
-	if (len>255)
306
-		goto error;
307
-	/* alloc enought space for the struct + null terminated name */
308
-	srv=local_malloc(sizeof(struct srv_rdata)-1+len+1);
309
-	if (srv==0){
310
-		LM_ERR("out of memory\n");
311
-		goto error;
312
-	}
313
-	srv->priority=ntohs(priority);
314
-	srv->weight=ntohs(weight);
315
-	srv->port=ntohs(port);
316
-	srv->name_len=len;
317
-	memcpy(srv->name, name, srv->name_len);
318
-	srv->name[srv->name_len]=0;
319
-	
320
-	return srv;
321
-error:
322
-	if (srv) local_free(srv);
323
-	return 0;
324
-}
325
-
326
-
327
-/** parses the naptr record into a naptr_rdata structure
328
- *   msg   - pointer to the dns message
329
- *   end   - pointer to the end of the message
330
- *   eor   - pointer to the end of the record/rdata
331
- *   rdata - pointer  to the rdata part of the naptr answer
332
- * returns 0 on error, or a dyn. alloc'ed naptr_rdata structure */
333
-
334
-/* NAPTR rdata format:
335
- *            111111
336
- *  0123456789012345
337
- * +----------------+
338
- * |      order     |
339
- * |----------------|
340
- * |   preference   |
341
- * |----------------|
342
- * ~     flags      ~
343
- * |   (string)     |
344
- * |----------------|
345
- * ~    services    ~
346
- * |   (string)     |
347
- * |----------------|
348
- * ~    regexp      ~
349
- * |   (string)     |
350
- * |----------------|
351
- * ~  replacement   ~
352
-   |    (name)      |
353
- * +----------------+
354
- */
355
-struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
356
-										unsigned char* eor,
357
-										unsigned char* rdata)
358
-{
359
-	struct naptr_rdata* naptr;
360
-	unsigned char* flags;
361
-	unsigned char* services;
362
-	unsigned char* regexp;
363
-	unsigned short order;
364
-	unsigned short pref;
365
-	unsigned char flags_len;
366
-	unsigned char services_len;
367
-	unsigned char regexp_len;
368
-	int len;
369
-	char repl[MAX_DNS_NAME];
370
-	
371
-	naptr = 0;
372
-	if ((rdata + 7 + 1)>eor) goto error;
373
-	
374
-	memcpy((void*)&order, rdata, 2);
375
-	memcpy((void*)&pref, rdata + 2, 2);
376
-	flags_len = rdata[4];
377
-	if ((rdata + 7 + 1 +  flags_len) > eor)
378
-		goto error;
379
-	flags=rdata+5;
380
-	services_len = rdata[5 + flags_len];
381
-	if ((rdata + 7 + 1 + flags_len + services_len) > eor)
382
-		goto error;
383
-	services=rdata + 6 + flags_len;
384
-	regexp_len = rdata[6 + flags_len + services_len];
385
-	if ((rdata + 7 +1 + flags_len + services_len + regexp_len) > eor)
386
-		goto error;
387
-	regexp=rdata + 7 + flags_len + services_len;
388
-	rdata = rdata + 7 + flags_len + services_len + regexp_len;
389
-	if (dn_expand(msg, end, rdata, repl, MAX_DNS_NAME-1) == -1)
390
-		goto error;
391
-	len=strlen(repl);
392
-	if (len>255)
393
-		goto error;
394
-	naptr=local_malloc(sizeof(struct naptr_rdata)+flags_len+services_len+
395
-						regexp_len+len+1-1);
396
-	if (naptr == 0){
397
-		LM_ERR("out of memory\n");
398
-		goto error;
399
-	}
400
-	naptr->order=ntohs(order);
401
-	naptr->pref=ntohs(pref);
402
-	
403
-	naptr->flags=&naptr->str_table[0];
404
-	naptr->flags_len=flags_len;
405
-	memcpy(naptr->flags, flags, naptr->flags_len);
406
-	naptr->services=&naptr->str_table[flags_len];
407
-	naptr->services_len=services_len;
408
-	memcpy(naptr->services, services, naptr->services_len);
409
-	naptr->regexp=&naptr->str_table[flags_len+services_len];
410
-	naptr->regexp_len=regexp_len;
411
-	memcpy(naptr->regexp, regexp, naptr->regexp_len);
412
-	naptr->repl=&naptr->str_table[flags_len+services_len+regexp_len];
413
-	naptr->repl_len=len;
414
-	memcpy(naptr->repl, repl, len);
415
-	naptr->repl[len]=0; /* null term. */
416
-	
417
-	return naptr;
418
-error:
419
-	if (naptr) local_free(naptr);
420
-	return 0;
421
-}
422
-
423
-
424
-
425
-/** parses a CNAME record into a cname_rdata structure */
426
-struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
427
-									  unsigned char* rdata)
428
-{
429
-	struct cname_rdata* cname;
430
-	int len;
431
-	char name[MAX_DNS_NAME];
432
-	
433
-	cname=0;
434
-	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
435
-		goto error;
436
-	len=strlen(name);
437
-	if (len>255)
438
-		goto error;
439
-	/* alloc sizeof struct + space for the null terminated name */
440
-	cname=local_malloc(sizeof(struct cname_rdata)-1+len+1);
441
-	if(cname==0){
442
-		LM_ERR("out of memory\n");
443
-		goto error;
444
-	}
445
-	cname->name_len=len;
446
-	memcpy(cname->name, name, cname->name_len);
447
-	cname->name[cname->name_len]=0;
448
-	return cname;
449
-error:
450
-	if (cname) local_free(cname);
451
-	return 0;
452
-}
453
-
454
-
455
-
456
-/** parses an A record rdata into an a_rdata structure
457
- * returns 0 on error or a dyn. alloc'ed a_rdata struct
458
- */
459
-struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* eor)
460
-{
461
-	struct a_rdata* a;
462
-	
463
-	if (rdata+4>eor) goto error;
464
-	a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata));
465
-	if (a==0){
466
-		LM_ERR("out of memory\n");
467
-		goto error;
468
-	}
469
-	memcpy(a->ip, rdata, 4);
470
-	return a;
471
-error:
472
-	return 0;
473
-}
474
-
475
-
476
-
477
-/** parses an AAAA (ipv6) record rdata into an aaaa_rdata structure
478
- * returns 0 on error or a dyn. alloc'ed aaaa_rdata struct */
479
-struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* eor)
480
-{
481
-	struct aaaa_rdata* aaaa;
482
-	
483
-	if (rdata+16>eor) goto error;
484
-	aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata));
485
-	if (aaaa==0){
486
-		LM_ERR("out of memory\n");
487
-		goto error;
488
-	}
489
-	memcpy(aaaa->ip6, rdata, 16);
490
-	return aaaa;
491
-error:
492
-	return 0;
493
-}
494
-
495
-
496
-
497
-/** parses a TXT record into a txt_rdata structure.
498
- *   @param msg   - pointer to the dns message
499
- *   @param end   - pointer to the end of the record (rdata end)
500
- *   @param rdata - pointer  to the rdata part of the txt answer
501
- * returns 0 on error, or a dyn. alloc'ed txt_rdata structure */
502
-/*  TXT rdata format:
503
- *
504
- * one or several character strings:
505
- *  01234567
506
- * +--------------------+
507
- * | len    | string   / ...
508
- * |------------------+
509
- */
510
-static struct txt_rdata* dns_txt_parser(unsigned char* msg, unsigned char* end,
511
-										unsigned char* rdata)
512
-{
513
-	struct txt_rdata* txt;
514
-	int len, n, i;
515
-	int str_size;
516
-	unsigned char* p;
517
-	unsigned char* st;
518
-	
519
-	txt=0;
520
-	if (unlikely((rdata+1)>end)) goto error;
521
-	n=0;
522
-	str_size=0;
523
-	/* count the number of strings */
524
-	p=rdata;
525
-	do{
526
-		len=*p;
527
-		p+=len+1;
528
-		str_size+=len+1; /* 1 for the term. 0 */
529
-		if (unlikely(p>end)) goto error;
530
-		n++;
531
-	}while(p<end);
532
-	/* alloc sizeof struct + space for the dns_cstr array + space for
533
-	   the strings */
534
-	txt=local_malloc(sizeof(struct txt_rdata) +(n-1)*sizeof(struct dns_cstr)+
535
-						str_size);
536
-	if(unlikely(txt==0)){
537
-		LM_ERR("out of memory\n");
538
-		goto error;
539
-	}
540
-	/* string table */
541
-	st=(unsigned char*)txt+sizeof(struct txt_rdata) +
542
-		(n-1)*sizeof(struct dns_cstr);
543
-	txt->cstr_no=n;
544
-	txt->tslen=str_size;
545
-	/* fill the structure */
546
-	p=rdata;
547
-	for (i=0; i<n; i++){
548
-		len=*p;
549
-		memcpy(st, p+1, len);
550
-		st[len]=0;
551
-		txt->txt[i].cstr_len=len;
552
-		txt->txt[i].cstr=(char*)st;
553
-		st+=len+1;
554
-		p+=len+1;
555
-	}
556
-	return txt;
557
-error:
558
-	if (txt) local_free(txt);
559
-	return 0;
560
-}
561
-
562
-
563
-
564
-/** parses an EBL record into a txt_rdata structure.
565
- *   @param msg   - pointer to the dns message
566
- *   @param end   - pointer to the end of the dns message
567
- *   @param eor   - pointer to the end of the record (rdata end)
568
- *   @param rdata - pointer  to the rdata part of the txt answer
569
- * returns 0 on error, or a dyn. alloc'ed txt_rdata structure */
570
-/*  EBL rdata format:
571
- *  (see http://tools.ietf.org/html/draft-ietf-enum-branch-location-record-03)
572
- * one or several character strings:
573
- *  01234567
574
- * +--------+
575
- * | postion|
576
- * +-----------+
577
- * / separator /
578
- * +-----------+
579
- * /   apex    /
580
- * +----------+
581
- *
582
- * where separator is a character string ( 8 bit len, followed by len chars)
583
- * and apex is a domain-name.
584
- */
585
-static struct ebl_rdata* dns_ebl_parser(unsigned char* msg, unsigned char* end,
586
-										unsigned char* eor,
587
-										unsigned char* rdata)
588
-{
589
-	struct ebl_rdata* ebl;
590
-	int sep_len;
591
-	int apex_len;
592
-	char apex[MAX_DNS_NAME];
593
-	
594
-	ebl=0;
595
-	/* check if len is at least 4 chars (minimum possible):
596
-	     pos (1 byte) +  sep. (min 1 byte) + apex (min. 2 bytes) 
597
-	   and also check if rdata+1 (pos) + 1 (sep. len) + sep_len + 1 is ok*/
598
-	if (unlikely(((rdata+4)>eor)||((rdata+1+1+rdata[1]+2)>eor))) goto error;
599
-	sep_len=rdata[1];
600
-	if (unlikely(dn_expand(msg, end, rdata+1+1+sep_len,
601
-							apex, MAX_DNS_NAME-1)==-1))
602
-		goto error;
603
-	apex_len=strlen(apex);
604
-	/* alloc sizeof struct + space for the 2 null-terminated strings */
605
-	ebl=local_malloc(sizeof(struct ebl_rdata)-1+sep_len+1+apex_len+1);
606
-	if (ebl==0){
607
-		LM_ERR("out of memory\n");
608
-		goto error;
609
-	}
610
-	ebl->position=rdata[0];
611
-	ebl->separator=&ebl->str_table[0];
612
-	ebl->apex=ebl->separator+sep_len+1;
613
-	ebl->separator_len=sep_len;
614
-	ebl->apex_len=apex_len;
615
-	memcpy(ebl->separator, rdata+2, sep_len);
616
-	ebl->separator[sep_len]=0;
617
-	memcpy(ebl->apex, apex, apex_len);
618
-	ebl->apex[apex_len]=0;
619
-	
620
-	return ebl;
621
-error:
622
-	if (ebl) local_free(ebl);
623
-	return 0;
624
-}
625
-
626
-
627
-
628
-/** parses a PTR record into a ptr_rdata structure */
629
-struct ptr_rdata* dns_ptr_parser( unsigned char* msg, unsigned char* end,
630
-									  unsigned char* rdata)
631
-{
632
-	struct ptr_rdata* pname;
633
-	int len;
634
-	char name[MAX_DNS_NAME];
635
-	
636
-	pname=0;
637
-	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
638
-		goto error;
639
-	len=strlen(name);
640
-	if (len>255)
641
-		goto error;
642
-	/* alloc sizeof struct + space for the null terminated name */
643
-	pname=local_malloc(sizeof(struct ptr_rdata)-1+len+1);
644
-	if(pname==0){
645
-		LM_ERR("out of memory\n");
646
-		goto error;
647
-	}
648
-	pname->ptrdname_len=len;
649
-	memcpy(pname->ptrdname, name, pname->ptrdname_len);
650
-	pname->ptrdname[pname->ptrdname_len]=0;
651
-	return pname;
652
-error:
653
-	if (pname) local_free(pname);
654
-	return 0;
655
-}
656
-
657
-
658
-
659
-/** frees completely a struct rdata list */
660
-void free_rdata_list(struct rdata* head)
661
-{
662
-	struct rdata* l;
663
-	struct rdata* next_l;
664
-	l=head;
665
-	while (l != 0) {
666
-		next_l = l->next;
667
-		/* free the parsed rdata*/
668
-		if (l->rdata) local_free(l->rdata);
669
-		local_free(l);
670
-		l = next_l;
671
-	}
672
-}
673
-
674
-#ifdef HAVE_RESOLV_RES
675
-/** checks whether supplied name exists in the resolver search list
676
- * returns 1 if found
677
- *         0 if not found
678
- */
679
-int match_search_list(const struct __res_state* res, char* name) {
680
-	int i;
681
-	for (i=0; (i<MAXDNSRCH) && (res->dnsrch[i]); i++) {
682
-		if (strcasecmp(name, res->dnsrch[i])==0) 
683
-			return 1;
684
-	}
685
-	return 0;
686
-}
687
-#endif
688
-
689
-/** gets the DNS records for name:type
690
- * returns a dyn. alloc'ed struct rdata linked list with the parsed responses
691
- * or 0 on error
692
- * see rfc1035 for the query/response format */
693
-struct rdata* get_record(char* name, int type, int flags)
694
-{
695
-	int size;
696
-	int skip;
697
-	int qno, answers_no;
698
-	int i, r;
699
-	static union dns_query buff;
700
-	unsigned char* p;
701
-	unsigned char* end;
702
-	unsigned char* rd_end;
703
-	static char rec_name[MAX_DNS_NAME]; /* placeholder for the record name */
704
-	int rec_name_len;
705
-	unsigned short rtype, class, rdlength;
706
-	unsigned int ttl;
707
-	struct rdata* head;
708
-	struct rdata** crt;
709
-	struct rdata** last;
710
-	struct rdata* rd;
711
-	struct srv_rdata* srv_rd;
712
-	struct srv_rdata* crt_srv;
713
-	int search_list_used;
714
-	int name_len;
715
-	struct rdata* fullname_rd;
716
-	char c;
717
-	
718
-	name_len=strlen(name);
719
-
720
-	for (i = 0; i < name_len; i++) {
721
-	    c = name[i];
722
-	    if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ||
723
-		((c >= '0') && (c <= '9')) || (name[i] == '.') ||
724
-		(name[i] == '-') || (name[i] == '_'))
725
-			continue;
726
-	    LM_DBG("'%s' is not domain name\n", name);
727
-	    return 0;
728
-	}
729
-
730
-	if (cfg_get(core, core_cfg, dns_search_list)==0) {
731
-		search_list_used=0;
732
-		name_len=0;
733
-	} else {
734
-		search_list_used=1;
735
-	}
736
-	fullname_rd=0;
737
-
738
-	size=dns_func.sr_res_search(name, C_IN, type, buff.buff, sizeof(buff));
739
-
740
-	if (unlikely(size<0)) {
741
-		LM_DBG("lookup(%s, %d) failed\n", name, type);
742
-		goto not_found;
743
-	}
744
-	else if (unlikely(size > sizeof(buff))) size=sizeof(buff);
745
-	head=rd=0;
746
-	last=crt=&head;
747
-	
748
-	p=buff.buff+DNS_HDR_SIZE;
749
-	end=buff.buff+size;
750
-	if (unlikely(p>=end)) goto error_boundary;
751
-	qno=ntohs((unsigned short)buff.hdr.qdcount);
752
-
753
-	for (r=0; r<qno; r++){
754
-		/* skip the name of the question */
755
-		if (unlikely((p=dns_skipname(p, end))==0)) {
756
-			LM_ERR("skipname==0\n");
757
-			goto error;
758
-		}
759
-		p+=2+2; /* skip QCODE & QCLASS */
760
-	#if 0
761
-		for (;(p<end && (*p)); p++);
762
-		p+=1+2+2; /* skip the ending  '\0, QCODE and QCLASS */
763
-	#endif
764
-		if (unlikely(p>end)) {
765
-			LM_ERR("p>=end\n");
766
-			goto error;
767
-		}
768
-	};
769
-	answers_no=ntohs((unsigned short)buff.hdr.ancount);
770
-again:
771
-	for (r=0; (r<answers_no) && (p<end); r++){
772
-#if 0
773
-		/*  ignore it the default domain name */
774
-		if ((p=dns_skipname(p, end))==0) {
775
-			LM_ERR("get_record: skip_name=0 (#2)\n");
776
-			goto error;
777
-		}
778
-#else
779
-		if (unlikely((skip=dn_expand(buff.buff, end, p, rec_name,
780
-							MAX_DNS_NAME-1))==-1)){
781
-			LM_ERR("dn_expand(rec_name) failed\n");
782
-			goto error;
783
-		}
784
-#endif
785
-		p+=skip;
786
-		rec_name_len=strlen(rec_name);
787
-		if (unlikely(rec_name_len>255)){
788
-			LM_ERR("dn_expand(rec_name): name too long (%d)\n",
789
-					rec_name_len);
790
-			goto error;
791
-		}
792
-		/* check if enough space is left for type, class, ttl & size */
793
-		if (unlikely((p+2+2+4+2)>end)) goto error_boundary;
794
-		/* get type */
795
-		memcpy((void*) &rtype, (void*)p, 2);
796
-		rtype=ntohs(rtype);
797
-		p+=2;
798
-		/* get  class */
799
-		memcpy((void*) &class, (void*)p, 2);
800
-		class=ntohs(class);
801
-		p+=2;
802
-		/* get ttl*/
803
-		memcpy((void*) &ttl, (void*)p, 4);
804
-		ttl=ntohl(ttl);
805
-		p+=4;
806
-		/* get size */
807
-		memcpy((void*)&rdlength, (void*)p, 2);
808
-		rdlength=ntohs(rdlength);
809
-		p+=2;
810
-		rd_end=p+rdlength;
811
-		if (unlikely((rd_end)>end)) goto error_boundary;
812
-		if ((flags & RES_ONLY_TYPE) && (rtype!=type)){
813
-			/* skip */
814
-			p=rd_end;
815
-			continue;
816
-		}
817
-		/* expand the "type" record  (rdata)*/
818
-		
819
-		rd=(struct rdata*) local_malloc(sizeof(struct rdata)+rec_name_len+
820
-										1-1);
821
-		if (rd==0){
822
-			LM_ERR("out of memory\n");
823
-			goto error;
824
-		}
825
-		rd->type=rtype;
826
-		rd->pclass=class;
827
-		rd->ttl=ttl;
828
-		rd->next=0;
829
-		memcpy(rd->name, rec_name, rec_name_len);
830
-		rd->name[rec_name_len]=0;
831
-		rd->name_len=rec_name_len;
832
-		/* check if full name matches */
833
-		if ((search_list_used==1)&&(fullname_rd==0)&&
834
-				(rec_name_len>=name_len)&&
835
-				(strncasecmp(rec_name, name, name_len)==0)) {
836
-			/* now we have record whose name is the same (up-to the
837
-			 * name_len with the searched one):
838
-			 * if the length is the same - we found full match, no fake
839
-			 *  cname needed, just clear the flag
840
-			 * if the length of the name differs - it has matched using
841
-			 *  search list remember the rd, so we can create fake CNAME
842
-			 *  record when all answers are used and no better match found
843
-			 */
844
-			if (rec_name_len==name_len)
845
-				search_list_used=0;
846
-			/* this is safe.... here was rec_name_len > name_len */
847
-			else if (rec_name[name_len]=='.') {
848
-#ifdef HAVE_RESOLV_RES
849
-				if ((cfg_get(core, core_cfg, dns_search_fmatch)==0) ||
850
-						(match_search_list(&_res, rec_name+name_len+1)!=0))
851
-#endif
852
-					fullname_rd=rd;
853
-			}
854
-		}
855
-		switch(rtype){
856
-			case T_SRV:
857
-				srv_rd= dns_srv_parser(buff.buff, end, rd_end, p);
858
-				rd->rdata=(void*)srv_rd;
859
-				if (unlikely(srv_rd==0)) goto error_parse;
860
-				
861
-				/* insert sorted into the list */
862
-				for (crt=&head; *crt; crt= &((*crt)->next)){
863
-					if ((*crt)->type!=T_SRV)
864
-						continue;
865
-					crt_srv=(struct srv_rdata*)(*crt)->rdata;
866
-					if ((srv_rd->priority <  crt_srv->priority) ||
867
-					   ( (srv_rd->priority == crt_srv->priority) && 
868
-							 (srv_rd->weight > crt_srv->weight) ) ){
869
-						/* insert here */
870
-						goto skip;
871
-					}
872
-				}
873
-				last=&(rd->next); /*end of for => this will be the last
874
-									element*/
875
-			skip:
876
-				/* insert here */
877
-				rd->next=*crt;
878
-				*crt=rd;
879
-				break;
880
-			case T_A:
881
-				rd->rdata=(void*) dns_a_parser(p, rd_end);
882
-				if (unlikely(rd->rdata==0)) goto error_parse;
883
-				*last=rd; /* last points to the last "next" or the list
884
-							 	head*/
885
-				last=&(rd->next);
886
-				break;
887
-			case T_AAAA:
888
-				rd->rdata=(void*) dns_aaaa_parser(p, rd_end);
889
-				if (unlikely(rd->rdata==0)) goto error_parse;
890
-				*last=rd;
891
-				last=&(rd->next);
892
-				break;
893
-			case T_CNAME:
894
-				rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
895
-				if(unlikely(rd->rdata==0)) goto error_parse;
896
-				*last=rd;
897
-				last=&(rd->next);
898
-				break;
899
-			case T_NAPTR:
900
-				rd->rdata=(void*)dns_naptr_parser(buff.buff, end, rd_end, p);
901
-				if(unlikely(rd->rdata==0)) goto error_parse;
902
-				*last=rd;
903
-				last=&(rd->next);
904
-				break;
905