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 422
 	 -DUSE_DNS_CACHE \
421 423
 	 -DUSE_DNS_FAILOVER \
422 424
 	 -DUSE_DST_BLACKLIST \
423
-	 -DDBG_QM_MALLOC \
425
+	 -DUSE_NAPTR \
424 426
 	 #-DLL_MALLOC \
425 427
 	 #-DSF_MALLOC \
426 428
 	 #-DDL_MALLOC \
427 429
 	 #-DF_MALLOC \
430
+	 #-DDBG_QM_MALLOC \
428 431
 	 #-DDBG_F_MALLOC \
429 432
 	 #-DNO_DEBUG \
430 433
 	 #-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 81
                long held locks, almost no performance impact otherwise)
80 82
 
81 83
 new config variables:
84
+  dns_srv_lb = yes | no (default no) - enable dns srv weight based load 
85
+    balancing (see doc/dns.txt)
86
+  dns_try_naptr = yes | no (default no) - enable naptr support 
87
+    (see doc/dns.txt for more info)
88
+  dns_{udp,tcp,tls}_pref = number - ser preference for each protocol when
89
+    doing naptr lookups. By default dns_udp_pref=3, dns_tcp_pref=2 and 
90
+    dns_tls_pref=1. To use the remote site preferences set all dns_*_pref to 
91
+    the same positive value (e.g. dns_udp_pref=1, dns_tcp_pref=1, 
92
+    dns_udp_pref=1). To completely ignore NAPTR records for a specific 
93
+    protocol, set the corresponding protocol preference to -1 (or any other 
94
+    negative number).  (see doc/dns.txt for more info)
82 95
   mlock_pages = yes |no (default no) - locks all ser pages into memory making 
83 96
     it unswappable (in general one doesn't want his sip proxy swapped out :-))
84 97
   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 233
 DNS		 dns
232 234
 REV_DNS	 rev_dns
233 235
 DNS_TRY_IPV6	dns_try_ipv6
236
+DNS_TRY_NAPTR	dns_try_naptr
237
+DNS_SRV_LB		dns_srv_lb|dns_srv_loadbalancing
238
+DNS_UDP_PREF	dns_udp_pref|dns_udp_preference
239
+DNS_TCP_PREF	dns_tcp_pref|dns_tcp_preference
240
+DNS_TLS_PREF	dns_tls_pref|dns_tls_preference
234 241
 DNS_RETR_TIME	dns_retr_time
235 242
 DNS_RETR_NO		dns_retr_no
236 243
 DNS_SERVERS_NO	dns_servers_no
... ...
@@ -455,6 +462,16 @@ EAT_ABLE	[\ \t\b\r]
455 462
 <INITIAL>{REV_DNS}	{ count(); yylval.strval=yytext; return REV_DNS; }
456 463
 <INITIAL>{DNS_TRY_IPV6}	{ count(); yylval.strval=yytext;
457 464
 								return DNS_TRY_IPV6; }
465
+<INITIAL>{DNS_TRY_NAPTR}	{ count(); yylval.strval=yytext;
466
+								return DNS_TRY_NAPTR; }
467
+<INITIAL>{DNS_SRV_LB}	{ count(); yylval.strval=yytext;
468
+								return DNS_SRV_LB; }
469
+<INITIAL>{DNS_UDP_PREF}	{ count(); yylval.strval=yytext;
470
+								return DNS_UDP_PREF; }
471
+<INITIAL>{DNS_TCP_PREF}	{ count(); yylval.strval=yytext;
472
+								return DNS_TCP_PREF; }
473
+<INITIAL>{DNS_TLS_PREF}	{ count(); yylval.strval=yytext;
474
+								return DNS_TLS_PREF; }
458 475
 <INITIAL>{DNS_RETR_TIME}	{ count(); yylval.strval=yytext;
459 476
 								return DNS_RETR_TIME; }
460 477
 <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 140
 	#define IF_DNS_FAILOVER(x) warn("dns failover support not compiled in")
140 141
 #endif
141 142
 
143
+#ifdef USE_NAPTR
144
+	#define IF_NAPTR(x) x
145
+#else
146
+	#define IF_NAPTR(x) warn("dns naptr support not compiled in")
147
+#endif
148
+
142 149
 #ifdef USE_DST_BLACKLIST
143 150
 	#define IF_DST_BLACKLIST(x) x
144 151
 #else
... ...
@@ -265,6 +272,11 @@ static struct socket_id* mk_listen_id(char*, int, int);
265 272
 %token DNS
266 273
 %token REV_DNS
267 274
 %token DNS_TRY_IPV6
275
+%token DNS_TRY_NAPTR
276
+%token DNS_SRV_LB
277
+%token DNS_UDP_PREF
278
+%token DNS_TCP_PREF
279
+%token DNS_TLS_PREF
268 280
 %token DNS_RETR_TIME
269 281
 %token DNS_RETR_NO
270 282
 %token DNS_SERVERS_NO
... ...
@@ -570,6 +582,16 @@ assign_stm:
570 582
 	| REV_DNS EQUAL error { yyerror("boolean value expected"); }
571 583
 	| DNS_TRY_IPV6 EQUAL NUMBER   { dns_try_ipv6=$3; }
572 584
 	| DNS_TRY_IPV6 error { yyerror("boolean value expected"); }
585
+	| DNS_TRY_NAPTR EQUAL NUMBER   { IF_NAPTR(dns_try_naptr=$3); }
586
+	| DNS_TRY_NAPTR error { yyerror("boolean value expected"); }
587
+	| DNS_SRV_LB EQUAL NUMBER   { IF_DNS_FAILOVER(dns_srv_lb=$3); }
588
+	| DNS_SRV_LB error { yyerror("boolean value expected"); }
589
+	| DNS_UDP_PREF EQUAL NUMBER   { IF_NAPTR(dns_udp_pref=$3); }
590
+	| DNS_UDP_PREF error { yyerror("number expected"); }
591
+	| DNS_TCP_PREF EQUAL NUMBER   { IF_NAPTR(dns_tcp_pref=$3); }
592
+	| DNS_TCP_PREF error { yyerror("number expected"); }
593
+	| DNS_TLS_PREF EQUAL NUMBER   { IF_NAPTR(dns_tls_pref=$3); }
594
+	| DNS_TLS_PREF error { yyerror("number expected"); }
573 595
 	| DNS_RETR_TIME EQUAL NUMBER   { dns_retr_time=$3; }
574 596
 	| DNS_RETR_TIME error { yyerror("number expected"); }
575 597
 	| 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 89
 unsigned int dns_timer_interval=DEFAULT_DNS_TIMER_INTERVAL; /* in s */
89 90
 int dns_flags=0; /* default flags used for the  dns_*resolvehost 
90 91
                     (compatibility wrappers) */
91
-int dns_srv_lb=1; /* off by default */
92
+int dns_srv_lb=0; /* off by default */
92 93
 
93 94
 #define LOCK_DNS_HASH()		lock_get(dns_hash_lock)
94 95
 #define UNLOCK_DNS_HASH()	lock_release(dns_hash_lock)
... ...
@@ -126,6 +127,7 @@ static const char* dns_str_errors[]={
126 127
 	"blacklisted ip",
127 128
 	"name too long ", /* try again with a shorter name */
128 129
 	"ip AF mismatch", /* address family mismatch */
130
+	"unresolvable NAPTR request", 
129 131
 	"bug - critical error"
130 132
 };
131 133
 
... ...
@@ -293,6 +295,13 @@ int init_dns_cache()
293 295
 					" support for it is not compiled -- ignoring\n");
294 296
 #endif
295 297
 	}
298
+	if (dns_try_naptr){
299
+#ifndef USE_NAPTR
300
+	LOG(L_WARN, "WARING: dns_cache_init: NAPTR support is enabled, but"
301
+				" support for it is not compiled -- ignoring\n");
302
+#endif
303
+		dns_flags|=DNS_TRY_NAPTR;
304
+	}
296 305
 	dns_timer_h=timer_alloc();
297 306
 	if (dns_timer_h==0){
298 307
 		ret=E_OUT_OF_MEM;
... ...
@@ -411,8 +420,10 @@ inline static struct dns_hash_entry* _dns_hash_find(str* name, int type,
411 420
 	*err=0;
412 421
 again:
413 422
 	*h=dns_hash_no(name->s, name->len, type);
423
+#ifdef DNS_CACHE_DEBUG
414 424
 	DBG("dns_hash_find(%.*s(%d), %d), h=%d\n", name->len, name->s,
415 425
 												name->len, type, *h);
426
+#endif
416 427
 	clist_foreach_safe(&dns_hash[*h], e, tmp, next){
417 428
 		/* automatically remove expired elements */
418 429
 		if ((s_ticks_t)(now-e->expire)>=0){
... ...
@@ -645,8 +656,10 @@ inline static int dns_cache_add(struct dns_hash_entry* e)
645 656
 	}
646 657
 	atomic_inc(&e->refcnt);
647 658
 	h=dns_hash_no(e->name, e->name_len, e->type);
659
+#ifdef DNS_CACHE_DEBUG
648 660
 	DBG("dns_cache_add: adding %.*s(%d) %d (flags=%0x) at %d\n",
649 661
 			e->name_len, e->name, e->name_len, e->type, e->err_flags, h);
662
+#endif
650 663
 	LOCK_DNS_HASH();
651 664
 		*dns_cache_mem_used+=e->total_size; /* no need for atomic ops, written
652 665
 										 only from within a lock */
... ...
@@ -681,8 +694,10 @@ inline static int dns_cache_add_unsafe(struct dns_hash_entry* e)
681 694
 	}
682 695
 	atomic_inc(&e->refcnt);
683 696
 	h=dns_hash_no(e->name, e->name_len, e->type);
697
+#ifdef DNS_CACHE_DEBUG
684 698
 	DBG("dns_cache_add: adding %.*s(%d) %d (flags=%0x) at %d\n",
685 699
 			e->name_len, e->name, e->name_len, e->type, e->err_flags, h);
700
+#endif
686 701
 	*dns_cache_mem_used+=e->total_size; /* no need for atomic ops, written
687 702
 										 only from within a lock */
688 703
 	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 719
 	int size;
705 720
 	ticks_t now;
706 721
 	
722
+#ifdef DNS_CACHE_DEBUG
707 723
 	DBG("dns_cache_mk_bad_entry(%.*s, %d, %d, %d)\n", name->len, name->s,
708 724
 									type, ttl, flags);
725
+#endif
709 726
 	size=sizeof(struct dns_hash_entry)+name->len-1+1;
710 727
 	e=shm_malloc(size);
711 728
 	if (e==0){
... ...
@@ -937,8 +954,10 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
937 954
 	}
938 955
 	*tail=0; /* mark the end of our tmp_lst */
939 956
 	if (size==0){
957
+#ifdef DNS_CACHE_DEBUG
940 958
 		DBG("dns_cache_mk_rd_entry: entry %.*s (%d) not found\n",
941 959
 				name->len, name->s, type);
960
+#endif
942 961
 		return 0;
943 962
 	}
944 963
 	/* compute size */
... ...
@@ -949,6 +968,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
949 968
 		return 0;
950 969
 	}
951 970
 	memset(e, 0, size); /* init with 0 */
971
+	clist_init(e, next, prev);
952 972
 	e->total_size=size;
953 973
 	e->name_len=name->len;
954 974
 	e->type=type;
... ...
@@ -1013,7 +1033,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1013 1033
 				max_ttl=MAX(max_ttl, ttl);
1014 1034
 				rr->rdata=(void*)((char*)rr+
1015 1035
 								ROUND_POINTER(sizeof(struct dns_rr)));
1016
-				/* copy the whole srv_rdata block*/
1036
+				/* copy the whole naptr_rdata block*/
1017 1037
 				memcpy(rr->rdata, l->rdata, 
1018 1038
 						NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
1019 1039
 				/* adjust the string pointer */
... ...
@@ -1034,6 +1054,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1034 1054
 										NAPTR_RDATA_SIZE(
1035 1055
 											*(struct naptr_rdata*)l->rdata)));
1036 1056
 				tail_rr=&(rr->next);
1057
+				rr=rr->next;
1037 1058
 			}
1038 1059
 			break;
1039 1060
 		case T_CNAME:
... ...
@@ -1267,6 +1288,7 @@ found:
1267 1288
 										NAPTR_RDATA_SIZE(
1268 1289
 											*(struct naptr_rdata*)l->rdata)));
1269 1290
 				rec[r].tail_rr=&(rec[r].rr->next);
1291
+				rec[r].rr=rec[r].rr->next;
1270 1292
 				break;
1271 1293
 			case T_CNAME:
1272 1294
 				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 1354
 	
1333 1355
 	ret=0;
1334 1356
 	l=e;
1357
+#ifdef DNS_CACHE_DEBUG
1335 1358
 	DBG("dns_get_related(%p (%.*s, %d), %d, *%p) (%d)\n", e,
1336 1359
 			e->name_len, e->name, e->type, type, *records, cname_chain_len);
1360
+#endif
1337 1361
 	clist_init(l, next, prev);
1338 1362
 	if (type==e->type){
1339 1363
 		ret=e;
... ...
@@ -1347,7 +1371,8 @@ inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
1347 1371
 						if (t){
1348 1372
 							if ((t->type==T_CNAME) && *records)
1349 1373
 								dns_get_related(t, T_A, records);
1350
-							clist_append(l, t, next, prev);
1374
+							lst_end=t->prev; /* needed for clist_append*/
1375
+							clist_append_sublist(l, t, lst_end, next, prev);
1351 1376
 						}
1352 1377
 					}
1353 1378
 					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 1380
 						if (t){
1356 1381
 							if ((t->type==T_CNAME) && *records)
1357 1382
 								dns_get_related(t, T_AAAA, records);
1358
-							clist_append(l, t, next, prev);
1383
+							lst_end=t->prev; /* needed for clist_append*/
1384
+							clist_append_sublist(l, t, lst_end, next, prev);
1359 1385
 						}
1360 1386
 					}
1361 1387
 				}
1362 1388
 				break;
1389
+#ifdef USE_NAPTR
1390
+			case T_NAPTR:
1391
+#ifdef NAPTR_CACHE_ALL_ARS
1392
+				if (*records)
1393
+						dns_cache_mk_rd_entry2(*records);
1394
+#else
1395
+				for (rr=e->rr_lst; rr && *records; rr=rr->next){
1396
+					if (naptr_get_sip_proto((struct naptr_rdata*)rr->rdata)>0){
1397
+						tmp.s=((struct naptr_rdata*)rr->rdata)->repl;
1398
+						tmp.len=((struct naptr_rdata*)rr->rdata)->repl_len;
1399
+						t=dns_cache_mk_rd_entry(&tmp, T_SRV, records);
1400
+						if (t){
1401
+							if (*records)
1402
+								dns_get_related(t, T_SRV, records);
1403
+							lst_end=t->prev; /* needed for clist_append*/
1404
+							clist_append_sublist(l, t, lst_end, next, prev);
1405
+						}
1406
+					}
1407
+				}
1408
+#endif /* NAPTR_CACHE_ALL_ARS */
1409
+#endif /* USE_NAPTR */
1410
+				break;
1363 1411
 			default:
1364 1412
 				/* nothing extra */
1365 1413
 				break;
... ...
@@ -1593,7 +1641,7 @@ error:
1593 1641
  *               now - current time/ticks value
1594 1642
  * returns pointer to the rr on success and sets no to the rr number
1595 1643
  *         0 on error and fills the error flags
1596
- *
1644
+	*
1597 1645
  * Example usage:
1598 1646
  * list all non-expired non-bad-marked ips for name:
1599 1647
  * e=dns_get_entry(name, T_A);
... ...
@@ -1980,6 +2028,36 @@ struct hostent* dns_resolvehost(char* name)
1980 2028
 
1981 2029
 
1982 2030
 
2031
+
2032
+#if 0
2033
+/* resolves a host name trying  NAPTR,  SRV, A & AAAA lookups, for details
2034
+ *  see dns_sip_resolve()
2035
+ *  FIXME: this version will return only the first ip
2036
+ * returns: hostent struct & *port filled with the port from the SRV record;
2037
+ *  0 on error
2038
+ */
2039
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2040
+										char* proto)
2041
+{
2042
+	struct dns_srv_handle h;
2043
+	struct ip_addr ip;
2044
+	int ret;
2045
+	
2046
+	if ((use_dns_cache==0) || (dns_hash==0)){ 
2047
+		/* not init or off => use normal, non-cached version */
2048
+		return _sip_resolvehost(name, port, proto);
2049
+	}
2050
+	dns_srv_handle_init(&h);
2051
+	ret=dns_sip_resolve(&h, name, &ip, port, proto, dns_flags);
2052
+	dns_srv_handle_put(&h);
2053
+	if (ret>=0)
2054
+		return ip_addr2he(name, &ip);
2055
+	return 0;
2056
+}
2057
+#endif
2058
+
2059
+
2060
+
1983 2061
 /* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup
1984 2062
  * if *port!=0.
1985 2063
  * when performing SRV lookup (*port==0) it will use proto to look for
... ...
@@ -1987,23 +2065,33 @@ struct hostent* dns_resolvehost(char* name)
1987 2065
  * returns: hostent struct & *port filled with the port from the SRV record;
1988 2066
  *  0 on error
1989 2067
  */
1990
-struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, int proto)
2068
+struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port, 
2069
+										char* proto)
1991 2070
 {
1992 2071
 	struct hostent* he;
1993 2072
 	struct ip_addr* ip;
1994 2073
 	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
1995 2074
 	int len;
1996 2075
 	str srv_name;
2076
+	char srv_proto;
1997 2077
 
1998 2078
 	if ((use_dns_cache==0) || (dns_hash==0)){ 
1999 2079
 		/* not init or off => use normal, non-cached version */
2000 2080
 		return _sip_resolvehost(name, port, proto);
2001 2081
 	}
2002 2082
 	len=0;
2083
+	if (proto){ /* makes sure we have a protocol set*/
2084
+		if (*proto==0)
2085
+			*proto=srv_proto=PROTO_UDP; /* default */
2086
+		else
2087
+			srv_proto=*proto;
2088
+	}else{
2089
+		srv_proto=PROTO_UDP;
2090
+	}
2003 2091
 	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
2004 2092
 	if ((port)&&(*port==0)){
2005
-		*port=(proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we don't
2006
-														find another */
2093
+		*port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we 
2094
+														 don't find another */
2007 2095
 		if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
2008 2096
 			LOG(L_WARN, "WARNING: dns_sip_resolvehost: domain name too long"
2009 2097
 						" (%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 2106
 				return ip_addr2he(name,ip);
2019 2107
 			}
2020 2108
 			
2021
-			switch(proto){
2109
+			switch(srv_proto){
2022 2110
 				case PROTO_NONE: /* no proto specified, use udp */
2023
-					goto skip_srv;
2111
+					if (proto)
2112
+						*proto=PROTO_UDP;
2113
+					/* no break */
2024 2114
 				case PROTO_UDP:
2025 2115
 					memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
2026 2116
 					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 2131
 					break;
2042 2132
 				default:
2043 2133
 					LOG(L_CRIT, "BUG: sip_resolvehost: unknown proto %d\n",
2044
-							proto);
2134
+							(int)srv_proto);
2045 2135
 					return 0;
2046 2136
 			}
2047 2137
 
... ...
@@ -2051,7 +2141,7 @@ struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, int proto)
2051 2141
 				return he;
2052 2142
 		}
2053 2143
 	}
2054
-skip_srv:
2144
+/*skip_srv:*/
2055 2145
 	if (name->len >= MAX_DNS_NAME) {
2056 2146
 		LOG(L_ERR, "dns_sip_resolvehost: domain name too long\n");
2057 2147
 		return 0;
... ...
@@ -2062,6 +2152,170 @@ skip_srv:
2062 2152
 
2063 2153
 
2064 2154
 
2155
+#ifdef USE_NAPTR
2156
+/* iterates over a naptr rr list, returning each time a "good" naptr record
2157
+ * is found.( srv type, no regex and a supported protocol)
2158
+ * params:
2159
+ *         naptr_head - naptr dns_rr list head
2160
+ *         tried      - bitmap used to keep track of the already tried records
2161
+ *                      (no more then sizeof(tried)*8 valid records are 
2162
+ *                      ever walked
2163
+ *         srv_name   - if succesfull, it will be set to the selected record
2164
+ *                      srv name (naptr repl.)
2165
+ *         proto      - if succesfull it will be set to the selected record
2166
+ *                      protocol
2167
+ * returns  0 if no more records found or a pointer to the selected record
2168
+ *  and sets  protocol and srv_name
2169
+ * WARNING: when calling first time make sure you run first 
2170
+ *           naptr_iterate_init(&tried)
2171
+ */
2172
+struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head, 
2173
+											naptr_bmp_t* tried,
2174
+											str* srv_name, char* proto)
2175
+{
2176
+	int i, idx;
2177
+	struct dns_rr* l;
2178
+	struct naptr_rdata* naptr;
2179
+	struct naptr_rdata* naptr_saved;
2180
+	char saved_proto;
2181
+	char naptr_proto;
2182
+
2183
+	idx=0;
2184
+	naptr_proto=PROTO_NONE;
2185
+	naptr_saved=0;
2186
+	saved_proto=0;
2187
+	i=0;
2188
+	for(l=naptr_head; l && (i<MAX_NAPTR_RRS); l=l->next){
2189
+		naptr=(struct naptr_rdata*) l->rdata;
2190
+		if (naptr==0){
2191
+				LOG(L_CRIT, "naptr_iterate: BUG: null rdata\n");
2192
+			goto end;
2193
+		}
2194
+		/* check if valid and get proto */
2195
+		if ((naptr_proto=naptr_get_sip_proto(naptr))<=0) continue;
2196
+		if (*tried& (1<<i)){
2197
+			i++;
2198
+			continue; /* already tried */
2199
+		}
2200
+#ifdef DNS_CACHE_DEBUG
2201
+		DBG("naptr_iterate: found a valid sip NAPTR rr %.*s,"
2202
+					" proto %d\n", naptr->repl_len, naptr->repl, 
2203
+					(int)naptr_proto);
2204
+#endif
2205
+		if ((naptr_proto_supported(naptr_proto))){
2206
+			if (naptr_choose(&naptr_saved, &saved_proto,
2207
+								naptr, naptr_proto))
2208
+				idx=i;
2209
+			}
2210
+		i++;
2211
+	}
2212
+	if (naptr_saved){
2213
+		/* found something */
2214
+#ifdef DNS_CACHE_DEBUG
2215
+		DBG("naptr_iterate: choosed NAPTR rr %.*s, proto %d"
2216
+					" tried: 0x%x\n", naptr_saved->repl_len, 
2217
+					naptr_saved->repl, (int)saved_proto, *tried);
2218
+#endif
2219
+		*tried|=1<<idx;
2220
+		*proto=saved_proto;
2221
+		srv_name->s=naptr_saved->repl;
2222
+		srv_name->len=naptr_saved->repl_len;
2223
+		return naptr_saved;
2224
+	}
2225
+end:
2226
+	return 0;
2227
+}
2228
+
2229
+
2230
+
2231
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2232
+ * lookup if *port==0 or normal A/AAAA lookup
2233
+ * if *port!=0.
2234
+ * when performing SRV lookup (*port==0) it will use proto to look for
2235
+ * tcp or udp hosts; if proto==0 => no SRV lookup
2236
+ * returns: hostent struct & *port filled with the port from the SRV record;
2237
+ *  0 on error
2238
+ */
2239
+struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port, 
2240
+										char* proto)
2241
+{
2242
+	struct hostent* he;
2243
+	struct ip_addr* tmp_ip;
2244
+	naptr_bmp_t tried_bmp;
2245
+	struct dns_hash_entry* e;
2246
+	char n_proto;
2247
+	str srv_name;
2248
+	
2249
+	he=0;
2250
+	if (dns_hash==0){ /* not init => use normal, non-cached version */
2251
+		LOG(L_WARN, "WARNING: dns_sip_resolvehost: called before dns cache"
2252
+					" initialization\n");
2253
+		return _sip_resolvehost(name, port, proto);
2254
+	}
2255
+	if (proto && port && (*proto==0) && (*port==0)){
2256
+		*proto=PROTO_UDP; /* just in case we don't find another */
2257
+		/* check if it's an ip address */
2258
+		if ( ((tmp_ip=str2ip(name))!=0)
2259
+#ifdef	USE_IPV6
2260
+			  || ((tmp_ip=str2ip6(name))!=0)
2261
+#endif
2262
+			){
2263
+			/* we are lucky, this is an ip address */
2264
+#ifdef	USE_IPV6
2265
+			if (((dns_flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
2266
+				((dns_flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
2267
+				return 0;
2268
+			}
2269
+#endif
2270
+			*port=SIP_PORT;
2271
+			return ip_addr2he(name, tmp_ip);
2272
+		}
2273
+		/* do naptr lookup */
2274
+		if ((e=dns_get_entry(name, T_NAPTR))==0)
2275
+			goto naptr_not_found;
2276
+		naptr_iterate_init(&tried_bmp);
2277
+		while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
2278
+												&srv_name, &n_proto)){
2279
+			if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0){
2280
+#ifdef DNS_CACHE_DEBUG
2281
+				DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n", 
2282
+							name->len, name->s, (int)*port, (int)*proto, he);
2283
+#endif
2284
+				dns_hash_put(e);
2285
+				*proto=n_proto;
2286
+				return he;
2287
+			}
2288
+		}
2289
+		/* no acceptable naptr record found, fallback to srv */
2290
+		dns_hash_put(e);
2291
+	}
2292
+naptr_not_found:
2293
+	return dns_srv_sip_resolvehost(name, port, proto);
2294
+}
2295
+#endif /* USE_NAPTR */
2296
+
2297
+
2298
+
2299
+/* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV 
2300
+ * lookup if *port==0 or normal A/AAAA lookup
2301
+ * if *port!=0.
2302
+ * when performing SRV lookup (*port==0) it will use proto to look for
2303
+ * tcp or udp hosts; if proto==0 => no SRV lookup
2304
+ * returns: hostent struct & *port filled with the port from the SRV record;
2305
+ *  0 on error
2306
+ */
2307
+struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, 
2308
+										char* proto)
2309
+{
2310
+#ifdef USE_NAPTR
2311
+	if (dns_flags&DNS_TRY_NAPTR)
2312
+		return dns_naptr_sip_resolvehost(name, port, proto);
2313
+#endif
2314
+	return dns_srv_sip_resolvehost(name, port, proto);
2315
+}
2316
+
2317
+
2318
+
2065 2319
 /* performs an a lookup, fills the dns_entry pointer and the ip addr.
2066 2320
  *  (with the first good ip). if *e ==0 does the a lookup, and changes it
2067 2321
  *   to the result, if not it uses the current value and tries to use 
... ...
@@ -2359,8 +2613,8 @@ error:
2359 2613
  *            0 on success and it fills *ip, *port, dns_sip_resolve_h
2360 2614
  * WARNING: when finished, dns_sip_resolve_put(h) must be called!
2361 2615
  */
2362
-int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2363
-						struct ip_addr* ip, unsigned short* port, int proto,
2616
+int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
2617
+						struct ip_addr* ip, unsigned short* port, char* proto,
2364 2618
 						int flags)
2365 2619
 {
2366 2620
 	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 2623
 	struct ip_addr* tmp_ip;
2370 2624
 	int ret;
2371 2625
 	struct hostent* he;
2626
+	char srv_proto;
2372 2627
 
2373 2628
 	if (dns_hash==0){ /* not init => use normal, non-cached version */
2374 2629
 		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 2638
 	}
2384 2639
 	len=0;
2385 2640
 	if ((h->srv==0) && (h->a==0)){ /* first call */
2386
-		h->port=(proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
2641
+		if (proto){ /* makes sure we have a protocol set*/
2642
+			if (*proto==0)
2643
+				*proto=srv_proto=PROTO_UDP; /* default */
2644
+			else
2645
+				srv_proto=*proto;
2646
+		}else{
2647
+			srv_proto=PROTO_UDP;
2648
+		}
2649
+		h->port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
2387 2650
 														don't find another */
2651
+		h->proto=srv_proto; /* store initial protocol */
2388 2652
 		if (port){
2389 2653
 			if (*port==0){
2390 2654
 				/* try SRV if initial call & no port specified
... ...
@@ -2409,12 +2673,15 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2409 2673
 #endif
2410 2674
 						*ip=*tmp_ip;
2411 2675
 						*port=h->port;
2676
+						/* proto already set */
2412 2677
 						return 0;
2413 2678
 					}
2414 2679
 					
2415
-					switch(proto){
2680
+					switch(srv_proto){
2416 2681
 						case PROTO_NONE: /* no proto specified, use udp */
2417
-							goto skip_srv;
2682
+							if (proto)
2683
+								*proto=PROTO_UDP;
2684
+							/* no break */
2418 2685
 						case PROTO_UDP:
2419 2686
 							memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
2420 2687
 							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 2702
 							break;
2436 2703
 						default:
2437 2704
 							LOG(L_CRIT, "BUG: sip_resolvehost: "
2438
-									"unknown proto %d\n", proto);
2705
+									"unknown proto %d\n", (int)srv_proto);
2439 2706
 							return -E_DNS_CRITICAL;
2440 2707
 					}
2441 2708
 					srv_name.s=tmp;
2442 2709
 					srv_name.len=len;
2443
-					
2444 2710
 					if ((ret=dns_srv_resolve_ip(h, &srv_name, ip,
2445 2711
 															port, flags))>=0)
2446 2712
 					{
... ...
@@ -2448,11 +2714,13 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2448 2714
 						DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2449 2715
 							name->len, name->s, h->srv_no, h->ip_no, ret);
2450 2716
 #endif
2717
+						/* proto already set */
2451 2718
 						return ret;
2452 2719
 					}
2453 2720
 				}
2454 2721
 			}else{ /* if (*port==0) */
2455 2722
 				h->port=*port; /* store initial port */
2723
+				/* proto already set */
2456 2724
 			}
2457 2725
 		} /* if (port) */
2458 2726
 	}else if (h->srv){
... ...
@@ -2460,11 +2728,13 @@ int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2460 2728
 			srv_name.len=h->srv->name_len;
2461 2729
 			/* continue srv resolving */
2462 2730
 			ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags);
2731
+			if (proto)
2732
+				*proto=h->proto;
2463 2733
 			DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n", 
2464 2734
 					name->len, name->s, h->srv_no, h->ip_no, ret);
2465 2735
 			return ret;
2466 2736
 	}
2467
-skip_srv:
2737
+/*skip_srv:*/
2468 2738
 	if (name->len >= MAX_DNS_NAME) {
2469 2739
 		LOG(L_ERR, "dns_sip_resolve: domain name too long\n");
2470 2740
 		return -E_DNS_NAME_TOO_LONG;
... ...
@@ -2472,13 +2742,133 @@ skip_srv:
2472 2742
 	ret=dns_ip_resolve(&h->a, &h->ip_no, name, ip, flags);
2473 2743
 	if (port)
2474 2744
 		*port=h->port;
2745
+	if (proto)
2746
+		*proto=h->proto;
2747
+#ifdef DNS_CACHE_DEBUG
2475 2748
 	DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n", 
2476 2749
 			name->len, name->s, h->srv_no, h->ip_no, ret);
2750
+#endif
2477 2751
 	return ret;
2478 2752
 }
2479 2753
 
2480 2754
 
2481 2755
 
2756
+#ifdef USE_NAPTR
2757
+/* resolves a host name trying:
2758
+ * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
2759
+ *    *port==0 and *proto=0 and if flags allow NAPTR lookups
2760
+ * -SRV lookup if  port!=0 and *port==0
2761
+ * - normal A/AAAA lookup if *port!=0, or port==0
2762
+ * when performing SRV lookup (*port==0) it will use proto to look for
2763
+ * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2764
+ * h must be initialized prior to  calling this function and can be used to 
2765
+ * get the subsequent ips
2766
+ * returns:  <0 on error
2767
+ *            0 on success and it fills *ip, *port, dns_sip_resolve_h
2768
+ * WARNING: when finished, dns_sip_resolve_put(h) must be called!
2769
+ */
2770
+int dns_naptr_sip_resolve(struct dns_srv_handle* h,  str* name,
2771
+						struct ip_addr* ip, unsigned short* port, char* proto,
2772
+						int flags)
2773
+{
2774
+	struct hostent* he;
2775
+	struct ip_addr* tmp_ip;
2776
+	naptr_bmp_t tried_bmp;
2777
+	struct dns_hash_entry* e;
2778
+	char n_proto;
2779
+	str srv_name;
2780
+	int ret;
2781
+	
2782
+	ret=-E_DNS_NO_NAPTR;
2783
+	if (dns_hash==0){ /* not init => use normal, non-cached version */
2784
+		LOG(L_WARN, "WARNING: dns_sip_resolve: called before dns cache"
2785
+					" initialization\n");
2786
+		h->srv=h->a=0;
2787
+		he=_sip_resolvehost(name, port, proto);
2788
+		if (he){
2789
+			hostent2ip_addr(ip, he, 0);
2790
+			return 0;
2791
+		}
2792
+		return -E_DNS_NO_NAPTR;
2793
+	}
2794
+	if (((h->srv==0) && (h->a==0)) && /* first call */
2795
+			 proto && port && (*proto==0) && (*port==0)){
2796
+		*proto=PROTO_UDP; /* just in case we don't find another */
2797
+		
2798
+		/* check if it's an ip address */
2799
+		if ( ((tmp_ip=str2ip(name))!=0)
2800
+#ifdef	USE_IPV6
2801
+			  || ((tmp_ip=str2ip6(name))!=0)
2802
+#endif
2803
+			){
2804
+			/* we are lucky, this is an ip address */
2805
+#ifdef	USE_IPV6
2806
+			if (((flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
2807
+				((flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
2808
+				return -E_DNS_AF_MISMATCH;
2809
+			}
2810
+#endif
2811
+			*ip=*tmp_ip;
2812
+			h->port=SIP_PORT;
2813
+			h->proto=*proto;
2814
+			*port=h->port;
2815
+			return 0;
2816
+		}
2817
+		/* do naptr lookup */
2818
+		if ((e=dns_get_entry(name, T_NAPTR))==0)
2819
+			goto naptr_not_found;
2820
+		naptr_iterate_init(&tried_bmp);
2821
+		while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
2822
+												&srv_name, &n_proto)){
2823
+			dns_srv_handle_init(h); /* make sure h does not contain garbage
2824
+									from previous dns_srv_sip_resolve calls */
2825
+			if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0){
2826
+#ifdef DNS_CACHE_DEBUG
2827
+				DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n", 
2828
+								name->len, name->s, h->srv_no, h->ip_no, ret);
2829
+#endif
2830
+				dns_hash_put(e);
2831
+				*proto=n_proto;
2832
+				h->proto=*proto;
2833
+				return ret;
2834
+			}
2835
+		}
2836
+		/* no acceptable naptr record found, fallback to srv */
2837
+		dns_hash_put(e);
2838
+		dns_srv_handle_init(h); /* make sure h does not contain garbage
2839
+								from previous dns_srv_sip_resolve calls */
2840
+	}
2841
+naptr_not_found:
2842
+	return dns_srv_sip_resolve(h, name, ip, port, proto, flags);
2843
+}
2844
+#endif /* USE_NAPTR */
2845
+
2846
+
2847
+
2848
+/* resolves a host name trying:
2849
+ * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
2850
+ *    *port==0 and *proto=0 and if flags allow NAPTR lookups
2851
+ * -SRV lookup if  port!=0 and *port==0
2852
+ * - normal A/AAAA lookup if *port!=0, or port==0
2853
+ * when performing SRV lookup (*port==0) it will use proto to look for
2854
+ * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
2855
+ * h must be initialized prior to  calling this function and can be used to 
2856
+ * get the subsequent ips
2857
+ * returns:  <0 on error
2858
+ *            0 on success and it fills *ip, *port, dns_sip_resolve_h
2859
+ * WARNING: when finished, dns_sip_resolve_put(h) must be called!
2860
+ */
2861
+int dns_sip_resolve(struct dns_srv_handle* h,  str* name,
2862
+						struct ip_addr* ip, unsigned short* port, char* proto,
2863
+						int flags)
2864
+{
2865
+#ifdef USE_NAPTR
2866
+	if (flags&DNS_TRY_NAPTR)
2867
+		return dns_naptr_sip_resolve(h, name, ip, port, proto, flags);
2868
+#endif
2869
+	return dns_srv_sip_resolve(h, name, ip, port, proto, flags);
2870
+}
2871
+
2482 2872
 /* performs an a lookup and fills ip with the first good ip address
2483 2873
  * returns 0 on success, <0 on error (see the error codes)
2484 2874
  */
... ...
@@ -2596,12 +2986,12 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
2596 2986
 			clist_foreach(&dns_hash[h], e, next){
2597 2987
 				for (i=0, rr=e->rr_lst; rr; i++, rr=rr->next){
2598 2988
 					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:
2989
+								e->name, (int)e->type, i, (int)e->total_size,
2990
+								(int)e->refcnt.val,
2991
+								(int)(s_ticks_t)(e->expire-now)<0?-1:
2602 2992
 									TICKS_TO_S(e->expire-now),
2603
-								TICKS_TO_S(now-e->last_used),
2604
-								e->err_flags);
2993
+								(int)TICKS_TO_S(now-e->last_used),
2994
+								(int)e->err_flags);
2605 2995
 					switch(e->type){
2606 2996
 						case T_A:
2607 2997
 						case T_AAAA:
... ...
@@ -2616,8 +3006,8 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
2616 3006
 									((struct srv_rdata*)(rr->rdata))->name);
2617 3007
 							break;
2618 3008
 						case T_NAPTR:
2619
-							rpc->add(ctx, "ss", "naptr", 
2620
-									((struct naptr_rdata*)(rr->rdata))->flags);
3009
+							rpc->add(ctx, "ss", "naptr ",
3010
+								((struct naptr_rdata*)(rr->rdata))->flags);
2621 3011
 							break;
2622 3012
 						case T_CNAME:
2623 3013
 							rpc->add(ctx, "ss", "cname", 
... ...
@@ -2627,9 +3017,9 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
2627 3017
 							rpc->add(ctx, "ss", "unknown", "?");
2628 3018
 					}
2629 3019
 					rpc->add(ctx, "dd",
2630
-								(s_ticks_t)(rr->expire-now)<0?-1:
3020
+								(int)(s_ticks_t)(rr->expire-now)<0?-1:
2631 3021
 									TICKS_TO_S(rr->expire-now),
2632
-							rr->err_flags);
3022
+								(int)rr->err_flags);
2633 3023
 				}
2634 3024
 			}
2635 3025
 		}
... ...
@@ -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 37
 #define __dns_cache_h
37 38
 
38 39
 #include "str.h"
40
+#include "config.h" /* MAX_BRANCHES */
39 41
 #include "timer.h"
40 42
 #include "ip_addr.h"
41 43
 #include "atomic_ops.h"
... ...
@@ -73,13 +75,12 @@ enum dns_errors{
73 75
 					E_DNS_AF_MISMATCH /* ipv4 or ipv6 only requested, but 
74 76
 										 name contains an ip addr. of the
75 77
 										 opossite type */ ,
78
+					E_DNS_NO_NAPTR /* unresolvable naptr record */,
76 79
 					E_DNS_CRITICAL /* critical error, marks the end
77 80
 									  of the error table (always last) */
78 81
 };
79 82
 
80 83
 
81
-extern int dns_flags; /* default flags used for dns lookup */
82
-extern int dns_srv_lb; /* default SRV LB support value */
83 84
 
84 85
 /* return a short string, printable error description (err <=0) */
85 86
 const char* dns_strerror(int err);
... ...
@@ -92,7 +93,8 @@ const char* dns_strerror(int err);
92 93
 #define DNS_IPV4_ONLY	1
93 94
 #define DNS_IPV6_ONLY	2
94 95
 #define DNS_IPV6_FIRST	4
95
-#define DNS_SRV_RR_LB		8  /* SRV RR weight based load balancing */
96
+#define DNS_SRV_RR_LB	8  /* SRV RR weight based load balancing */
97
+#define DNS_TRY_NAPTR	16 /* enable naptr lookup */
96 98
 
97 99
 
98 100
 /* ip blacklist error flags */
... ...
@@ -141,7 +143,14 @@ struct dns_hash_entry{
141 143
 };
142 144
 
143 145
 
146
+#if MAX_BRANCHES < 16
147
+/* forking is limited by tm to 12 by default */
148
+typedef unsigned short srv_flags_t;
149
+#elif MAX_BRANCHES < 32
144 150
 typedef unsigned int srv_flags_t;
151
+#else
152
+typedef unsigned long long srv_flags_t;
153
+#endif
145 154
 
146 155
 struct dns_srv_handle{
147 156
 	struct dns_hash_entry* srv; /* srv entry */
... ...
@@ -151,7 +160,8 @@ struct dns_srv_handle{
151 160
 #endif
152 161
 	unsigned short port; /* current port */
153 162
 	unsigned char srv_no; /* current record no. in the srv entry */
154
-	unsigned char ip_no;   /* current record no. in the a/aaaa entry */
163
+	unsigned char ip_no;  /* current record no. in the a/aaaa entry */
164
+	unsigned char proto;  /* protocol number */
155 165
 };
156 166
 
157 167
 
... ...
@@ -241,6 +251,8 @@ inline static void dns_srv_handle_init(struct dns_srv_handle* h)
241 251
 {
242 252
 	h->srv=h->a=0;
243 253
 	h->srv_no=h->ip_no=0;
254
+	h->port=0;
255
+	h->proto=0;
244 256
 #ifdef DNS_SRV_LB
245 257
 	h->srv_tried_rrs=0;
246 258
 #endif
... ...
@@ -280,13 +292,13 @@ struct hostent* dns_get_he(str* name, int flags);
280 292
  *  dns_srv_handle_put(h) must be called when h is no longer needed
281 293
  */
282 294
 int dns_sip_resolve(struct dns_srv_handle* h,  str* name, struct ip_addr* ip,
283
-					unsigned short* port, int proto, int flags);
295
+					unsigned short* port, char* proto, int flags);
284 296
 
285 297
 /* same as above, but fills su intead of changing port and filling an ip */ 
286 298
 inline static int dns_sip_resolve2su(struct dns_srv_handle* h,
287 299
 									 union sockaddr_union* su,
288 300
 									 str* name, unsigned short port,
289
-									 int proto, int flags)
301
+									 char* proto, int flags)
290 302
 {
291 303
 	struct ip_addr ip;
292 304
 	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 19
   destination host doesn't send any reply to a forwarded invite within the
19 20
   sip timeout interval (whose value can be configured using the tm fr_timer
20 21
    parameter).
22
+ When SRV based load balancing is enabled ser can even do DNS based load 
23
+ balancing (see RFC2782 and the dns_srv_lb option below).
21 24
 
22 25
 
23 26
 DNS Cache and Failover Drawbacks
... ...
@@ -42,6 +45,19 @@ DNS Cache and Failover Drawbacks
42 45
      Workaround: compile without dns failover support (-DUSE_DNS_FAILOVER).
43 46
   Turning it off from the config file is not enough in this case (the extra
44 47
    memory will still be used).
48
+ 
49
+ On the other hand using the dns cache saves lots of DNS queries and makes
50
+ DNS based failover and DNS based load balancing possible. If the destination
51
+ blacklist is enabled, ser can do failover even if forwarding in stateless 
52
+ mode.
53
+ In the ideal case with dns cache enabled ser will do only one query for
54
+ a NAPTR (if enabled) or SRV lookup and then it will use the results for the
55
+ record's TTL (for example if all the resulting records have 1 minute TTL,
56
+  ser won't make another query for this domain for 1 minute). Even negative
57
+ answers will be cached.
58
+ Without the dns cache, each NAPTR or SRV lookup will result in at least 2 
59
+ queries. These queries will happen every time, for each message (even if 
60
+ all of them go to the same domain).
45 61
 
46 62
 
47 63
 DNS Resolver Options
... ...
@@ -59,6 +75,41 @@ DNS Resolver Options
59 75
       If off only ipv4 (A) lookups will be used.
60 76
       Default: on if ser is compiled with ipv6 support.
61 77
 
78
+   dns_try_naptr = on | off - if on ser will first try a NAPTR lookup for
79
+      destinations that don't have the protocol or port specified and 
80
+      are not simple ip addresses (as described in RFC 3263). This will 
81
+      introduce a slight performance penalty and will probably cause extra
82
+      DNS lookups. For example a lookup for a non-existing domain will
83
+      produce one extra query: NAPTR(domain), SRV(_sip._udp.domain) 
84
+      and A/AAAA(domain).
85
+      If the result of a query contains several NAPTR records, ser will select
86
+      among them according to the RFC2915 and ser preference towards a
87
+      specific protocol (see dns_udp_pref, dns_tcp_pref and dns_tls_pref 
88
+      below). For an RFC3263 compliant configuration (choose the remote side
89
+      preferred protocol if supported), set dns_udp_pref, dns_tcp_pref and
90
+      dns_tls_pref to the same value (>=0), e.g. 0.
91
+      Default: off
92
+
93
+   dns_udp_pref = number - udp protocol preference when doing NAPTR lookups.
94
+      This option works together with dns_tcp_pref and dns_tls_pref. If all
95
+      this options have the same positive value and more NAPTR records are
96
+      available, ser will select the NAPTR record preferred by the remote side
97
+      (according to RFC2915). If the values are positive but different, ser
98
+      will select the NAPTR record whose protocol it prefers the most
99
+      (the protocol with the highest dns_<proto>_pref number). If there are 
100
+       several NAPTR records with the same preferred protocol, ser will select        among them based on their order and preference (see RFC2915).
101
+      To completely disable selecting a specific protocol, use  a negative
102
+       number. For example dns_tcp_pref=-1 will completely disable selection
103
+       of tcp NAPTR records, even if this will result in the NAPTR lookup
104
+       failure.
105
+       Default: dns_udp_pref=3, dns_tcp_pref=2 and dns_tls_pref=1
106
+       (prefer udp, but if no udp NAPTR record found or no SRV-resolvable 
107
+        udp NAPTR record found use tcp records and if this fails too use tls)
108
+
109
+   dns_tcp_pref = number  (see dns_udp_pref above)
110
+
111
+   dns_tls_pref = number (see dns_udp_pref above)
112
+
62 113
    dns_retr_time = time - time in s before retrying a dns request.
63 114
       Default: system specific, depends also on the/etc/resolv.conf content
64 115
       (usually 5 s).
... ...
@@ -98,6 +149,19 @@ DNS Resolver Options
98 149
  dns server (to avoid unnecessary extra lookups).
99 150
 
100 151
 
152
+DNS Resolver Compile Options
153
+
154
+   USE_NAPTR - if defined the naptr lookup support will be compiled in.
155
+      NAPTR support still has to be enabled from ser's config file (it's
156
+      off by default).
157
+
158
+   RESOLVE_DBG - if defined, the resolver will be very verbose: it will log
159
+      a lot of debugging information at L_DBG level.
160
+
161
+   NAPTR_DBG - if defined the NAPTR related resolver functions will be very
162
+       verbose.
163
+
164
+
101 165
 DNS Cache and Failover Config Variables
102 166
 
103 167
    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 182
    Depends on use_dns_cache being on. If tm is used along with dns failover is
119 183
    recommended to also turn on dst_blacklist.
120 184
 
185
+   dns_srv_lb = on | off or
186
+   dns_srv_loadbalancing = on | off - if on instead of doing simple dns 
187
+        failover (like above), ser will load balance requests to different srv
188
+        records of the same priority based on the srv records weights (like 
189
+        described in RFC2782). For a destination which has different priorities
190
+        for all its srv records, this option will be equivalent with simple
191
+        dns failover.
192
+        Note: this option requires having dns failover enabled (see 
193
+        use_dns_failover above).
194
+        Default: off.
195
+
196
+   dns_try_ipv6 = on | off - shared with the resolver (see resolver 
197
+        description).
198
+
199
+   dns_try_naptr = on | off - shared with the resolver (see resolver 
200
+        description).
201
+
202
+   dns_udp_pref =  number - shared with the resolver (see resolver 
203
+        description).
204
+
205
+   dns_tcp_pref =  number - shared with the resolver (see resolver 
206
+        description).
207
+
208
+   dns_tls_pref =  number - shared with the resolver (see resolver 
209
+        description).
210
+
121 211
    dns_cache_flags = dns cache specific resolver flags, used for overriding
122 212
      the default behaviour (low level).
123 213
       Possible values:
... ...
@@ -165,9 +255,38 @@ DNS Cache Compile Options
165 255
    USE_DNS_FAILOVER - if defined the dns failover support will be compiled in.
166 256
       (default). Compiling the dns failover support has a few disadvantages,
167 257
       see the "Drawbacks" section.
258
+
259
+   DNS_SRV_LB  - if defined (default) support for load balancing using 
260
+       srv records weights (as described in RFC2782) will be compiled in.
261
+       Note however that it still must be enabled from the ser config, it's
262
+       disabled by default (see the dns_srv_lb config option).
263
+
264
+   USE_NAPTR  - (shared with the resolver)  if defined NAPTR support will
265
+       be compiled in (default). Note that even if compiled, NAPTR support
266
+       must be enabled also from the ser config (see the dns_try_naptr option).
267
+
268
+   NAPTR_CACHE_ALL_ARS - if defined all the additional records in a NAPTR
269
+       answer will be cached. Normally ser would cache only "related" records
270
+       (records that are directly referred), but for answers with lots of 
271
+        A/AAAA records it might happen that not all of the SRV records will fit
272
+       in the AR section. In this case, without this compile option ser will 
273
+       not cache the un-referred A/AAAA records. BY default this option is
274
+       disabled.
275
+
276
+   CACHE_RELEVANT_RECS_ONLY - if defined (default), records in the AR section
277
+       of an answer will be cached only if they are "related" to the query.
278
+       For example if the query is for a SRV record, A & AAAA records in the
279
+       AR section will be cached only if there are SRV records pointing to 
280
+       them. This avoids adding possible garbage to the cache.
281
+       If this option is not defined (experimental), everything in the AR
282
+       section will be added to the cache.
283
+
284
+   DNS_CACHE_DEBUG - if defined the dns cache will be very verbose (it will
285
+       log lots of messages at the L_DBG levell).
168 286
  
169 287
  Note: To remove a compile options,  edit ser's Makefile.defs and remove it 
170 288
    form DEFS list. To add a compile options add it to the make command line,
171 289
      e.g.: make proper; make all extra_defs=-DUSE_DNS_FAILOVER
172 290
    or for a permanent solution, edit Makefile.defs and add it to DEFS 
173
-   (don't foget to prefix it with -D).
291
+   (don't foget to prefix it with -D). Some options require editing 
292
+   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 527
 	    sip_resolvehost now accepts str -janakj
527 528
 	*/
528 529
 	DBG("update_sock_struct_from_via: trying SRV lookup\n");
529
-	he=sip_resolvehost(name, &port, via->proto);
530
+	proto=via->proto;
531
+	he=sip_resolvehost(name, &port, &proto);
530 532
 	
531 533
 	if (he==0){
532 534
 		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 215
 	memset(p,0,sizeof(struct proxy_l));
215 216
 	p->name=*name;
216 217
 	p->port=port;
217
-	p->proto=proto;
218 218
 
219 219
 	DBG("DEBUG: mk_proxy: doing DNS lookup...\n");
220
-	he=sip_resolvehost(name, &(p->port), proto);
220
+	proto=protocol;
221
+	he=sip_resolvehost(name, &(p->port), &proto);
221 222
 	if (he==0){
222 223
 		ser_error=E_BAD_ADDRESS;
223 224
 		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 230
 		pkg_free(p);
230 231
 		goto error;
231 232
 	}
233
+	p->proto=proto;
232 234
 	p->ok=1;
233 235
 	return p;
234 236
 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 46
 #include <string.h>
46 47
 
47 48
 #include "resolve.h"
49
+#include "compiler_opt.h"
48 50
 #include "dprint.h"
49 51
 #include "mem/mem.h"
50 52
 #include "ip_addr.h"
51 53
 #include "error.h"
54
+#include "globals.h" /* tcp_disable, tls_disable a.s.o */
52 55
 
53 56
 #ifdef USE_DNS_CACHE
54 57
 #include "dns_cache.h"
... ...
@@ -65,6 +68,17 @@ int dns_try_ipv6=1; /* default on */
65 68
 #else
66 69
 int dns_try_ipv6=0; /* off, if no ipv6 support */
67 70
 #endif
71
+int dns_try_naptr=0;  /* off by default */
72
+
73
+int dns_udp_pref=3;  /* udp transport preference (for naptr) */
74
+int dns_tcp_pref=2;  /* tcp transport preference (for naptr) */
75
+int dns_tls_pref=1;  /* tls transport preference (for naptr) */
76
+
77
+#ifdef USE_NAPTR
78
+#define PROTO_LAST  PROTO_SCTP
79
+static int naptr_proto_pref[PROTO_LAST];
80
+#endif
81
+
68 82
 /* declared in globals.h */
69 83
 int dns_retr_time=-1;
70 84
 int dns_retr_no=-1;
... ...
@@ -72,6 +86,23 @@ int dns_servers_no=-1;
72 86
 int dns_search_list=-1;
73 87
 
74 88
 
89
+#ifdef USE_NAPTR
90
+void init_naptr_proto_prefs()
91
+{
92
+	if ((PROTO_UDP >= PROTO_LAST) || (PROTO_TCP >= PROTO_LAST) ||
93
+		(PROTO_TLS >= PROTO_LAST)){
94
+		BUG("init_naptr_proto_prefs: array too small \n");
95
+		return;
96
+	}
97
+	naptr_proto_pref[PROTO_UDP]=dns_udp_pref;
98
+	naptr_proto_pref[PROTO_TCP]=dns_tcp_pref;
99
+	naptr_proto_pref[PROTO_TLS]=dns_tls_pref;
100
+}
101
+
102
+#endif /* USE_NAPTR */
103
+
104
+
105
+
75 106
 /* init. the resolver
76 107
  * params: retr_time  - time before retransmitting (must be >0)
77 108
  *         retr_no    - retransmissions number
... ...
@@ -102,6 +133,9 @@ int resolv_init()
102 133
 #warning "no resolv timeout support"
103 134
 	LOG(L_WARN, "WARNING: resolv_init: no resolv options support - resolv"
104 135
 			" options will be ignored\n");
136
+#endif
137
+#ifdef USE_NAPTR
138
+	init_naptr_proto_prefs();
105 139
 #endif
106 140
 	return 0;
107 141
 }
... ...
@@ -266,8 +300,8 @@ struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
266 300
 		LOG(L_ERR, "ERROR: dns_naptr_parser: out of memory\n");
267 301
 		goto error;
268 302
 	}
269
-	naptr->order=ntohs(naptr->order);
270
-	naptr->pref=ntohs(naptr->pref);
303
+	naptr->order=ntohs(order);
304
+	naptr->pref=ntohs(pref);
271 305
 	
272 306
 	naptr->flags=&naptr->str_table[0];
273 307
 	naptr->flags_len=flags_len;
... ...
@@ -555,7 +589,9 @@ again:
555 589
 	if (flags & RES_AR){
556 590
 		flags&=~RES_AR;
557 591
 		answers_no=ntohs((unsigned short)buff.hdr.nscount);
592
+#ifdef RESOLVE_DBG
558 593
 		DBG("get_record: skipping %d NS (p=%p, end=%p)\n", answers_no, p, end);
594
+#endif
559 595
 		for (r=0; (r<answers_no) && (p<end); r++){
560 596
 			/* skip over the ns records */
561 597
 			if ((p=dns_skipname(p, end))==0) {
... ...
@@ -568,7 +604,9 @@ again:
568 604
 			p+=2+2+4+2+ntohs(rdlength);
569 605
 		}
570 606
 		answers_no=ntohs((unsigned short)buff.hdr.arcount);
607
+#ifdef RESOLVE_DBG
571 608
 		DBG("get_record: parsing %d ARs (p=%p, end=%p)\n", answers_no, p, end);
609
+#endif
572 610
 		goto again; /* add also the additional records */
573 611
 	}
574 612
 			
... ...
@@ -591,47 +629,242 @@ not_found:
591 629
 	return 0;
592 630
 }
593 631
 
632
+#ifdef USE_NAPTR
594 633
 
634
+/* service matching constants, lowercase */
635
+#define SIP_SCH		0x2b706973
636
+#define SIPS_SCH	0x73706973
637
+#define SIP_D2U		0x00753264
638
+#define SIP_D2T		0x00743264
639
+#define SIP_D2S		0x00733264
640
+#define SIPS_D2T	0x7432642b
595 641
 
596