[sr-dev] git:master: core: respect order field in NAPTR, as required by RFC 2915

Daniel-Constantin Mierla miconda at gmail.com
Tue Nov 12 15:49:43 CET 2013


Module: sip-router
Branch: master
Commit: a9fc979c839b44411e3c34076591c64c16d2fe87
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a9fc979c839b44411e3c34076591c64c16d2fe87

Author: Øyvind Kolbu <oyvind.kolbu at usit.uio.no>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Tue Nov 12 15:47:30 2013 +0100

core: respect order field in NAPTR, as required by RFC 2915

- the beaviour is controlled by core parameter dns_naptr_ignore_rfc
- default is 1, preserving current behaviouf to ignore rfc requirements
  (for backward compatibility)

---

 cfg.lex     |    3 ++
 cfg.y       |    3 ++
 cfg_core.c  |   11 +++++---
 cfg_core.h  |    1 +
 dns_cache.c |    3 +-
 resolve.c   |   71 ++++++++++++++++++++++++++++++++++++++++++++++------------
 resolve.h   |    2 +-
 7 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/cfg.lex b/cfg.lex
index 127fce5..8e60c1e 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -360,6 +360,7 @@ DNS_RETR_NO		dns_retr_no
 DNS_SERVERS_NO	dns_servers_no
 DNS_USE_SEARCH	dns_use_search_list
 DNS_SEARCH_FMATCH	dns_search_full_match
+DNS_NAPTR_IGNORE_RFC	dns_naptr_ignore_rfc
 /* dns cache */
 DNS_CACHE_INIT	dns_cache_init
 DNS_USE_CACHE	use_dns_cache
@@ -724,6 +725,8 @@ IMPORTFILE      "import_file"
 								return DNS_USE_SEARCH; }
 <INITIAL>{DNS_SEARCH_FMATCH}	{ count(); yylval.strval=yytext;
 								return DNS_SEARCH_FMATCH; }
+<INITIAL>{DNS_NAPTR_IGNORE_RFC}	{ count(); yylval.strval=yytext;
+								return DNS_NAPTR_IGNORE_RFC; }
 <INITIAL>{DNS_CACHE_INIT}	{ count(); yylval.strval=yytext;
 								return DNS_CACHE_INIT; }
 <INITIAL>{DNS_USE_CACHE}	{ count(); yylval.strval=yytext;
diff --git a/cfg.y b/cfg.y
index 2533f72..195593b 100644
--- a/cfg.y
+++ b/cfg.y
@@ -409,6 +409,7 @@ extern char *finame;
 %token DNS_SERVERS_NO
 %token DNS_USE_SEARCH
 %token DNS_SEARCH_FMATCH
+%token DNS_NAPTR_IGNORE_RFC
 %token DNS_CACHE_INIT
 %token DNS_USE_CACHE
 %token DNS_USE_FAILOVER
@@ -865,6 +866,8 @@ assign_stm:
 	| DNS_USE_SEARCH error { yyerror("boolean value expected"); }
 	| DNS_SEARCH_FMATCH EQUAL NUMBER   { default_core_cfg.dns_search_fmatch=$3; }
 	| DNS_SEARCH_FMATCH error { yyerror("boolean value expected"); }
+	| DNS_NAPTR_IGNORE_RFC EQUAL NUMBER   { default_core_cfg.dns_naptr_ignore_rfc=$3; }
+	| DNS_NAPTR_IGNORE_RFC error { yyerror("boolean value expected"); }
 	| DNS_CACHE_INIT EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_init=$3); }
 	| DNS_CACHE_INIT error { yyerror("boolean value expected"); }
 	| DNS_USE_CACHE EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.use_dns_cache=$3); }
diff --git a/cfg_core.c b/cfg_core.c
index ac67b11..06edb86 100644
--- a/cfg_core.c
+++ b/cfg_core.c
@@ -88,6 +88,7 @@ struct cfg_group_core default_core_cfg = {
 	1,  /*!< dns_search_list */
 	1,  /*!< dns_search_fmatch */
 	0,  /*!< dns_reinit */
+	1,  /*!< dns_naptr_ignore_rfc */
 	/* DNS cache */
 #ifdef USE_DNS_CACHE
 	1,  /*!< use_dns_cache -- on by default */
@@ -216,13 +217,13 @@ cfg_def_t core_cfg_def[] = {
 	{"dns_try_naptr",	CFG_VAR_INT,	0, 1, 0, 0,
 #endif
 		"enable/disable NAPTR DNS lookups"},
-	{"dns_udp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
+	{"dns_udp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
 		"udp protocol preference when doing NAPTR lookups"},
-	{"dns_tcp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
+	{"dns_tcp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
 		"tcp protocol preference when doing NAPTR lookups"},
-	{"dns_tls_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
+	{"dns_tls_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
 		"tls protocol preference when doing NAPTR lookups"},
-	{"dns_sctp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
+	{"dns_sctp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
 		"sctp protocol preference when doing NAPTR lookups"},
 	{"dns_retr_time",	CFG_VAR_INT,	0, 0, 0, resolv_reinit,
 		"time in s before retrying a dns request"},
@@ -239,6 +240,8 @@ cfg_def_t core_cfg_def[] = {
 	{"dns_reinit",		CFG_VAR_INT|CFG_INPUT_INT,	1, 1, dns_reinit_fixup,
 		resolv_reinit,
 		"set to 1 in order to reinitialize the DNS resolver"},
+	{"dns_naptr_ignore_rfc",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
+		"ignore the Order field required by RFC 2915"},
 	/* DNS cache */
 #ifdef USE_DNS_CACHE
 	{"use_dns_cache",	CFG_VAR_INT,	0, 1, use_dns_cache_fixup, 0,
diff --git a/cfg_core.h b/cfg_core.h
index 4bfbfbb..3739acb 100644
--- a/cfg_core.h
+++ b/cfg_core.h
@@ -80,6 +80,7 @@ struct cfg_group_core {
 	int dns_search_list;
 	int dns_search_fmatch;
 	int dns_reinit;
+	int dns_naptr_ignore_rfc;
 	/* DNS cache */
 #ifdef USE_DNS_CACHE
 	int use_dns_cache;
diff --git a/dns_cache.c b/dns_cache.c
index d9737c8..f3bdda9 100644
--- a/dns_cache.c
+++ b/dns_cache.c
@@ -3291,12 +3291,11 @@ inline static int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
 						srv_name.len=strlen(tmp);
 						if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0)
 						{
-							*proto = srv_proto_list[i].proto;
+							h->proto = *proto = srv_proto_list[i].proto;
 #ifdef DNS_CACHE_DEBUG
 							DBG("dns_srv_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
 								name->len, name->s, h->srv_no, h->ip_no, ret);
 #endif
-							/* proto already set */
 							return ret;
 						}
 					}
diff --git a/resolve.c b/resolve.c
index 7450b6f..d0ef16c 100644
--- a/resolve.c
+++ b/resolve.c
@@ -92,23 +92,58 @@ counter_def_t dns_cnt_defs[] =  {
 #ifdef USE_NAPTR
 static int naptr_proto_pref[PROTO_LAST+1];
 #endif
+static int srv_proto_pref[PROTO_LAST+1];
 
 #ifdef USE_NAPTR
-void init_naptr_proto_prefs()
+static void init_naptr_proto_prefs()
 {
+	int ignore_rfc, udp, tcp, tls, sctp;
+
 	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
 		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
 		BUG("init_naptr_proto_prefs: array too small \n");
 		return;
 	}
-	naptr_proto_pref[PROTO_UDP]=cfg_get(core, core_cfg, dns_udp_pref);
-	naptr_proto_pref[PROTO_TCP]=cfg_get(core, core_cfg, dns_tcp_pref);
-	naptr_proto_pref[PROTO_TLS]=cfg_get(core, core_cfg, dns_tls_pref);
-	naptr_proto_pref[PROTO_SCTP]=cfg_get(core, core_cfg, dns_sctp_pref);
+
+	ignore_rfc = cfg_get(core, core_cfg, dns_naptr_ignore_rfc);
+	udp = cfg_get(core, core_cfg, dns_udp_pref);
+	tcp = cfg_get(core, core_cfg, dns_tcp_pref);
+	tls = cfg_get(core, core_cfg, dns_tls_pref);
+	sctp = cfg_get(core, core_cfg, dns_sctp_pref);
+
+	/* Old implementation ignored the Order field in the NAPTR RR and
+	 * thus violated a MUST in RFC 2915. Currently still the default. */
+	if (ignore_rfc) {
+		naptr_proto_pref[PROTO_UDP] = udp;
+		naptr_proto_pref[PROTO_TCP] = tcp;
+		naptr_proto_pref[PROTO_TLS] = tls;
+		naptr_proto_pref[PROTO_SCTP] = sctp;
+	} else {
+		/* If value is less than 0, proto is disabled, otherwise
+		 * ignored. */
+		naptr_proto_pref[PROTO_UDP] = udp < 0 ? udp : 1;
+		naptr_proto_pref[PROTO_TCP] = tcp < 0 ? tcp : 1;
+		naptr_proto_pref[PROTO_TLS] = tls < 0 ? tls : 1;
+		naptr_proto_pref[PROTO_SCTP] = sctp < 0 ? sctp : 1;
+	}
 }
 
 #endif /* USE_NAPTR */
 
+static void init_srv_proto_prefs()
+{
+	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
+		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
+		BUG("init_srv_proto_prefs: array too small \n");
+		return;
+	}
+
+	srv_proto_pref[PROTO_UDP] = cfg_get(core, core_cfg, dns_udp_pref);
+	srv_proto_pref[PROTO_TCP] = cfg_get(core, core_cfg, dns_tcp_pref);
+	srv_proto_pref[PROTO_TLS] = cfg_get(core, core_cfg, dns_tls_pref);
+	srv_proto_pref[PROTO_SCTP] = cfg_get(core, core_cfg, dns_sctp_pref);
+}
+
 #ifdef DNS_WATCHDOG_SUPPORT
 static on_resolv_reinit	on_resolv_reinit_cb = NULL;
 
@@ -178,9 +213,7 @@ int resolv_init(void)
 	int res = -1;
 	_resolv_init();
 
-#ifdef USE_NAPTR
-	init_naptr_proto_prefs();
-#endif
+	reinit_proto_prefs(NULL,NULL);
 	/* init counter API only at startup
 	 * This function must be called before DNS cache init method (if available)
 	 */
@@ -212,12 +245,13 @@ int dns_reinit_fixup(void *handle, str *gname, str *name, void **val)
 	return 0;
 }
 
-/* wrapper function to recalculate the naptr protocol preferences */
-void reinit_naptr_proto_prefs(str *gname, str *name)
+/* wrapper function to recalculate the naptr and srv protocol preferences */
+void reinit_proto_prefs(str *gname, str *name)
 {
 #ifdef USE_NAPTR
 	init_naptr_proto_prefs();
 #endif
+	init_srv_proto_prefs();
 }
 
 /* fixup function for dns_try_ipv6
@@ -1080,19 +1114,26 @@ char naptr_get_sip_proto(struct naptr_rdata* n)
 
 
 
-inline static int proto_pref_score(char proto)
+inline static int naptr_proto_pref_score(char proto)
 {
 	if ((proto>=PROTO_UDP) && (proto<= PROTO_LAST))
 		return naptr_proto_pref[(int)proto];
 	return 0;
 }
 
+inline static int srv_proto_pref_score(char proto)
+{
+	if ((proto>=PROTO_UDP) && (proto<= PROTO_LAST))
+		return srv_proto_pref[(int)proto];
+	return 0;
+}
+
 
 
 /* returns true if we support the protocol */
 int naptr_proto_supported(char proto)
 {
-	if (proto_pref_score(proto)<0)
+	if (naptr_proto_pref_score(proto)<0)
 		return 0;
 	switch(proto){
 		case PROTO_UDP:
@@ -1119,7 +1160,7 @@ int naptr_proto_supported(char proto)
 /* returns true if new_proto is preferred over old_proto */
 int naptr_proto_preferred(char new_proto, char old_proto)
 {
-	return proto_pref_score(new_proto)>proto_pref_score(old_proto);
+	return naptr_proto_pref_score(new_proto)>naptr_proto_pref_score(old_proto);
 }
 
 
@@ -1451,7 +1492,7 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list) {
 		list_len = 0;
 		/*get protocols and preference scores, and add availble protocol(s) and score(s) to the list*/
 		for (i=PROTO_UDP; i<PROTO_LAST;i++) {
-			tmp.proto_pref = proto_pref_score(i);
+			tmp.proto_pref = srv_proto_pref_score(i);
 			/* if -1 so disabled continue with next protocol*/
 			if (naptr_proto_supported(i) == 0) {
 				continue;
@@ -1470,7 +1511,7 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list) {
 		}
 		if (default_order){
 			for (i=0; i<list_len;i++) {
-				list[i].proto_pref=proto_pref_score(i);
+				list[i].proto_pref=srv_proto_pref_score(i);
 			}
 		}
 
diff --git a/resolve.h b/resolve.h
index b3e6eba..2d67da7 100644
--- a/resolve.h
+++ b/resolve.h
@@ -455,7 +455,7 @@ int resolv_init(void);
 void resolv_reinit(str *gname, str *name);
 int dns_reinit_fixup(void *handle, str *gname, str *name, void **val);
 int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val);
-void reinit_naptr_proto_prefs(str *gname, str *name);
+void reinit_proto_prefs(str *gname, str *name);
 
 struct dns_srv_proto {
 	char proto;




More information about the sr-dev mailing list