Module: sip-router
Branch: master
Commit: a9fc979c839b44411e3c34076591c64c16d2fe87
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a9fc979…
Author: Øyvind Kolbu <oyvind.kolbu(a)usit.uio.no>
Committer: Daniel-Constantin Mierla <miconda(a)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;