[sr-dev] Patch: Respect Order field in NAPTR, as required by RFC 2915
Øyvind Kolbu
oyvind.kolbu at usit.uio.no
Mon Nov 11 14:48:46 CET 2013
On 2013-10-29 at 09:34, Daniel-Constantin Mierla wrote:
> On 10/18/13 3:14 PM, Øyvind Kolbu wrote:
> > Made a core option, dns_naptr_ignore_rfc, default off, to preserve today's
> > behavior.
> did I get it wrong or the dns_naptr_ignore_rfc has to be 1 (on) to
> preserve current behaviour? You said 'off' (expect 0) which collides
> with the 'ignore' in the name of the parameter.
Hi and sorry for the late reply. Been offline on vacation.
Yes, the value has to be 1 to actually ignore the rfc. The code
was correct, but the default value not. Fixed in the attached patch.
> > One implementation detail is that one currently can disable a protocol
> > by setting the priority to -1. In my patch that is currently ignored.
> > Can add a check for that in init_naptr_proto_prefs() before setting
> > a protocol's preference to 1.
>
> Can you add the check for ignoring a protocol? Sometime it might be
> needed. Resend the patch and I will push it to repo.
Fixed in the new patch.
--
Øyvind Kolbu
-------------- next part --------------
diff --git a/cfg.lex b/cfg.lex
index 5a7ce8a..03fde61 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -359,6 +359,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
@@ -747,6 +748,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 0c4fb5d..c472e54 100644
--- a/cfg.y
+++ b/cfg.y
@@ -418,6 +418,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
@@ -896,6 +897,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 55a5638..6bb6399 100644
--- a/cfg_core.c
+++ b/cfg_core.c
@@ -92,6 +92,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 */
@@ -220,13 +221,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"},
@@ -243,6 +244,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 8d86c02..4a690d3 100644
--- a/dns_cache.c
+++ b/dns_cache.c
@@ -3341,12 +3341,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 bced952..77102bb 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
@@ -1097,19 +1131,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:
@@ -1136,7 +1177,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);
}
@@ -1470,7 +1511,7 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto_t *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;
@@ -1489,7 +1530,7 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto_t *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);
}
}
@@ -1581,6 +1622,7 @@ struct hostent* no_naptr_srv_sip_resolvehost(str* name, unsigned short* port, ch
he=srv_sip_resolvehost(&srv_name, 0, port, proto, 1, 0);
#endif
if (he!=0) {
+ *proto = srv_proto_list[i].proto;
return he;
}
}
diff --git a/resolve.h b/resolve.h
index 1d67e3d..c7e1e0f 100644
--- a/resolve.h
+++ b/resolve.h
@@ -485,7 +485,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_t {
char proto;
More information about the sr-dev
mailing list