Browse code

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)

√ėyvind Kolbu authored on 12/11/2013 14:47:30
Showing 7 changed files
... ...
@@ -360,6 +360,7 @@ DNS_RETR_NO		dns_retr_no
360 360
 DNS_SERVERS_NO	dns_servers_no
361 361
 DNS_USE_SEARCH	dns_use_search_list
362 362
 DNS_SEARCH_FMATCH	dns_search_full_match
363
+DNS_NAPTR_IGNORE_RFC	dns_naptr_ignore_rfc
363 364
 /* dns cache */
364 365
 DNS_CACHE_INIT	dns_cache_init
365 366
 DNS_USE_CACHE	use_dns_cache
... ...
@@ -724,6 +725,8 @@ IMPORTFILE      "import_file"
724 724
 								return DNS_USE_SEARCH; }
725 725
 <INITIAL>{DNS_SEARCH_FMATCH}	{ count(); yylval.strval=yytext;
726 726
 								return DNS_SEARCH_FMATCH; }
727
+<INITIAL>{DNS_NAPTR_IGNORE_RFC}	{ count(); yylval.strval=yytext;
728
+								return DNS_NAPTR_IGNORE_RFC; }
727 729
 <INITIAL>{DNS_CACHE_INIT}	{ count(); yylval.strval=yytext;
728 730
 								return DNS_CACHE_INIT; }
729 731
 <INITIAL>{DNS_USE_CACHE}	{ count(); yylval.strval=yytext;
... ...
@@ -409,6 +409,7 @@ extern char *finame;
409 409
 %token DNS_SERVERS_NO
410 410
 %token DNS_USE_SEARCH
411 411
 %token DNS_SEARCH_FMATCH
412
+%token DNS_NAPTR_IGNORE_RFC
412 413
 %token DNS_CACHE_INIT
413 414
 %token DNS_USE_CACHE
414 415
 %token DNS_USE_FAILOVER
... ...
@@ -865,6 +866,8 @@ assign_stm:
865 865
 	| DNS_USE_SEARCH error { yyerror("boolean value expected"); }
866 866
 	| DNS_SEARCH_FMATCH EQUAL NUMBER   { default_core_cfg.dns_search_fmatch=$3; }
867 867
 	| DNS_SEARCH_FMATCH error { yyerror("boolean value expected"); }
868
+	| DNS_NAPTR_IGNORE_RFC EQUAL NUMBER   { default_core_cfg.dns_naptr_ignore_rfc=$3; }
869
+	| DNS_NAPTR_IGNORE_RFC error { yyerror("boolean value expected"); }
868 870
 	| DNS_CACHE_INIT EQUAL NUMBER   { IF_DNS_CACHE(dns_cache_init=$3); }
869 871
 	| DNS_CACHE_INIT error { yyerror("boolean value expected"); }
870 872
 	| DNS_USE_CACHE EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.use_dns_cache=$3); }
... ...
@@ -88,6 +88,7 @@ struct cfg_group_core default_core_cfg = {
88 88
 	1,  /*!< dns_search_list */
89 89
 	1,  /*!< dns_search_fmatch */
90 90
 	0,  /*!< dns_reinit */
91
+	1,  /*!< dns_naptr_ignore_rfc */
91 92
 	/* DNS cache */
92 93
 #ifdef USE_DNS_CACHE
93 94
 	1,  /*!< use_dns_cache -- on by default */
... ...
@@ -216,13 +217,13 @@ cfg_def_t core_cfg_def[] = {
216 216
 	{"dns_try_naptr",	CFG_VAR_INT,	0, 1, 0, 0,
217 217
 #endif
218 218
 		"enable/disable NAPTR DNS lookups"},
219
-	{"dns_udp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
219
+	{"dns_udp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
220 220
 		"udp protocol preference when doing NAPTR lookups"},
221
-	{"dns_tcp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
221
+	{"dns_tcp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
222 222
 		"tcp protocol preference when doing NAPTR lookups"},
223
-	{"dns_tls_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
223
+	{"dns_tls_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
224 224
 		"tls protocol preference when doing NAPTR lookups"},
225
-	{"dns_sctp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_naptr_proto_prefs,
225
+	{"dns_sctp_pref",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
226 226
 		"sctp protocol preference when doing NAPTR lookups"},
227 227
 	{"dns_retr_time",	CFG_VAR_INT,	0, 0, 0, resolv_reinit,
228 228
 		"time in s before retrying a dns request"},
... ...
@@ -239,6 +240,8 @@ cfg_def_t core_cfg_def[] = {
239 239
 	{"dns_reinit",		CFG_VAR_INT|CFG_INPUT_INT,	1, 1, dns_reinit_fixup,
240 240
 		resolv_reinit,
241 241
 		"set to 1 in order to reinitialize the DNS resolver"},
242
+	{"dns_naptr_ignore_rfc",	CFG_VAR_INT,	0, 0, 0, reinit_proto_prefs,
243
+		"ignore the Order field required by RFC 2915"},
242 244
 	/* DNS cache */
243 245
 #ifdef USE_DNS_CACHE
244 246
 	{"use_dns_cache",	CFG_VAR_INT,	0, 1, use_dns_cache_fixup, 0,
... ...
@@ -80,6 +80,7 @@ struct cfg_group_core {
80 80
 	int dns_search_list;
81 81
 	int dns_search_fmatch;
82 82
 	int dns_reinit;
83
+	int dns_naptr_ignore_rfc;
83 84
 	/* DNS cache */
84 85
 #ifdef USE_DNS_CACHE
85 86
 	int use_dns_cache;
... ...
@@ -3291,12 +3291,11 @@ inline static int dns_srv_sip_resolve(struct dns_srv_handle* h,  str* name,
3291 3291
 						srv_name.len=strlen(tmp);
3292 3292
 						if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0)
3293 3293
 						{
3294
-							*proto = srv_proto_list[i].proto;
3294
+							h->proto = *proto = srv_proto_list[i].proto;
3295 3295
 #ifdef DNS_CACHE_DEBUG
3296 3296
 							DBG("dns_srv_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
3297 3297
 								name->len, name->s, h->srv_no, h->ip_no, ret);
3298 3298
 #endif
3299
-							/* proto already set */
3300 3299
 							return ret;
3301 3300
 						}
3302 3301
 					}
... ...
@@ -92,23 +92,58 @@ counter_def_t dns_cnt_defs[] =  {
92 92
 #ifdef USE_NAPTR
93 93
 static int naptr_proto_pref[PROTO_LAST+1];
94 94
 #endif
95
+static int srv_proto_pref[PROTO_LAST+1];
95 96
 
96 97
 #ifdef USE_NAPTR
97
-void init_naptr_proto_prefs()
98
+static void init_naptr_proto_prefs()
98 99
 {
100
+	int ignore_rfc, udp, tcp, tls, sctp;
101
+
99 102
 	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
100 103
 		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
101 104
 		BUG("init_naptr_proto_prefs: array too small \n");
102 105
 		return;
103 106
 	}
104
-	naptr_proto_pref[PROTO_UDP]=cfg_get(core, core_cfg, dns_udp_pref);
105
-	naptr_proto_pref[PROTO_TCP]=cfg_get(core, core_cfg, dns_tcp_pref);
106
-	naptr_proto_pref[PROTO_TLS]=cfg_get(core, core_cfg, dns_tls_pref);
107
-	naptr_proto_pref[PROTO_SCTP]=cfg_get(core, core_cfg, dns_sctp_pref);
107
+
108
+	ignore_rfc = cfg_get(core, core_cfg, dns_naptr_ignore_rfc);
109
+	udp = cfg_get(core, core_cfg, dns_udp_pref);
110
+	tcp = cfg_get(core, core_cfg, dns_tcp_pref);
111
+	tls = cfg_get(core, core_cfg, dns_tls_pref);
112
+	sctp = cfg_get(core, core_cfg, dns_sctp_pref);
113
+
114
+	/* Old implementation ignored the Order field in the NAPTR RR and
115
+	 * thus violated a MUST in RFC 2915. Currently still the default. */
116
+	if (ignore_rfc) {
117
+		naptr_proto_pref[PROTO_UDP] = udp;
118
+		naptr_proto_pref[PROTO_TCP] = tcp;
119
+		naptr_proto_pref[PROTO_TLS] = tls;
120
+		naptr_proto_pref[PROTO_SCTP] = sctp;
121
+	} else {
122
+		/* If value is less than 0, proto is disabled, otherwise
123
+		 * ignored. */
124
+		naptr_proto_pref[PROTO_UDP] = udp < 0 ? udp : 1;
125
+		naptr_proto_pref[PROTO_TCP] = tcp < 0 ? tcp : 1;
126
+		naptr_proto_pref[PROTO_TLS] = tls < 0 ? tls : 1;
127
+		naptr_proto_pref[PROTO_SCTP] = sctp < 0 ? sctp : 1;
128
+	}
108 129
 }
109 130
 
110 131
 #endif /* USE_NAPTR */
111 132
 
133
+static void init_srv_proto_prefs()
134
+{
135
+	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
136
+		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
137
+		BUG("init_srv_proto_prefs: array too small \n");
138
+		return;
139
+	}
140
+
141
+	srv_proto_pref[PROTO_UDP] = cfg_get(core, core_cfg, dns_udp_pref);
142
+	srv_proto_pref[PROTO_TCP] = cfg_get(core, core_cfg, dns_tcp_pref);
143
+	srv_proto_pref[PROTO_TLS] = cfg_get(core, core_cfg, dns_tls_pref);
144
+	srv_proto_pref[PROTO_SCTP] = cfg_get(core, core_cfg, dns_sctp_pref);
145
+}
146
+
112 147
 #ifdef DNS_WATCHDOG_SUPPORT
113 148
 static on_resolv_reinit	on_resolv_reinit_cb = NULL;
114 149
 
... ...
@@ -178,9 +213,7 @@ int resolv_init(void)
178 178
 	int res = -1;
179 179
 	_resolv_init();
180 180
 
181
-#ifdef USE_NAPTR
182
-	init_naptr_proto_prefs();
183
-#endif
181
+	reinit_proto_prefs(NULL,NULL);
184 182
 	/* init counter API only at startup
185 183
 	 * This function must be called before DNS cache init method (if available)
186 184
 	 */
... ...
@@ -212,12 +245,13 @@ int dns_reinit_fixup(void *handle, str *gname, str *name, void **val)
212 212
 	return 0;
213 213
 }
214 214
 
215
-/* wrapper function to recalculate the naptr protocol preferences */
216
-void reinit_naptr_proto_prefs(str *gname, str *name)
215
+/* wrapper function to recalculate the naptr and srv protocol preferences */
216
+void reinit_proto_prefs(str *gname, str *name)
217 217
 {
218 218
 #ifdef USE_NAPTR
219 219
 	init_naptr_proto_prefs();
220 220
 #endif
221
+	init_srv_proto_prefs();
221 222
 }
222 223
 
223 224
 /* fixup function for dns_try_ipv6
... ...
@@ -1080,19 +1114,26 @@ char naptr_get_sip_proto(struct naptr_rdata* n)
1080 1080
 
1081 1081
 
1082 1082
 
1083
-inline static int proto_pref_score(char proto)
1083
+inline static int naptr_proto_pref_score(char proto)
1084 1084
 {
1085 1085
 	if ((proto>=PROTO_UDP) && (proto<= PROTO_LAST))
1086 1086
 		return naptr_proto_pref[(int)proto];
1087 1087
 	return 0;
1088 1088
 }
1089 1089
 
1090
+inline static int srv_proto_pref_score(char proto)
1091
+{
1092
+	if ((proto>=PROTO_UDP) && (proto<= PROTO_LAST))
1093
+		return srv_proto_pref[(int)proto];
1094
+	return 0;
1095
+}
1096
+
1090 1097
 
1091 1098
 
1092 1099
 /* returns true if we support the protocol */
1093 1100
 int naptr_proto_supported(char proto)
1094 1101
 {
1095
-	if (proto_pref_score(proto)<0)
1102
+	if (naptr_proto_pref_score(proto)<0)
1096 1103
 		return 0;
1097 1104
 	switch(proto){
1098 1105
 		case PROTO_UDP:
... ...
@@ -1119,7 +1160,7 @@ int naptr_proto_supported(char proto)
1119 1119
 /* returns true if new_proto is preferred over old_proto */
1120 1120
 int naptr_proto_preferred(char new_proto, char old_proto)
1121 1121
 {
1122
-	return proto_pref_score(new_proto)>proto_pref_score(old_proto);
1122
+	return naptr_proto_pref_score(new_proto)>naptr_proto_pref_score(old_proto);
1123 1123
 }
1124 1124
 
1125 1125
 
... ...
@@ -1451,7 +1492,7 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list) {
1451 1451
 		list_len = 0;
1452 1452
 		/*get protocols and preference scores, and add availble protocol(s) and score(s) to the list*/
1453 1453
 		for (i=PROTO_UDP; i<PROTO_LAST;i++) {
1454
-			tmp.proto_pref = proto_pref_score(i);
1454
+			tmp.proto_pref = srv_proto_pref_score(i);
1455 1455
 			/* if -1 so disabled continue with next protocol*/
1456 1456
 			if (naptr_proto_supported(i) == 0) {
1457 1457
 				continue;
... ...
@@ -1470,7 +1511,7 @@ size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list) {
1470 1470
 		}
1471 1471
 		if (default_order){
1472 1472
 			for (i=0; i<list_len;i++) {
1473
-				list[i].proto_pref=proto_pref_score(i);
1473
+				list[i].proto_pref=srv_proto_pref_score(i);
1474 1474
 			}
1475 1475
 		}
1476 1476
 
... ...
@@ -455,7 +455,7 @@ int resolv_init(void);
455 455
 void resolv_reinit(str *gname, str *name);
456 456
 int dns_reinit_fixup(void *handle, str *gname, str *name, void **val);
457 457
 int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val);
458
-void reinit_naptr_proto_prefs(str *gname, str *name);
458
+void reinit_proto_prefs(str *gname, str *name);
459 459
 
460 460
 struct dns_srv_proto {
461 461
 	char proto;