Browse code

- dns naptr support (off by default) - dns naptr related config options: dns_try_naptr (off by default), dns_udp_pref, dns_tcp_pref. dns_tls_pref (protocol preferences for naptr record selection) - dns srv load balancing config options: dns_srv_lb (off by default) - dns resolver & cache api change (to support getting the protocol via naptr) - fix: dns iteration through A & AAAA records was not correct

For more info see doc/dns.txt.

Andrei Pelinescu-Onciul authored on 18/06/2007 21:20:58
Showing 17 changed files
... ...
@@ -75,7 +75,7 @@ MAIN_NAME=ser
75 75
 VERSION = 2
76 76
 PATCHLEVEL = 1
77 77
 SUBLEVEL =  0
78
-EXTRAVERSION = -dev8-sf_malloc
78
+EXTRAVERSION = -dev9-dns
79 79
 
80 80
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
81 81
 			$(SUBLEVEL) )
... ...
@@ -401,6 +401,8 @@ endif
401 401
 # -DNO_SIG_DEBUG
402 402
 #        turns off debugging messages in signal handlers (which might be 
403 403
 #         unsafe)
404
+# -DUSE_NAPTR
405
+#		 turns on naptr support (but must be also enabled from the config)
404 406
 
405 407
 # Sometimes is needes correct non-quoted $OS. HACK: gcc translates known OS to number ('linux'), so there is added underscore
406 408
 
... ...
@@ -420,11 +422,12 @@ DEFS+= $(extra_defs) \
420 420
 	 -DUSE_DNS_CACHE \
421 421
 	 -DUSE_DNS_FAILOVER \
422 422
 	 -DUSE_DST_BLACKLIST \
423
-	 -DDBG_QM_MALLOC \
423
+	 -DUSE_NAPTR \
424 424
 	 #-DLL_MALLOC \
425 425
 	 #-DSF_MALLOC \
426 426
 	 #-DDL_MALLOC \
427 427
 	 #-DF_MALLOC \
428
+	 #-DDBG_QM_MALLOC \
428 429
 	 #-DDBG_F_MALLOC \
429 430
 	 #-DNO_DEBUG \
430 431
 	 #-DEXTRA_DEBUG \
... ...
@@ -71,6 +71,8 @@ modules:
71 71
                         - t_set_retr(t1, t2) - changes the retransmissions
72 72
                            intervals on the fly, on a per transaction basis.
73 73
 core:
74
+             - dns naptr support (see dns_try_naptr and dns_<proto>_pref)
75
+             - dns srv based load balancing support (see dns_srv_lb)
74 76
              - support for locking ser's pages in memory, pre-mapping
75 77
                all the shared memory on startup (fill it with 0)
76 78
              - real time options
... ...
@@ -79,6 +81,17 @@ core:
79 79
                long held locks, almost no performance impact otherwise)
80 80
 
81 81
 new config variables:
82
+  dns_srv_lb = yes | no (default no) - enable dns srv weight based load 
83
+    balancing (see doc/dns.txt)
84
+  dns_try_naptr = yes | no (default no) - enable naptr support 
85
+    (see doc/dns.txt for more info)
86
+  dns_{udp,tcp,tls}_pref = number - ser preference for each protocol when
87
+    doing naptr lookups. By default dns_udp_pref=3, dns_tcp_pref=2 and 
88
+    dns_tls_pref=1. To use the remote site preferences set all dns_*_pref to 
89
+    the same positive value (e.g. dns_udp_pref=1, dns_tcp_pref=1, 
90
+    dns_udp_pref=1). To completely ignore NAPTR records for a specific 
91
+    protocol, set the corresponding protocol preference to -1 (or any other 
92
+    negative number).  (see doc/dns.txt for more info)
82 93
   mlock_pages = yes |no (default no) - locks all ser pages into memory making 
83 94
     it unswappable (in general one doesn't want his sip proxy swapped out :-))
84 95
   shm_force_alloc = yes | no (default no) - tries to pre-fault all the 
... ...
@@ -176,7 +176,8 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
176 176
 											 from the uri */
177 177
 					switch(u->proto){
178 178
 						case PROTO_NONE:
179
-							dst.proto=PROTO_UDP;
179
+							/*dst.proto=PROTO_UDP; */
180
+							/* no proto, try to get it from the dns */
180 181
 							break;
181 182
 						case PROTO_UDP:
182 183
 #ifdef USE_TCP
... ...
@@ -67,6 +67,8 @@
67 67
  *  2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
68 68
  *              RT_POLICY, RT_TIMER1_PRIO, RT_TIMER1_POLICY, RT_TIMER2_PRIO,
69 69
  *              RT_TIMER2_POLICY (andrei)
70
+ *  2007-06-16  added DNS_SRV_LB, DNS_TRY_NAPTR (andrei)
71
+ *  2007-06-18  added DNS_{UDP,TCP,TLS}_PREF (andrei)
70 72
  */
71 73
 
72 74
 
... ...
@@ -231,6 +233,11 @@ ALIAS		alias
231 231
 DNS		 dns
232 232
 REV_DNS	 rev_dns
233 233
 DNS_TRY_IPV6	dns_try_ipv6
234
+DNS_TRY_NAPTR	dns_try_naptr
235
+DNS_SRV_LB		dns_srv_lb|dns_srv_loadbalancing
236
+DNS_UDP_PREF	dns_udp_pref|dns_udp_preference
237
+DNS_TCP_PREF	dns_tcp_pref|dns_tcp_preference
238
+DNS_TLS_PREF	dns_tls_pref|dns_tls_preference
234 239
 DNS_RETR_TIME	dns_retr_time
235 240
 DNS_RETR_NO		dns_retr_no
236 241
 DNS_SERVERS_NO	dns_servers_no
... ...
@@ -455,6 +462,16 @@ EAT_ABLE	[\ \t\b\r]
455 455
 <INITIAL>{REV_DNS}	{ count(); yylval.strval=yytext; return REV_DNS; }
456 456
 <INITIAL>{DNS_TRY_IPV6}	{ count(); yylval.strval=yytext;
457 457
 								return DNS_TRY_IPV6; }
458
+<INITIAL>{DNS_TRY_NAPTR}	{ count(); yylval.strval=yytext;
459
+								return DNS_TRY_NAPTR; }
460
+<INITIAL>{DNS_SRV_LB}	{ count(); yylval.strval=yytext;
461
+								return DNS_SRV_LB; }
462
+<INITIAL>{DNS_UDP_PREF}	{ count(); yylval.strval=yytext;
463
+								return DNS_UDP_PREF; }
464
+<INITIAL>{DNS_TCP_PREF}	{ count(); yylval.strval=yytext;
465
+								return DNS_TCP_PREF; }
466
+<INITIAL>{DNS_TLS_PREF}	{ count(); yylval.strval=yytext;
467
+								return DNS_TLS_PREF; }
458 468
 <INITIAL>{DNS_RETR_TIME}	{ count(); yylval.strval=yytext;
459 469
 								return DNS_RETR_TIME; }
460 470
 <INITIAL>{DNS_RETR_NO}	{ count(); yylval.strval=yytext;
... ...
@@ -78,9 +78,10 @@
78 78
  *              (vlada)
79 79
  * 2007-02-09  separated command needed for tls-in-core and for tls in general
80 80
  *              (andrei)
81
- *  2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
81
+ * 2007-06-07  added SHM_FORCE_ALLOC, MLOCK_PAGES, REAL_TIME, RT_PRIO,
82 82
  *              RT_POLICY, RT_TIMER1_PRIO, RT_TIMER1_POLICY, RT_TIMER2_PRIO,
83 83
  *              RT_TIMER2_POLICY (andrei)
84
+ * 2007-06-16  added DDNS_SRV_LB, DNS_TRY_NAPTR (andrei)
84 85
  */
85 86
 
86 87
 %{
... ...
@@ -139,6 +140,12 @@
139 139
 	#define IF_DNS_FAILOVER(x) warn("dns failover support not compiled in")
140 140
 #endif
141 141
 
142
+#ifdef USE_NAPTR
143
+	#define IF_NAPTR(x) x
144
+#else
145
+	#define IF_NAPTR(x) warn("dns naptr support not compiled in")
146
+#endif
147
+
142 148
 #ifdef USE_DST_BLACKLIST
143 149
 	#define IF_DST_BLACKLIST(x) x
144 150
 #else
... ...
@@ -265,6 +272,11 @@ static struct socket_id* mk_listen_id(char*, int, int);
265 265
 %token DNS
266 266
 %token REV_DNS
267 267
 %token DNS_TRY_IPV6
268
+%token DNS_TRY_NAPTR
269
+%token DNS_SRV_LB
270
+%token DNS_UDP_PREF
271
+%token DNS_TCP_PREF
272
+%token DNS_TLS_PREF
268 273
 %token DNS_RETR_TIME
269 274
 %token DNS_RETR_NO
270 275
 %token DNS_SERVERS_NO
... ...
@@ -570,6 +582,16 @@ assign_stm:
570 570
 	| REV_DNS EQUAL error { yyerror("boolean value expected"); }
571 571
 	| DNS_TRY_IPV6 EQUAL NUMBER   { dns_try_ipv6=$3; }
572 572
 	| DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
573
+	| DNS_TRY_NAPTR EQUAL NUMBER   { IF_NAPTR(dns_try_naptr=$3); }
574
+	| DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
575
+	| DNS_SRV_LB EQUAL NUMBER   { IF_DNS_FAILOVER(dns_srv_lb=$3); }
576
+	| DNS_SRV_LB error { yyerror("boolean value expected"); }
577
+	| DNS_UDP_PREF EQUAL NUMBER   { IF_NAPTR(dns_udp_pref=$3); }
578
+	| DNS_UDP_PREF error { yyerror("number expected"); }
579
+	| DNS_TCP_PREF EQUAL NUMBER   { IF_NAPTR(dns_tcp_pref=$3); }
580
+	| DNS_TCP_PREF error { yyerror("number expected"); }
581
+	| DNS_TLS_PREF EQUAL NUMBER   { IF_NAPTR(dns_tls_pref=$3); }
582
+	| DNS_TLS_PREF error { yyerror("number expected"); }
573 583
 	| DNS_RETR_TIME EQUAL NUMBER   { dns_retr_time=$3; }
574 584
 	| DNS_RETR_TIME error { yyerror("number expected"); }
575 585
 	| DNS_RETR_NO EQUAL NUMBER   { dns_retr_no=$3; }
... ...
@@ -32,6 +32,7 @@
32 32
  *  2006-10-06  port fix (andrei)
33 33
  *  2007-06-14  dns iterate through A & AAAA records fix (andrei)
34 34
  *  2007-06-15  srv rr weight based load balancing support (andrei)
35
+ *  2007-06-16  naptr support (andrei)
35 36
  */
36 37
 
37 38
 #ifdef USE_DNS_CACHE
... ...
@@ -88,7 +89,7 @@ unsigned int dns_cache_min_ttl=DEFAULT_DNS_CACHE_MIN_TTL; /* minimum ttl */
88 88
 unsigned int dns_timer_interval=DEFAULT_DNS_TIMER_INTERVAL; /* in s */
89 89
 int dns_flags=0; /* default flags used for the  dns_*resolvehost 
90 90
                     (compatibility wrappers) */
91
-int dns_srv_lb=1; /* off by default */
91
+int dns_srv_lb=0; /* off by default */
92 92
 
93 93
 #define LOCK_DNS_HASH()		lock_get(dns_hash_lock)
94 94
 #define UNLOCK_DNS_HASH()	lock_release(dns_hash_lock)
... ...
@@ -126,6 +127,7 @@ static const char* dns_str_errors[]={
126 126
 	"blacklisted ip",
127 127
 	"name too long ", /* try again with a shorter name */
128 128
 	"ip AF mismatch", /* address family mismatch */
129
+	"unresolvable NAPTR request", 
129 130
 	"bug - critical error"
130 131
 };
131 132
 
... ...
@@ -293,6 +295,13 @@ int init_dns_cache()
293 293
 					" support for it is not compiled -- ignoring\n");
294 294
 #endif
295 295
 	}
296
+	if (dns_try_naptr){
297
+#ifndef USE_NAPTR
298
+	LOG(L_WARN, "WARING: dns_cache_init: NAPTR support is enabled, but"
299
+				" support for it is not compiled -- ignoring\n");
300
+#endif
301
+		dns_flags|=DNS_TRY_NAPTR;
302
+	}
296 303
 	dns_timer_h=timer_alloc();
297 304
 	if (dns_timer_h==0){
298 305
 		ret=E_OUT_OF_MEM;
... ...
@@ -411,8 +420,10 @@ inline static struct dns_hash_entry* _dns_hash_find(str* name, int type,
411 411
 	*err=0;
412 412
 again:
413 413
 	*h=dns_hash_no(name->s, name->len, type);
414
+#ifdef DNS_CACHE_DEBUG
414 415
 	DBG("dns_hash_find(%.*s(%d), %d), h=%d\n", name->len, name->s,
415 416
 												name->len, type, *h);
417
+#endif
416 418
 	clist_foreach_safe(&dns_hash[*h], e, tmp, next){
417 419
 		/* automatically remove expired elements */
418 420
 		if ((s_ticks_t)(now-e->expire)>=0){
... ...
@@ -645,8 +656,10 @@ inline static int dns_cache_add(struct dns_hash_entry* e)
645 645
 	}
646 646
 	atomic_inc(&e->refcnt);
647 647
 	h=dns_hash_no(e->name, e->name_len, e->type);
648
+#ifdef DNS_CACHE_DEBUG
648 649
 	DBG("dns_cache_add: adding %.*s(%d) %d (flags=%0x) at %d\n",
649 650
 			e->name_len, e->name, e->name_len, e->type, e->err_flags, h);
651
+#endif
650 652
 	LOCK_DNS_HASH();
651 653
 		*dns_cache_mem_used+=e->total_size; /* no need for atomic ops, written
652 654
 										 only from within a lock */
... ...
@@ -681,8 +694,10 @@ inline static int dns_cache_add_unsafe(struct dns_hash_entry* e)
681 681
 	}
682 682
 	atomic_inc(&e->refcnt);
683 683
 	h=dns_hash_no(e->name, e->name_len, e->type);
684
+#ifdef DNS_CACHE_DEBUG
684 685
 	DBG("dns_cache_add: adding %.*s(%d) %d (flags=%0x) at %d\n",
685 686
 			e->name_len, e->name, e->name_len, e->type, e->err_flags, h);
687
+#endif
686 688
 	*dns_cache_mem_used+=e->total_size; /* no need for atomic ops, written
687 689
 										 only from within a lock */
688 690
 	clist_append(&dns_hash[h], e, next, prev);
... ...
@@ -704,8 +719,10 @@ inline static struct dns_hash_entry* dns_cache_mk_bad_entry(str* name,
704 704
 	int size;
705 705
 	ticks_t now;
706 706
 	
707
+#ifdef DNS_CACHE_DEBUG
707 708
 	DBG("dns_cache_mk_bad_entry(%.*s, %d, %d, %d)\n", name->len, name->s,
708 709
 									type, ttl, flags);
710
+#endif
709 711
 	size=sizeof(struct dns_hash_entry)+name->len-1+1;
710 712
 	e=shm_malloc(size);
711 713
 	if (e==0){
... ...
@@ -937,8 +954,10 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
937 937
 	}
938 938
 	*tail=0; /* mark the end of our tmp_lst */
939 939
 	if (size==0){
940
+#ifdef DNS_CACHE_DEBUG
940 941
 		DBG("dns_cache_mk_rd_entry: entry %.*s (%d) not found\n",
941 942
 				name->len, name->s, type);
943
+#endif
942 944
 		return 0;
943 945
 	}
944 946
 	/* compute size */
... ...
@@ -949,6 +968,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
949 949
 		return 0;
950 950
 	}
951 951
 	memset(e, 0, size); /* init with 0 */
952
+	clist_init(e, next, prev);
952 953
 	e->total_size=size;
953 954
 	e->name_len=name->len;
954 955
 	e->type=type;
... ...
@@ -1013,7 +1033,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1013 1013
 				max_ttl=MAX(max_ttl, ttl);
1014 1014
 				rr->rdata=(void*)((char*)rr+
1015 1015
 								ROUND_POINTER(sizeof(struct dns_rr)));
1016
-				/* copy the whole srv_rdata block*/
1016
+				/* copy the whole naptr_rdata block*/
1017 1017
 				memcpy(rr->rdata, l->rdata, 
1018 1018
 						NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
1019 1019
 				/* adjust the string pointer */
... ...
@@ -1034,6 +1054,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1034 1034
 										NAPTR_RDATA_SIZE(
1035 1035
 											*(struct naptr_rdata*)l->rdata)));
1036 1036
 				tail_rr=&(rr->next);
1037
+				rr=rr->next;
1037 1038
 			}
1038 1039
 			break;
1039 1040
 		case T_CNAME:
... ...
@@ -1267,6 +1288,7 @@ found:
1267 1267
 										NAPTR_RDATA_SIZE(
1268 1268
 											*(struct naptr_rdata*)l->rdata)));
1269 1269
 				rec[r].tail_rr=&(rec[r].rr->next);
1270
+				rec[r].rr=rec[r].rr->next;
1270 1271
 				break;
1271 1272
 			case T_CNAME:
1272 1273
 				rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
... ...
@@ -1332,8 +1354,10 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1332 1332
 	
1333 1333
 	ret=0;
1334 1334
 	l=e;
1335
+#ifdef DNS_CACHE_DEBUG
1335 1336
 	DBG("dns_get_related(%p (%.*s, %d), %d, *%p) (%d)\n", e,
1336 1337
 			e->name_len, e->name, e->type, type, *records, cname_chain_len);
1338
+#endif
1337 1339
 	clist_init(l, next, prev);
1338 1340
 	if (type==e->type){
1339 1341
 		ret=e;
... ...
@@ -1347,7 +1371,8 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1347 1347
 						if (t){
1348 1348
 							if ((t->type==T_CNAME) && *records)
1349 1349
 								dns_get_related(t, T_A, records);
1350
-							clist_append(l, t, next, prev);
1350
+							lst_end=t->prev; /* needed for clist_append*/
1351
+							clist_append_sublist(l, t, lst_end, next, prev);
1351 1352
 						}
1352 1353
 					}
1353 1354
 					if (!(dns_flags&DNS_IPV4_ONLY)){
... ...
@@ -1355,11 +1380,34 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1355 1355
 						if (t){
1356 1356
 							if ((t->type==T_CNAME) && *records)
1357 1357
 								dns_get_related(t, T_AAAA, records);
1358
-							clist_append(l, t, next, prev);
1358
+							lst_end=t->prev; /* needed for clist_append*/
1359
+							clist_append_sublist(l, t, lst_end, next, prev);
1359 1360
 						}
1360 1361
 					}
1361 1362
 				}
1362 1363
 				break;
1364
+#ifdef USE_NAPTR
1365
+			case T_NAPTR:
1366
+#ifdef NAPTR_CACHE_ALL_ARS
1367
+				if (*records)
1368
+						dns_cache_mk_rd_entry2(*records);
1369
+#else
1370
+				for (rr=e->rr_lst; rr && *records; rr=rr->next){
1371
+					if (naptr_get_sip_proto((struct naptr_rdata*)rr->rdata)>0){
1372
+						tmp.s=((struct naptr_rdata*)rr->rdata)->repl;
1373
+						tmp.len=((struct naptr_rdata*)rr->rdata)->repl_len;
1374
+						t=dns_cache_mk_rd_entry(&tmp, T_SRV, records);
1375
+						if (t){
1376
+							if (*records)
1377
+								dns_get_related(t, T_SRV, records);
1378
+							lst_end=t->prev; /* needed for clist_append*/
1379
+							clist_append_sublist(l, t, lst_end, next, prev);
1380
+						}
1381
+					}
1382
+				}
1383
+#endif /* NAPTR_CACHE_ALL_ARS */
1384
+#endif /* USE_NAPTR */
1385
+				break;
1363 1386
 			default:
1364 1387
 				/* nothing extra */
1365 1388
 				break;
... ...
@@ -1593,7 +1641,7 @@ error:
1593 1593
  *               now - current time/ticks value
1594 1594
  * returns pointer to the rr on success and sets no to the rr number
1595 1595
  *         0 on error and fills the error flags
1596
- *
1596
+	*
1597 1597
  * Example usage:
1598 1598
  * list all non-expired non-bad-marked ips for name:
1599 1599
  * e=dns_get_entry(name, T_A);
... ...
@@ -1980,6 +2028,36 @@ struct hostent* dns_resolvehost(char* name)
1980 1980
 
1981 1981
 
1982 1982
 
1983
+
1984
+#if 0
1985
+/* resolves a host name trying  NAPTR,  SRV, A & AAAA lookups, for details
1986
+ *  see dns_sip_resolve()
1987
+ *  FIXME: this version will return only the first ip
1988
+ * returns: hostent struct & *port filled with the port from the SRV record;
1989
+ *  0 on error
1990
+ */
1991
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
1992
+										char* proto)
1993
+{
1994
+	struct dns_srv_handle h;
1995
+	struct ip_addr ip;
1996
+	int ret;
1997
+	
1998
+	if ((use_dns_cache==0) || (dns_hash==0)){ 
1999
+		/* not init or off => use normal, non-cached version */
2000
+		return _sip_resolvehost(name, port, proto);
2001
+	}
2002
+	dns_srv_handle_init(&h);
2003
+	ret=dns_sip_resolve(&h, name, &ip, port, proto, dns_flags);
2004
+	dns_srv_handle_put(&h);
2005
+	if (ret>=0)
2006
+		return ip_addr2he(name, &ip);
2007
+	return 0;
2008
+}
2009
+#endif
2010
+
2011
+
2012
+
1983 2013
 /* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup
1984 2014
  * if *port!=0.
1985 2015
  * when performing SRV lookup (*port==0) it will use proto to look for
... ...
@@ -1987,23 +2065,33 @@ struct hostent* dns_resolvehost(char* name)
1987 1987
  * returns: hostent struct & *port filled with the port from the SRV record;
1988 1988
  *  0 on error
1989 1989
  */
1990
-struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, int proto)
1990
+struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port, 
1991
+										char* proto)
1991 1992
 {
1992 1993
 	struct hostent* he;
1993 1994
 	struct ip_addr* ip;
1994 1995
 	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
1995 1996
 	int len;
1996 1997
 	str srv_name;
1998
+	char srv_proto;
1997 1999
 
1998 2000
 	if ((use_dns_cache==0) || (dns_hash==0)){ 
1999 2001
 		/* not init or off => use normal, non-cached version */
2000 2002
 		return _sip_resolvehost(name, port, proto);
2001 2003
 	}
2002 2004
 	len=0;
2005
+	if (proto){ /* makes sure we have a protocol set*/
2006
+		if (*proto==0)
2007
+			*proto=srv_proto=PROTO_UDP; /* default */
2008
+		else
2009
+			srv_proto=*proto;
2010
+	}else{
2011
+		srv_proto=PROTO_UDP;
2012
+	}
2003 2013
 	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
2004 2014
 	if ((port)&&(*port==0)){
2005
-		*port=(proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we don't
2006
-														find another */
2015
+		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we 
2016
+														 don't find another */
2007 2017
 		if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
2008 2018
 			LOG(L_WARN, "WARNING: dns_sip_resolvehost: domain name too long"
2009 2019
 						" (%d), unable to perform SRV lookup\n", name->len);
... ...
@@ -2018,9 +2106,11 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, int proto)
2018 2018
 				return ip_addr2he(name,ip);
2019 2019
 			}
2020 2020
 			
2021
-			switch(proto){
2021
+			switch(srv_proto){
2022 2022
 				case PROTO_NONE: /* no proto specified, use udp */
2023
-					goto skip_srv;
2023
+					if (proto)
2024
+						*proto=PROTO_UDP;
2025
+					/* no break */
2024 2026
 				case PROTO_UDP:
2025 2027
 					memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
2026 2028
 					memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
... ...
@@ -2041,7 +2131,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, int proto)
2041 2041
 					break;
2042 2042
 				default:
2043 2043
 					LOG(L_CRIT, "BUG: sip_resolvehost: unknown proto %d\n",
2044
-							proto);
2044
+							(int)srv_proto);
2045 2045
 					return 0;
2046 2046
 			}
2047 2047
 
... ...
@@ -2051,7 +2141,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, int proto)
2051 2051
 				return he;
2052 2052
 		}
2053 2053
 	}
2054
-skip_srv:
2054
+/*skip_srv:*/
2055 2055
 	if (name->len >= MAX_DNS_NAME) {
2056 2056
 		LOG(L_ERR, "dns_sip_resolvehost: domain name too long\n");
2057 2057
 		return 0;
... ...
@@ -2062,6 +2152,170 @@ skip_srv:
2062 2062
 
2063 2063
 
2064 2064
 
2065
+#ifdef USE_NAPTR
2066
+/* iterates over a naptr rr list, returning each time a "good" naptr record
2067
+ * is found.( srv type, no regex and a supported protocol)
2068
+ * params:
2069
+ *         naptr_head - naptr dns_rr list head
2070
+ *         tried      - bitmap used to keep track of the already tried records
2071
+ *                      (no more then sizeof(tried)*8 valid records are 
2072
+ *                      ever walked
2073
+ *         srv_name   - if succesfull, it will be set to the selected record
2074
+ *                      srv name (naptr repl.)
2075
+ *         proto      - if succesfull it will be set to the selected record
2076
+ *                      protocol
2077
+ * returns  0 if no more records found or a pointer to the selected record
2078
+ *  and sets  protocol and srv_name
2079
+ * WARNING: when calling first time make sure you run first 
2080
+ *           naptr_iterate_init(&tried)
2081
+ */
2082
+struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head, 
2083
+											naptr_bmp_t* tried,
2084
+											str* srv_name, char* proto)
2085
+{
2086
+	int i, idx;
2087
+	struct dns_rr* l;
2088
+	struct naptr_rdata* naptr;
2089
+	struct naptr_rdata* naptr_saved;
2090
+	char saved_proto;
2091
+	char naptr_proto;
2092
+
2093
+	idx=0;
2094
+	naptr_proto=PROTO_NONE;
2095
+	naptr_saved=0;
2096
+	saved_proto=0;
2097
+	i=0;
2098
+	for(l=naptr_head; l && (i<MAX_NAPTR_RRS); l=l->next){
2099
+		naptr=(struct naptr_rdata*) l->rdata;
2100
+		if (naptr==0){
2101
+				LOG(L_CRIT, "naptr_iterate: BUG: null rdata\n");
2102
+			goto end;
2103
+		}
2104
+		/* check if valid and get proto */
2105
+		if ((naptr_proto=naptr_get_sip_proto(naptr))<=0) continue;
2106
+		if (*tried& (1<<i)){
2107
+			i++;
2108
+			continue; /* already tried */
2109
+		}
2110
+#ifdef DNS_CACHE_DEBUG
2111
+		DBG("naptr_iterate: found a valid sip NAPTR rr %.*s,"
2112
+					" proto %d\n", naptr->repl_len, naptr->repl, 
2113
+					(int)naptr_proto);
2114
+#endif
2115
+		if ((naptr_proto_supported(naptr_proto))){
2116
+			if (naptr_choose(&naptr_saved, &saved_proto,
2117
+								naptr, naptr_proto))
2118
+				idx=i;
2119
+			}
2120
+		i++;
2121
+	}
2122
+	if (naptr_saved){
2123
+		/* found something */
2124
+#ifdef DNS_CACHE_DEBUG
2125
+		DBG("naptr_iterate: choosed NAPTR rr %.*s, proto %d"
2126
+					" tried: 0x%x\n", naptr_saved->repl_len, 
2127
+					naptr_saved->repl, (int)saved_proto, *tried);
2128
+#endif
2129
+		*tried|=1<<idx;
2130
+		*proto=saved_proto;
2131
+		srv_name->s=naptr_saved->repl;
2132
+		srv_name->len=naptr_saved->repl_len;
2133
+		return naptr_saved;
2134
+	}
2135
+end:
2136
+	return 0;
2137
+}
2138
+
2139
+
2140
+
2141
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2142
+ * lookup if *port==0 or normal A/AAAA lookup
2143
+ * if *port!=0.
2144
+ * when performing SRV lookup (*port==0) it will use proto to look for
2145
+ * tcp or udp hosts; if proto==0 => no SRV lookup
2146
+ * returns: hostent struct & *port filled with the port from the SRV record;
2147
+ *  0 on error
2148
+ */
2149
+struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port, 
2150
+										char* proto)
2151
+{
2152
+	struct hostent* he;
2153
+	struct ip_addr* tmp_ip;
2154
+	naptr_bmp_t tried_bmp;
2155
+	struct dns_hash_entry* e;
2156
+	char n_proto;
2157
+	str srv_name;
2158
+	
2159
+	he=0;
2160
+	if (dns_hash==0){ /* not init => use normal, non-cached version */
2161
+		LOG(L_WARN, "WARNING: dns_sip_resolvehost: called before dns cache"
2162
+					" initialization\n");
2163
+		return _sip_resolvehost(name, port, proto);
2164
+	}
2165
+	if (proto && port && (*proto==0) && (*port==0)){
2166
+		*proto=PROTO_UDP; /* just in case we don't find another */
2167
+		/* check if it's an ip address */
2168
+		if ( ((tmp_ip=str2ip(name))!=0)
2169
+#ifdef	USE_IPV6
2170
+			  || ((tmp_ip=str2ip6(name))!=0)
2171
+#endif
2172
+			){
2173
+			/* we are lucky, this is an ip address */
2174
+#ifdef	USE_IPV6
2175
+			if (((dns_flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
2176
+				((dns_flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
2177
+				return 0;
2178
+			}
2179
+#endif
2180
+			*port=SIP_PORT;
2181
+			return ip_addr2he(name, tmp_ip);
2182
+		}
2183
+		/* do naptr lookup */
2184
+		if ((e=dns_get_entry(name, T_NAPTR))==0)
2185
+			goto naptr_not_found;
2186
+		naptr_iterate_init(&tried_bmp);
2187
+		while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
2188
+												&srv_name, &n_proto)){
2189
+			if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0){
2190
+#ifdef DNS_CACHE_DEBUG
2191
+				DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n", 
2192
+							name->len, name->s, (int)*port, (int)*proto, he);
2193
+#endif
2194
+				dns_hash_put(e);
2195
+				*proto=n_proto;
2196
+				return he;
2197
+			}
2198
+		}
2199
+		/* no acceptable naptr record found, fallback to srv */
2200
+		dns_hash_put(e);
2201
+	}
2202
+naptr_not_found:
2203
+	return dns_srv_sip_resolvehost(name, port, proto);
2204
+}
2205
+#endif /* USE_NAPTR */
2206
+
2207
+
2208
+
2209
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2210
+ * lookup if *port==0 or normal A/AAAA lookup
2211
+ * if *port!=0.
2212
+ * when performing SRV lookup (*port==0) it will use proto to look for
2213
+ * tcp or udp hosts; if proto==0 => no SRV lookup
2214
+ * returns: hostent struct & *port filled with the port from the SRV record;
2215
+ *  0 on error
2216
+ */
2217
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2218
+										char* proto)
2219
+{
2220
+#ifdef USE_NAPTR
2221
+	if (dns_flags&DNS_TRY_NAPTR)
2222
+		return dns_naptr_sip_resolvehost(name, port, proto);
2223
+#endif
2224
+	return dns_srv_sip_resolvehost(name, port, proto);
2225
+}
2226
+
2227
+
2228
+
2065 2229
 /* performs an a lookup, fills the dns_entry pointer and the ip addr.
2066 2230
  *  (with the first good ip). if *e ==0 does the a lookup, and changes it
2067 2231
  *   to the result, if not it uses the current value and tries to use 
... ...
@@ -2359,8 +2613,8 @@ error:
2359 2359
  *            0 on success and it fills *ip, *port, dns_sip_resolve_h
2360 2360
  * WARNING: when finished, dns_sip_resolve_put(h) must be called!
2361 2361
  */
2362
-int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2363
-						struct ip_addr* ip, unsigned short* port, int proto,
2362
+int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2363
+						struct ip_addr* ip, unsigned short* port, char* proto,
2364 2364
 						int flags)
2365 2365
 {
2366 2366
 	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
... ...
@@ -2369,6 +2623,7 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2369 2369
 	struct ip_addr* tmp_ip;
2370 2370
 	int ret;
2371 2371
 	struct hostent* he;
2372
+	char srv_proto;
2372 2373
 
2373 2374
 	if (dns_hash==0){ /* not init => use normal, non-cached version */
2374 2375
 		LOG(L_WARN, "WARNING: dns_sip_resolve: called before dns cache"
... ...
@@ -2383,8 +2638,17 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2383 2383
 	}
2384 2384
 	len=0;
2385 2385
 	if ((h->srv==0) && (h->a==0)){ /* first call */
2386
-		h->port=(proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
2386
+		if (proto){ /* makes sure we have a protocol set*/
2387
+			if (*proto==0)
2388
+				*proto=srv_proto=PROTO_UDP; /* default */
2389
+			else
2390
+				srv_proto=*proto;
2391
+		}else{
2392
+			srv_proto=PROTO_UDP;
2393
+		}
2394
+		h->port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
2387 2395
 														don't find another */
2396
+		h->proto=srv_proto; /* store initial protocol */
2388 2397
 		if (port){
2389 2398
 			if (*port==0){
2390 2399
 				/* try SRV if initial call & no port specified
... ...
@@ -2409,12 +2673,15 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2409 2409
 #endif
2410 2410
 						*ip=*tmp_ip;
2411 2411
 						*port=h->port;
2412
+						/* proto already set */
2412 2413
 						return 0;
2413 2414
 					}
2414 2415
 					
2415
-					switch(proto){
2416
+					switch(srv_proto){
2416 2417
 						case PROTO_NONE: /* no proto specified, use udp */
2417
-							goto skip_srv;
2418
+							if (proto)
2419
+								*proto=PROTO_UDP;
2420
+							/* no break */
2418 2421
 						case PROTO_UDP:
2419 2422
 							memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
2420 2423
 							memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
... ...
@@ -2435,12 +2702,11 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2435 2435
 							break;
2436 2436
 						default:
2437 2437
 							LOG(L_CRIT, "BUG: sip_resolvehost: "
2438
-									"unknown proto %d\n", proto);
2438
+									"unknown proto %d\n", (int)srv_proto);
2439 2439
 							return -E_DNS_CRITICAL;
2440 2440
 					}
2441 2441
 					srv_name.s=tmp;
2442 2442
 					srv_name.len=len;
2443
-					
2444 2443
 					if ((ret=dns_srv_resolve_ip(h, &srv_name, ip,
2445 2444
 															port, flags))>=0)
2446 2445
 					{
... ...
@@ -2448,11 +2714,13 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2448 2448
 						DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2449 2449
 							name->len, name->s, h->srv_no, h->ip_no, ret);
2450 2450
 #endif
2451
+						/* proto already set */
2451 2452
 						return ret;
2452 2453
 					}
2453 2454
 				}
2454 2455
 			}else{ /* if (*port==0) */
2455 2456
 				h->port=*port; /* store initial port */
2457
+				/* proto already set */
2456 2458
 			}
2457 2459
 		} /* if (port) */
2458 2460
 	}else if (h->srv){
... ...
@@ -2460,11 +2728,13 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2460 2460
 			srv_name.len=h->srv->name_len;
2461 2461
 			/* continue srv resolving */
2462 2462
 			ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags);
2463
+			if (proto)
2464
+				*proto=h->proto;
2463 2465
 			DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n", 
2464 2466
 					name->len, name->s, h->srv_no, h->ip_no, ret);
2465 2467
 			return ret;
2466 2468
 	}
2467
-skip_srv:
2469
+/*skip_srv:*/
2468 2470
 	if (name->len >= MAX_DNS_NAME) {
2469 2471
 		LOG(L_ERR, "dns_sip_resolve: domain name too long\n");
2470 2472
 		return -E_DNS_NAME_TOO_LONG;
... ...
@@ -2472,13 +2742,133 @@ skip_srv:
2472 2472
 	ret=dns_ip_resolve(&h->a, &h->ip_no, name, ip, flags);
2473 2473
 	if (port)
2474 2474
 		*port=h->port;
2475
+	if (proto)
2476
+		*proto=h->proto;
2477
+#ifdef DNS_CACHE_DEBUG
2475 2478
 	DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n", 
2476 2479
 			name->len, name->s, h->srv_no, h->ip_no, ret);
2480
+#endif
2477 2481
 	return ret;
2478 2482
 }
2479 2483
 
2480 2484
 
2481 2485
 
2486
+#ifdef USE_NAPTR
2487
+/* resolves a host name trying:
2488
+ * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
2489
+ *    *port==0 and *proto=0 and if flags allow NAPTR lookups
2490
+ * -SRV lookup if  port!=0 and *port==0
2491
+ * - normal A/AAAA lookup if *port!=0, or port==0
2492
+ * when performing SRV lookup (*port==0) it will use proto to look for
2493
+ * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2494
+ * h must be initialized prior to  calling this function and can be used to 
2495
+ * get the subsequent ips
2496
+ * returns:  <0 on error
2497
+ *            0 on success and it fills *ip, *port, dns_sip_resolve_h
2498
+ * WARNING: when finished, dns_sip_resolve_put(h) must be called!
2499
+ */
2500
+int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
2501
+						struct ip_addr* ip, unsigned short* port, char* proto,
2502
+						int flags)
2503
+{
2504
+	struct hostent* he;
2505
+	struct ip_addr* tmp_ip;
2506
+	naptr_bmp_t tried_bmp;
2507
+	struct dns_hash_entry* e;
2508
+	char n_proto;
2509
+	str srv_name;
2510
+	int ret;
2511
+	
2512
+	ret=-E_DNS_NO_NAPTR;
2513
+	if (dns_hash==0){ /* not init => use normal, non-cached version */
2514
+		LOG(L_WARN, "WARNING: dns_sip_resolve: called before dns cache"
2515
+					" initialization\n");
2516
+		h->srv=h->a=0;
2517
+		he=_sip_resolvehost(name, port, proto);
2518
+		if (he){
2519
+			hostent2ip_addr(ip, he, 0);
2520
+			return 0;
2521
+		}
2522
+		return -E_DNS_NO_NAPTR;
2523
+	}
2524
+	if (((h->srv==0) && (h->a==0)) && /* first call */
2525
+			 proto && port && (*proto==0) && (*port==0)){
2526
+		*proto=PROTO_UDP; /* just in case we don't find another */
2527
+		
2528
+		/* check if it's an ip address */
2529
+		if ( ((tmp_ip=str2ip(name))!=0)
2530
+#ifdef	USE_IPV6
2531
+			  || ((tmp_ip=str2ip6(name))!=0)
2532
+#endif
2533
+			){
2534
+			/* we are lucky, this is an ip address */
2535
+#ifdef	USE_IPV6
2536
+			if (((flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
2537
+				((flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
2538
+				return -E_DNS_AF_MISMATCH;
2539
+			}
2540
+#endif
2541
+			*ip=*tmp_ip;
2542
+			h->port=SIP_PORT;
2543
+			h->proto=*proto;
2544
+			*port=h->port;
2545
+			return 0;
2546
+		}
2547
+		/* do naptr lookup */
2548
+		if ((e=dns_get_entry(name, T_NAPTR))==0)
2549
+			goto naptr_not_found;
2550
+		naptr_iterate_init(&tried_bmp);
2551
+		while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
2552
+												&srv_name, &n_proto)){
2553
+			dns_srv_handle_init(h); /* make sure h does not contain garbage
2554
+									from previous dns_srv_sip_resolve calls */
2555
+			if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0){
2556
+#ifdef DNS_CACHE_DEBUG
2557
+				DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2558
+								name->len, name->s, h->srv_no, h->ip_no, ret);
2559
+#endif
2560
+				dns_hash_put(e);
2561
+				*proto=n_proto;
2562
+				h->proto=*proto;
2563
+				return ret;
2564
+			}
2565
+		}
2566
+		/* no acceptable naptr record found, fallback to srv */
2567
+		dns_hash_put(e);
2568
+		dns_srv_handle_init(h); /* make sure h does not contain garbage
2569
+								from previous dns_srv_sip_resolve calls */
2570
+	}
2571
+naptr_not_found:
2572
+	return dns_srv_sip_resolve(h, name, ip, port, proto, flags);
2573
+}
2574
+#endif /* USE_NAPTR */
2575
+
2576
+
2577
+
2578
+/* resolves a host name trying:
2579
+ * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
2580
+ *    *port==0 and *proto=0 and if flags allow NAPTR lookups
2581
+ * -SRV lookup if  port!=0 and *port==0
2582
+ * - normal A/AAAA lookup if *port!=0, or port==0
2583
+ * when performing SRV lookup (*port==0) it will use proto to look for
2584
+ * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2585
+ * h must be initialized prior to  calling this function and can be used to 
2586
+ * get the subsequent ips
2587
+ * returns:  <0 on error
2588
+ *            0 on success and it fills *ip, *port, dns_sip_resolve_h
2589
+ * WARNING: when finished, dns_sip_resolve_put(h) must be called!
2590
+ */
2591
+int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2592
+						struct ip_addr* ip, unsigned short* port, char* proto,
2593
+						int flags)
2594
+{
2595
+#ifdef USE_NAPTR
2596
+	if (flags&DNS_TRY_NAPTR)
2597
+		return dns_naptr_sip_resolve(h, name, ip, port, proto, flags);
2598
+#endif
2599
+	return dns_srv_sip_resolve(h, name, ip, port, proto, flags);
2600
+}
2601
+
2482 2602
 /* performs an a lookup and fills ip with the first good ip address
2483 2603
  * returns 0 on success, <0 on error (see the error codes)
2484 2604
  */
... ...
@@ -2596,12 +2986,12 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
2596 2596
 			clist_foreach(&dns_hash[h], e, next){
2597 2597
 				for (i=0, rr=e->rr_lst; rr; i++, rr=rr->next){
2598 2598
 					rpc->add(ctx, "sddddddd", 
2599
-								e->name, e->type, i, e->total_size,
2600
-								e->refcnt.val,
2601
-								(s_ticks_t)(e->expire-now)<0?-1:
2599
+								e->name, (int)e->type, i, (int)e->total_size,
2600
+								(int)e->refcnt.val,
2601
+								(int)(s_ticks_t)(e->expire-now)<0?-1:
2602 2602
 									TICKS_TO_S(e->expire-now),
2603
-								TICKS_TO_S(now-e->last_used),
2604
-								e->err_flags);
2603
+								(int)TICKS_TO_S(now-e->last_used),
2604
+								(int)e->err_flags);
2605 2605
 					switch(e->type){
2606 2606
 						case T_A:
2607 2607
 						case T_AAAA:
... ...
@@ -2616,8 +3006,8 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
2616 2616
 									((struct srv_rdata*)(rr->rdata))->name);
2617 2617
 							break;
2618 2618
 						case T_NAPTR:
2619
-							rpc->add(ctx, "ss", "naptr", 
2620
-									((struct naptr_rdata*)(rr->rdata))->flags);
2619
+							rpc->add(ctx, "ss", "naptr ",
2620
+								((struct naptr_rdata*)(rr->rdata))->flags);
2621 2621
 							break;
2622 2622
 						case T_CNAME:
2623 2623
 							rpc->add(ctx, "ss", "cname", 
... ...
@@ -2627,9 +3017,9 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
2627 2627
 							rpc->add(ctx, "ss", "unknown", "?");
2628 2628
 					}
2629 2629
 					rpc->add(ctx, "dd",
2630
-								(s_ticks_t)(rr->expire-now)<0?-1:
2630
+								(int)(s_ticks_t)(rr->expire-now)<0?-1:
2631 2631
 									TICKS_TO_S(rr->expire-now),
2632
-							rr->err_flags);
2632
+								(int)rr->err_flags);
2633 2633
 				}
2634 2634
 			}
2635 2635
 		}
... ...
@@ -29,6 +29,7 @@
29 29
 /* History:
30 30
  * --------
31 31
  *  2006-07-13  created by andrei
32
+ *  2007-06-16  naptr support (andrei)
32 33
  */
33 34
 
34 35
 
... ...
@@ -36,6 +37,7 @@
36 36
 #define __dns_cache_h
37 37
 
38 38
 #include "str.h"
39
+#include "config.h" /* MAX_BRANCHES */
39 40
 #include "timer.h"
40 41
 #include "ip_addr.h"
41 42
 #include "atomic_ops.h"
... ...
@@ -73,13 +75,12 @@ enum dns_errors{
73 73
 					E_DNS_AF_MISMATCH /* ipv4 or ipv6 only requested, but 
74 74
 										 name contains an ip addr. of the
75 75
 										 opossite type */ ,
76
+					E_DNS_NO_NAPTR /* unresolvable naptr record */,
76 77
 					E_DNS_CRITICAL /* critical error, marks the end
77 78
 									  of the error table (always last) */
78 79
 };
79 80
 
80 81
 
81
-extern int dns_flags; /* default flags used for dns lookup */
82
-extern int dns_srv_lb; /* default SRV LB support value */
83 82
 
84 83
 /* return a short string, printable error description (err <=0) */
85 84
 const char* dns_strerror(int err);
... ...
@@ -92,7 +93,8 @@ const char* dns_strerror(int err);
92 92
 #define DNS_IPV4_ONLY	1
93 93
 #define DNS_IPV6_ONLY	2
94 94
 #define DNS_IPV6_FIRST	4
95
-#define DNS_SRV_RR_LB		8  /* SRV RR weight based load balancing */
95
+#define DNS_SRV_RR_LB	8  /* SRV RR weight based load balancing */
96
+#define DNS_TRY_NAPTR	16 /* enable naptr lookup */
96 97
 
97 98
 
98 99
 /* ip blacklist error flags */
... ...
@@ -141,7 +143,14 @@ struct dns_hash_entry{
141 141
 };
142 142
 
143 143
 
144
+#if MAX_BRANCHES < 16
145
+/* forking is limited by tm to 12 by default */
146
+typedef unsigned short srv_flags_t;
147
+#elif MAX_BRANCHES < 32
144 148
 typedef unsigned int srv_flags_t;
149
+#else
150
+typedef unsigned long long srv_flags_t;
151
+#endif
145 152
 
146 153
 struct dns_srv_handle{
147 154
 	struct dns_hash_entry* srv; /* srv entry */
... ...
@@ -151,7 +160,8 @@ struct dns_srv_handle{
151 151
 #endif
152 152
 	unsigned short port; /* current port */
153 153
 	unsigned char srv_no; /* current record no. in the srv entry */
154
-	unsigned char ip_no;   /* current record no. in the a/aaaa entry */
154
+	unsigned char ip_no;  /* current record no. in the a/aaaa entry */
155
+	unsigned char proto;  /* protocol number */
155 156
 };
156 157
 
157 158
 
... ...
@@ -241,6 +251,8 @@ inline static void dns_srv_handle_init(struct dns_srv_handle* h)
241 241
 {
242 242
 	h->srv=h->a=0;
243 243
 	h->srv_no=h->ip_no=0;
244
+	h->port=0;
245
+	h->proto=0;
244 246
 #ifdef DNS_SRV_LB
245 247
 	h->srv_tried_rrs=0;
246 248
 #endif
... ...
@@ -280,13 +292,13 @@ struct hostent* dns_get_he(str* name, int flags);
280 280
  *  dns_srv_handle_put(h) must be called when h is no longer needed
281 281
  */
282 282
 int dns_sip_resolve(struct dns_srv_handle* h,  str* name, struct ip_addr* ip,
283
-					unsigned short* port, int proto, int flags);
283
+					unsigned short* port, char* proto, int flags);
284 284
 
285 285
 /* same as above, but fills su intead of changing port and filling an ip */ 
286 286
 inline static int dns_sip_resolve2su(struct dns_srv_handle* h,
287 287
 									 union sockaddr_union* su,
288 288
 									 str* name, unsigned short port,
289
-									 int proto, int flags)
289
+									 char* proto, int flags)
290 290
 {
291 291
 	struct ip_addr ip;
292 292
 	int ret;
... ...
@@ -36,6 +36,6 @@
36 36
 
37 37
 struct hostent* dns_resolvehost(char* name);
38 38
 struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
39
-										int proto);
39
+										char* proto);
40 40
 
41 41
 #endif
... ...
@@ -3,6 +3,7 @@
3 3
 # History:
4 4
 # --------
5 5
 # 2006-09-08  created by andrei
6
+# 2007-06-18  added naptr & friends, dns_srv_lb, more compile options (andrei)
6 7
 #
7 8
 
8 9
 Overview
... ...
@@ -18,6 +19,8 @@ Overview
18 18
   destination host doesn't send any reply to a forwarded invite within the
19 19
   sip timeout interval (whose value can be configured using the tm fr_timer
20 20
    parameter).
21
+ When SRV based load balancing is enabled ser can even do DNS based load 
22
+ balancing (see RFC2782 and the dns_srv_lb option below).
21 23
 
22 24
 
23 25
 DNS Cache and Failover Drawbacks
... ...
@@ -42,6 +45,19 @@ DNS Cache and Failover Drawbacks
42 42
      Workaround: compile without dns failover support (-DUSE_DNS_FAILOVER).
43 43
   Turning it off from the config file is not enough in this case (the extra
44 44
    memory will still be used).
45
+ 
46
+ On the other hand using the dns cache saves lots of DNS queries and makes
47
+ DNS based failover and DNS based load balancing possible. If the destination
48
+ blacklist is enabled, ser can do failover even if forwarding in stateless 
49
+ mode.
50
+ In the ideal case with dns cache enabled ser will do only one query for
51
+ a NAPTR (if enabled) or SRV lookup and then it will use the results for the
52
+ record's TTL (for example if all the resulting records have 1 minute TTL,
53
+  ser won't make another query for this domain for 1 minute). Even negative
54
+ answers will be cached.
55
+ Without the dns cache, each NAPTR or SRV lookup will result in at least 2 
56
+ queries. These queries will happen every time, for each message (even if 
57
+ all of them go to the same domain).
45 58
 
46 59
 
47 60
 DNS Resolver Options
... ...
@@ -59,6 +75,41 @@ DNS Resolver Options
59 59
       If off only ipv4 (A) lookups will be used.
60 60
       Default: on if ser is compiled with ipv6 support.
61 61
 
62
+   dns_try_naptr = on | off - if on ser will first try a NAPTR lookup for
63
+      destinations that don't have the protocol or port specified and 
64
+      are not simple ip addresses (as described in RFC 3263). This will 
65
+      introduce a slight performance penalty and will probably cause extra
66
+      DNS lookups. For example a lookup for a non-existing domain will
67
+      produce one extra query: NAPTR(domain), SRV(_sip._udp.domain) 
68
+      and A/AAAA(domain).
69
+      If the result of a query contains several NAPTR records, ser will select
70
+      among them according to the RFC2915 and ser preference towards a
71
+      specific protocol (see dns_udp_pref, dns_tcp_pref and dns_tls_pref 
72
+      below). For an RFC3263 compliant configuration (choose the remote side
73
+      preferred protocol if supported), set dns_udp_pref, dns_tcp_pref and
74
+      dns_tls_pref to the same value (>=0), e.g. 0.
75
+      Default: off
76
+
77
+   dns_udp_pref = number - udp protocol preference when doing NAPTR lookups.
78
+      This option works together with dns_tcp_pref and dns_tls_pref. If all
79
+      this options have the same positive value and more NAPTR records are
80
+      available, ser will select the NAPTR record preferred by the remote side
81
+      (according to RFC2915). If the values are positive but different, ser
82
+      will select the NAPTR record whose protocol it prefers the most
83
+      (the protocol with the highest dns_<proto>_pref number). If there are 
84
+       several NAPTR records with the same preferred protocol, ser will select        among them based on their order and preference (see RFC2915).
85
+      To completely disable selecting a specific protocol, use  a negative
86
+       number. For example dns_tcp_pref=-1 will completely disable selection
87
+       of tcp NAPTR records, even if this will result in the NAPTR lookup
88
+       failure.
89
+       Default: dns_udp_pref=3, dns_tcp_pref=2 and dns_tls_pref=1
90
+       (prefer udp, but if no udp NAPTR record found or no SRV-resolvable 
91
+        udp NAPTR record found use tcp records and if this fails too use tls)
92
+
93
+   dns_tcp_pref = number  (see dns_udp_pref above)
94
+
95
+   dns_tls_pref = number (see dns_udp_pref above)
96
+
62 97
    dns_retr_time = time - time in s before retrying a dns request.
63 98
       Default: system specific, depends also on the/etc/resolv.conf content
64 99
       (usually 5 s).
... ...
@@ -98,6 +149,19 @@ DNS Resolver Options
98 98
  dns server (to avoid unnecessary extra lookups).
99 99
 
100 100
 
101
+DNS Resolver Compile Options
102
+
103
+   USE_NAPTR - if defined the naptr lookup support will be compiled in.
104
+      NAPTR support still has to be enabled from ser's config file (it's
105
+      off by default).
106
+
107
+   RESOLVE_DBG - if defined, the resolver will be very verbose: it will log
108
+      a lot of debugging information at L_DBG level.
109
+
110
+   NAPTR_DBG - if defined the NAPTR related resolver functions will be very
111
+       verbose.
112
+
113
+
101 114
 DNS Cache and Failover Config Variables
102 115
 
103 116
    use_dns_cache = on | off - if off the dns cache won't be used (all dns
... ...
@@ -118,6 +182,32 @@ DNS Cache and Failover Config Variables
118 118
    Depends on use_dns_cache being on. If tm is used along with dns failover is
119 119
    recommended to also turn on dst_blacklist.
120 120
 
121
+   dns_srv_lb = on | off or
122
+   dns_srv_loadbalancing = on | off - if on instead of doing simple dns 
123
+        failover (like above), ser will load balance requests to different srv
124
+        records of the same priority based on the srv records weights (like 
125
+        described in RFC2782). For a destination which has different priorities
126
+        for all its srv records, this option will be equivalent with simple
127
+        dns failover.
128
+        Note: this option requires having dns failover enabled (see 
129
+        use_dns_failover above).
130
+        Default: off.
131
+
132
+   dns_try_ipv6 = on | off - shared with the resolver (see resolver 
133
+        description).
134
+
135
+   dns_try_naptr = on | off - shared with the resolver (see resolver 
136
+        description).
137
+
138
+   dns_udp_pref =  number - shared with the resolver (see resolver 
139
+        description).
140
+
141
+   dns_tcp_pref =  number - shared with the resolver (see resolver 
142
+        description).
143
+
144
+   dns_tls_pref =  number - shared with the resolver (see resolver 
145
+        description).
146
+
121 147
    dns_cache_flags = dns cache specific resolver flags, used for overriding
122 148
      the default behaviour (low level).
123 149
       Possible values:
... ...
@@ -165,9 +255,38 @@ DNS Cache Compile Options
165 165
    USE_DNS_FAILOVER - if defined the dns failover support will be compiled in.
166 166
       (default). Compiling the dns failover support has a few disadvantages,
167 167
       see the "Drawbacks" section.
168
+
169
+   DNS_SRV_LB  - if defined (default) support for load balancing using 
170
+       srv records weights (as described in RFC2782) will be compiled in.
171
+       Note however that it still must be enabled from the ser config, it's
172
+       disabled by default (see the dns_srv_lb config option).
173
+
174
+   USE_NAPTR  - (shared with the resolver)  if defined NAPTR support will
175
+       be compiled in (default). Note that even if compiled, NAPTR support
176
+       must be enabled also from the ser config (see the dns_try_naptr option).
177
+
178
+   NAPTR_CACHE_ALL_ARS - if defined all the additional records in a NAPTR
179
+       answer will be cached. Normally ser would cache only "related" records
180
+       (records that are directly referred), but for answers with lots of 
181
+        A/AAAA records it might happen that not all of the SRV records will fit
182
+       in the AR section. In this case, without this compile option ser will 
183
+       not cache the un-referred A/AAAA records. BY default this option is
184
+       disabled.
185
+
186
+   CACHE_RELEVANT_RECS_ONLY - if defined (default), records in the AR section
187
+       of an answer will be cached only if they are "related" to the query.
188
+       For example if the query is for a SRV record, A & AAAA records in the
189
+       AR section will be cached only if there are SRV records pointing to 
190
+       them. This avoids adding possible garbage to the cache.
191
+       If this option is not defined (experimental), everything in the AR
192
+       section will be added to the cache.
193
+
194
+   DNS_CACHE_DEBUG - if defined the dns cache will be very verbose (it will
195
+       log lots of messages at the L_DBG levell).
168 196
  
169 197
  Note: To remove a compile options,  edit ser's Makefile.defs and remove it 
170 198
    form DEFS list. To add a compile options add it to the make command line,
171 199
      e.g.: make proper; make all extra_defs=-DUSE_DNS_FAILOVER
172 200
    or for a permanent solution, edit Makefile.defs and add it to DEFS 
173
-   (don't foget to prefix it with -D).
201
+   (don't foget to prefix it with -D). Some options require editing 
202
+   dns_cache.c or resolve.[ch] (just grep after them).
... ...
@@ -315,7 +315,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
315 315
 		if (use_dns_failover){
316 316
 			dns_srv_handle_init(&dns_srv_h);
317 317
 			err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
318
-									send_info->proto, dns_flags);
318
+									&send_info->proto, dns_flags);
319 319
 			if (err!=0){
320 320
 				LOG(L_ERR, "ERROR: forward_request: resolving \"%.*s\""
321 321
 						" failed: %s [%d]\n", dst->len, ZSW(dst->s),
... ...
@@ -325,7 +325,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
325 325
 			}
326 326
 		}else
327 327
 #endif
328
-		if (sip_hostport2su(&send_info->to, dst, port, send_info->proto)<0){
328
+		if (sip_hostport2su(&send_info->to, dst, port, &send_info->proto)<0){
329 329
 			LOG(L_ERR, "ERROR: forward_request: bad host name %.*s,"
330 330
 						" dropping packet\n", dst->len, ZSW(dst->s));
331 331
 			ret=E_BAD_ADDRESS;
... ...
@@ -449,7 +449,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
449 449
 #ifdef USE_DNS_FAILOVER
450 450
 	}while(dst && use_dns_failover && dns_srv_handle_next(&dns_srv_h, err) && 
451 451
 			((err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
452
-								  send_info->proto, dns_flags))==0));
452
+								  &send_info->proto, dns_flags))==0));
453 453
 	if ((err!=0) && (err!=-E_DNS_EOR)){
454 454
 		LOG(L_ERR, "ERROR:  resolving %.*s host name in uri"
455 455
 							" failed: %s [%d] (dropping packet)\n",
... ...
@@ -483,6 +483,7 @@ int update_sock_struct_from_via( union sockaddr_union* to,
483 483
 	str* name;
484 484
 	int err;
485 485
 	unsigned short port;
486
+	char proto;
486 487
 
487 488
 	port=0;
488 489
 	if(via==msg->via1){ 
... ...
@@ -526,7 +527,8 @@ int update_sock_struct_from_via( union sockaddr_union* to,
526 526
 	    sip_resolvehost now accepts str -janakj
527 527
 	*/
528 528
 	DBG("update_sock_struct_from_via: trying SRV lookup\n");
529
-	he=sip_resolvehost(name, &port, via->proto);
529
+	proto=via->proto;
530
+	he=sip_resolvehost(name, &port, &proto);
530 531
 	
531 532
 	if (he==0){
532 533
 		LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%.*s) failure\n",
... ...
@@ -212,6 +212,8 @@ extern unsigned int dns_cache_min_ttl; /* minimum ttl */
212 212
 extern unsigned int dns_timer_interval; /* gc timer interval in s */
213 213
 extern int dns_flags; /* default flags used for the  dns_*resolvehost 
214 214
                     (compatibility wrappers) */
215
+extern int dns_srv_lb; /* default SRV LB support value */
216
+
215 217
 #endif
216 218
 #ifdef USE_DST_BLACKLIST
217 219
 extern int use_dst_blacklist; /* 1 if the blacklist is enabled */
... ...
@@ -89,13 +89,13 @@ struct socket_info{
89 89
 	str name; /* name - eg.: foo.bar or 10.0.0.1 */
90 90
 	struct ip_addr address; /* ip address */
91 91
 	str address_str;        /* ip address converted to string -- optimization*/
92
-	unsigned short port_no;  /* port number */
93 92
 	str port_no_str; /* port number converted to string -- optimization*/
94 93
 	enum si_flags flags; /* SI_IS_IP | SI_IS_LO | SI_IS_MCAST */
95 94
 	union sockaddr_union su; 
96
-	int proto; /* tcp or udp*/
97 95
 	struct socket_info* next;
98 96
 	struct socket_info* prev;
97
+	unsigned short port_no;  /* port number */
98
+	char proto; /* tcp or udp*/
99 99
 };
100 100
 
101 101
 
... ...
@@ -109,7 +109,7 @@ struct receive_info{
109 109
 	union sockaddr_union src_su; /* useful for replies*/
110 110
 	struct socket_info* bind_address; /* sock_info structure on which 
111 111
 									  the msg was received*/
112
-	short proto;
112
+	char proto;
113 113
 #ifdef USE_COMP
114 114
 	short comp; /* compression */
115 115
 #endif
... ...
@@ -121,7 +121,7 @@ struct dest_info{
121 121
 	struct socket_info* send_sock;
122 122
 	union sockaddr_union to;
123 123
 	int id; /* tcp stores the connection id here */ 
124
-	short proto;
124
+	char proto;
125 125
 #ifdef USE_COMP
126 126
 	short comp;
127 127
 #endif
... ...
@@ -1579,7 +1579,7 @@ try_again:
1579 1579
 		goto error;
1580 1580
 	}
1581 1581
 #ifdef USE_DNS_CACHE
1582
-	if (init_dns_cache()<0){
1582
+	if (use_dns_cache && init_dns_cache()<0){
1583 1583
 		LOG(L_CRIT, "could not initialize the dns cache, exiting...\n");
1584 1584
 		goto error;
1585 1585
 	}
... ...
@@ -200,10 +200,11 @@ error:
200 200
 /* same as add_proxy, but it doesn't add the proxy to the list
201 201
  * uses also SRV if possible & port==0 (quick hack) */
202 202
 
203
-struct proxy_l* mk_proxy(str* name, unsigned short port, int proto)
203
+struct proxy_l* mk_proxy(str* name, unsigned short port, int protocol)
204 204
 {
205 205
 	struct proxy_l* p;
206 206
 	struct hostent* he;
207
+	char proto;
207 208
 
208 209
 	p=(struct proxy_l*) pkg_malloc(sizeof(struct proxy_l));
209 210
 	if (p==0){
... ...
@@ -214,10 +215,10 @@ struct proxy_l* mk_proxy(str* name, unsigned short port, int proto)
214 214
 	memset(p,0,sizeof(struct proxy_l));
215 215
 	p->name=*name;
216 216
 	p->port=port;
217
-	p->proto=proto;
218 217
 
219 218
 	DBG("DEBUG: mk_proxy: doing DNS lookup...\n");
220
-	he=sip_resolvehost(name, &(p->port), proto);
219
+	proto=protocol;
220
+	he=sip_resolvehost(name, &(p->port), &proto);
221 221
 	if (he==0){
222 222
 		ser_error=E_BAD_ADDRESS;
223 223
 		LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
... ...
@@ -229,6 +230,7 @@ struct proxy_l* mk_proxy(str* name, unsigned short port, int proto)
229 229
 		pkg_free(p);
230 230
 		goto error;
231 231
 	}
232
+	p->proto=proto;
232 233
 	p->ok=1;
233 234
 	return p;
234 235
 error:
... ...
@@ -35,6 +35,7 @@
35 35
  *  2006-07-17  rdata contains now also the record name (andrei)
36 36
  *  2006-08-18  get_record can append also the additional records to the
37 37
  *               returned list (andrei)
38
+ *  2007-06-15  naptr support (andrei)
38 39
  */ 
39 40
 
40 41
 
... ...
@@ -45,10 +46,12 @@
45 45
 #include <string.h>
46 46
 
47 47
 #include "resolve.h"
48
+#include "compiler_opt.h"
48 49
 #include "dprint.h"
49 50
 #include "mem/mem.h"
50 51
 #include "ip_addr.h"
51 52
 #include "error.h"
53
+#include "globals.h" /* tcp_disable, tls_disable a.s.o */
52 54
 
53 55
 #ifdef USE_DNS_CACHE
54 56
 #include "dns_cache.h"
... ...
@@ -65,6 +68,17 @@ int dns_try_ipv6=1; /* default on */
65 65
 #else
66 66
 int dns_try_ipv6=0; /* off, if no ipv6 support */
67 67
 #endif
68
+int dns_try_naptr=0;  /* off by default */
69
+
70
+int dns_udp_pref=3;  /* udp transport preference (for naptr) */
71
+int dns_tcp_pref=2;  /* tcp transport preference (for naptr) */
72
+int dns_tls_pref=1;  /* tls transport preference (for naptr) */
73
+
74
+#ifdef USE_NAPTR
75
+#define PROTO_LAST  PROTO_SCTP
76
+static int naptr_proto_pref[PROTO_LAST];
77
+#endif
78
+
68 79
 /* declared in globals.h */
69 80
 int dns_retr_time=-1;
70 81
 int dns_retr_no=-1;
... ...
@@ -72,6 +86,23 @@ int dns_servers_no=-1;
72 72
 int dns_search_list=-1;
73 73
 
74 74
 
75
+#ifdef USE_NAPTR
76
+void init_naptr_proto_prefs()
77
+{
78
+	if ((PROTO_UDP >= PROTO_LAST) || (PROTO_TCP >= PROTO_LAST) ||
79
+		(PROTO_TLS >= PROTO_LAST)){
80
+		BUG("init_naptr_proto_prefs: array too small \n");
81
+		return;
82
+	}
83
+	naptr_proto_pref[PROTO_UDP]=dns_udp_pref;
84
+	naptr_proto_pref[PROTO_TCP]=dns_tcp_pref;
85
+	naptr_proto_pref[PROTO_TLS]=dns_tls_pref;
86
+}
87
+
88
+#endif /* USE_NAPTR */
89
+
90
+
91
+
75 92
 /* init. the resolver
76 93
  * params: retr_time  - time before retransmitting (must be >0)
77 94
  *         retr_no    - retransmissions number
... ...
@@ -103,6 +134,9 @@ int resolv_init()
103 103
 	LOG(L_WARN, "WARNING: resolv_init: no resolv options support - resolv"
104 104
 			" options will be ignored\n");
105 105
 #endif
106
+#ifdef USE_NAPTR
107
+	init_naptr_proto_prefs();
108
+#endif
106 109
 	return 0;
107 110
 }
108 111
 
... ...
@@ -266,8 +300,8 @@ struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
266 266
 		LOG(L_ERR, "ERROR: dns_naptr_parser: out of memory\n");
267 267
 		goto error;
268 268
 	}
269
-	naptr->order=ntohs(naptr->order);
270
-	naptr->pref=ntohs(naptr->pref);
269
+	naptr->order=ntohs(order);
270
+	naptr->pref=ntohs(pref);
271 271
 	
272 272
 	naptr->flags=&naptr->str_table[0];
273 273
 	naptr->flags_len=flags_len;
... ...
@@ -555,7 +589,9 @@ again:
555 555
 	if (flags & RES_AR){
556 556
 		flags&=~RES_AR;
557 557
 		answers_no=ntohs((unsigned short)buff.hdr.nscount);
558
+#ifdef RESOLVE_DBG
558 559
 		DBG("get_record: skipping %d NS (p=%p, end=%p)\n", answers_no, p, end);
560
+#endif
559 561
 		for (r=0; (r<answers_no) && (p<end); r++){
560 562
 			/* skip over the ns records */
561 563
 			if ((p=dns_skipname(p, end))==0) {
... ...
@@ -568,7 +604,9 @@ again:
568 568
 			p+=2+2+4+2+ntohs(rdlength);
569 569
 		}
570 570
 		answers_no=ntohs((unsigned short)buff.hdr.arcount);
571
+#ifdef RESOLVE_DBG
571 572
 		DBG("get_record: parsing %d ARs (p=%p, end=%p)\n", answers_no, p, end);
573
+#endif
572 574
 		goto again; /* add also the additional records */
573 575
 	}
574 576
 			
... ...
@@ -591,47 +629,242 @@ not_found:
591 591
 	return 0;
592 592
 }
593 593
 
594
+#ifdef USE_NAPTR
594 595
 
596
+/* service matching constants, lowercase */
597
+#define SIP_SCH		0x2b706973
598
+#define SIPS_SCH	0x73706973
599
+#define SIP_D2U		0x00753264
600
+#define SIP_D2T		0x00743264
601
+#define SIP_D2S		0x00733264
602
+#define SIPS_D2T	0x7432642b
595 603
 
596 604