From 98a7f8c7ae44bb98d5469cb3a4240c59abceba7f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 28 Sep 2015 18:57:19 +1000 Subject: [PATCH] 4222. [func] Bias IPv6 servers when selecting the next server to query. [RT #40836] --- CHANGES | 3 +++ bin/named/config.c | 1 + bin/named/server.c | 5 ++++ doc/arm/Bv9ARM-book.xml | 12 +++++++++ doc/misc/options | 2 ++ lib/dns/include/dns/view.h | 1 + lib/dns/resolver.c | 52 ++++++++++++++++++++++++++++++-------- lib/dns/view.c | 1 + lib/isccfg/namedconf.c | 34 ++++++++++++++----------- 9 files changed, 86 insertions(+), 25 deletions(-) diff --git a/CHANGES b/CHANGES index 320d4c8ede..66a58e87c0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4222. [func] Bias IPv6 servers when selecting the next server to + query. [RT #40836] + 4221. [bug] Resource leak on DNS_R_NXDOMAIN in fctx_create. [RT #40583] diff --git a/bin/named/config.c b/bin/named/config.c index 728659360e..fbc6c18acb 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -184,6 +184,7 @@ options {\n\ allow-new-zones no;\n\ fetches-per-server 0;\n\ require-server-cookie no;\n\ + v6-bias 50;\n\ " #ifdef HAVE_GEOIP "\ diff --git a/bin/named/server.c b/bin/named/server.c index 734d11e48a..2dbafe8939 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3542,6 +3542,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, INSIST(result == ISC_R_SUCCESS); view->requireservercookie = cfg_obj_asboolean(obj); + obj = NULL; + result = ns_config_get(maps, "v6-bias", &obj); + INSIST(result == ISC_R_SUCCESS); + view->v6bias = cfg_obj_asuint32(obj) * 1000; + obj = NULL; result = ns_config_get(maps, "max-clients-per-query", &obj); INSIST(result == ISC_R_SUCCESS); diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 04b386ea5c..393317f75b 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -5035,6 +5035,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] min-ns-dots number qname-wait-recurse yes_or_no ; + v6-bias number ; }; @@ -9590,6 +9591,17 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; + + + v6-bias + + + When determining the next nameserver to try + preference IPv6 nameservers by this many milliseconds. + The default is 50 milliseconds. + + + diff --git a/doc/misc/options b/doc/misc/options index f87992a494..fa5a610a57 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -314,6 +314,7 @@ options { use-queryport-pool ; // obsolete use-v4-udp-ports { ; ... }; use-v6-udp-ports { ; ... }; + v6-bias ; version ( | none ); zero-no-soa-ttl ; zero-no-soa-ttl-cache ; @@ -587,6 +588,7 @@ view [ ] { update-check-ksk ; use-alt-transfer-source ; use-queryport-pool ; // obsolete + v6-bias ; zero-no-soa-ttl ; zero-no-soa-ttl-cache ; zone [ ] { diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 04126e95a2..51b41ae417 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -216,6 +216,7 @@ struct dns_view { void (*cfg_destroy)(void **); unsigned char secret[32]; /* Client secret */ + unsigned int v6bias; }; #define DNS_VIEW_MAGIC ISC_MAGIC('V','i','e','w') diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 78310f4cc4..4050905a8a 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2933,18 +2933,32 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, * Sort addrinfo list by RTT. */ static void -sort_adbfind(dns_adbfind_t *find) { +sort_adbfind(dns_adbfind_t *find, unsigned int bias) { dns_adbaddrinfo_t *best, *curr; dns_adbaddrinfolist_t sorted; + int family; /* Lame N^2 bubble sort. */ ISC_LIST_INIT(sorted); while (!ISC_LIST_EMPTY(find->list)) { best = ISC_LIST_HEAD(find->list); + family = isc_sockaddr_pf(&best->sockaddr); curr = ISC_LIST_NEXT(best, publink); while (curr != NULL) { - if (curr->srtt < best->srtt) - best = curr; + if (isc_sockaddr_pf(&curr->sockaddr) == family) { + if (curr->srtt < best->srtt) + best = curr; + } else if (family == AF_INET6) { + if (curr->srtt + bias < best->srtt) { + best = curr; + family = AF_INET; + } + } else { + if (curr->srtt < best->srtt + bias) { + best = curr; + family = AF_INET6; + } + } curr = ISC_LIST_NEXT(curr, publink); } ISC_LIST_UNLINK(find->list, best, publink); @@ -2957,16 +2971,17 @@ sort_adbfind(dns_adbfind_t *find) { * Sort a list of finds by server RTT. */ static void -sort_finds(dns_adbfindlist_t *findlist) { +sort_finds(dns_adbfindlist_t *findlist, unsigned int bias) { dns_adbfind_t *best, *curr; dns_adbfindlist_t sorted; dns_adbaddrinfo_t *addrinfo, *bestaddrinfo; + int family; /* Sort each find's addrinfo list by SRTT. */ for (curr = ISC_LIST_HEAD(*findlist); curr != NULL; curr = ISC_LIST_NEXT(curr, publink)) - sort_adbfind(curr); + sort_adbfind(curr, bias); /* Lame N^2 bubble sort. */ ISC_LIST_INIT(sorted); @@ -2974,13 +2989,30 @@ sort_finds(dns_adbfindlist_t *findlist) { best = ISC_LIST_HEAD(*findlist); bestaddrinfo = ISC_LIST_HEAD(best->list); INSIST(bestaddrinfo != NULL); + family = isc_sockaddr_pf(&bestaddrinfo->sockaddr); curr = ISC_LIST_NEXT(best, publink); while (curr != NULL) { addrinfo = ISC_LIST_HEAD(curr->list); INSIST(addrinfo != NULL); - if (addrinfo->srtt < bestaddrinfo->srtt) { - best = curr; - bestaddrinfo = addrinfo; + if (isc_sockaddr_pf(&addrinfo->sockaddr) == family) { + if (addrinfo->srtt < bestaddrinfo->srtt) { + best = curr; + bestaddrinfo = addrinfo; + } + } else if (family == AF_INET6) { + if (addrinfo->srtt + bias < + bestaddrinfo->srtt) { + best = curr; + bestaddrinfo = addrinfo; + family = AF_INET; + } + } else { + if (addrinfo->srtt < + bestaddrinfo->srtt + bias) { + best = curr; + bestaddrinfo = addrinfo; + family = AF_INET6; + } } curr = ISC_LIST_NEXT(curr, publink); } @@ -3394,8 +3426,8 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { * We've found some addresses. We might still be looking * for more addresses. */ - sort_finds(&fctx->finds); - sort_finds(&fctx->altfinds); + sort_finds(&fctx->finds, res->view->v6bias); + sort_finds(&fctx->altfinds, 0); result = ISC_R_SUCCESS; } diff --git a/lib/dns/view.c b/lib/dns/view.c index 6220c7d321..6d47aebc71 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -240,6 +240,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->cfg_destroy = NULL; view->fail_ttl = 0; view->failcache = NULL; + view->v6bias = 0; dns_badcache_init(view->mctx, DNS_VIEW_FAILCACHESIZE, &view->failcache); if (isc_bind9) { diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index d402327c26..ce2db8c5ac 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1578,6 +1578,18 @@ view_clauses[] = { { "fetch-quota-params", &cfg_type_fetchquota, 0 }, { "fetches-per-server", &cfg_type_fetchesper, 0 }, { "fetches-per-zone", &cfg_type_fetchesper, 0 }, +#ifdef ALLOW_FILTER_AAAA + { "filter-aaaa", &cfg_type_bracketed_aml, 0 }, + { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, 0 }, + { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, 0 }, +#else + { "filter-aaaa", &cfg_type_bracketed_aml, + CFG_CLAUSEFLAG_NOTCONFIGURED }, + { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, + CFG_CLAUSEFLAG_NOTCONFIGURED }, + { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, + CFG_CLAUSEFLAG_NOTCONFIGURED }, +#endif { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 }, { "lame-ttl", &cfg_type_ttlval, 0 }, { "nocookie-udp-size", &cfg_type_uint32, 0 }, @@ -1608,11 +1620,13 @@ view_clauses[] = { { "queryport-pool-ports", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, { "queryport-pool-updateinterval", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, + { "rate-limit", &cfg_type_rrl, 0 }, { "recursion", &cfg_type_boolean, 0 }, { "request-sit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "request-nsid", &cfg_type_boolean, 0 }, { "require-server-cookie", &cfg_type_boolean, 0 }, { "resolver-query-timeout", &cfg_type_uint32, 0 }, + { "response-policy", &cfg_type_rpz, 0 }, { "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, { "root-delegation-only", &cfg_type_optional_exclude, 0 }, { "rrset-order", &cfg_type_rrsetorder, 0 }, @@ -1623,21 +1637,8 @@ view_clauses[] = { { "topology", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_NOTIMP }, { "transfer-format", &cfg_type_transferformat, 0 }, { "use-queryport-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, + { "v6-bias", &cfg_type_uint32, 0 }, { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 }, -#ifdef ALLOW_FILTER_AAAA - { "filter-aaaa", &cfg_type_bracketed_aml, 0 }, - { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, 0 }, - { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, 0 }, -#else - { "filter-aaaa", &cfg_type_bracketed_aml, - CFG_CLAUSEFLAG_NOTCONFIGURED }, - { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, - CFG_CLAUSEFLAG_NOTCONFIGURED }, - { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, - CFG_CLAUSEFLAG_NOTCONFIGURED }, -#endif - { "response-policy", &cfg_type_rpz, 0 }, - { "rate-limit", &cfg_type_rrl, 0 }, { NULL, NULL, 0 } }; @@ -1815,8 +1816,11 @@ view_clausesets[] = { zone_clauses, NULL }; + static cfg_type_t cfg_type_viewopts = { - "view", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, view_clausesets }; + "view", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, + view_clausesets +}; /*% The "zone" statement syntax. */ -- GitLab