mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
2129. [func] Provide a pool of UDP sockets for queries to be
made over. See use-queryport-pool, queryport-pool-ports and queryport-pool-updateinterval. [RT #16415]
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,3 +1,7 @@
|
|||||||
|
2129. [func] Provide a pool of UDP sockets for queries to be
|
||||||
|
made over. See use-queryport-pool, queryport-pool-ports
|
||||||
|
and queryport-pool-updateinterval. [RT #16415]
|
||||||
|
|
||||||
2128. [doc] xsltproc --nonet, update DTD versions. [RT #16635]
|
2128. [doc] xsltproc --nonet, update DTD versions. [RT #16635]
|
||||||
|
|
||||||
2127. [port] Improved OpenSSL 0.9.8 support. [RT #16563]
|
2127. [port] Improved OpenSSL 0.9.8 support. [RT #16563]
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: interfacemgr.c,v 1.85 2006/07/20 01:10:31 marka Exp $ */
|
/* $Id: interfacemgr.c,v 1.86 2007/02/02 02:18:03 marka Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -802,7 +802,9 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
|||||||
(void)dns_acl_match(&listen_netaddr,
|
(void)dns_acl_match(&listen_netaddr,
|
||||||
NULL, ele->acl,
|
NULL, ele->acl,
|
||||||
NULL, &match, NULL);
|
NULL, &match, NULL);
|
||||||
if (match > 0 && ele->port == le->port)
|
if (match > 0 &&
|
||||||
|
(ele->port == le->port ||
|
||||||
|
ele->port == 0))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
match = 0;
|
match = 0;
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
- PERFORMANCE OF THIS SOFTWARE.
|
- PERFORMANCE OF THIS SOFTWARE.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- $Id: named.conf.docbook,v 1.26 2007/01/29 23:57:22 marka Exp $ -->
|
<!-- $Id: named.conf.docbook,v 1.27 2007/02/02 02:18:04 marka Exp $ -->
|
||||||
<refentry>
|
<refentry>
|
||||||
<refentryinfo>
|
<refentryinfo>
|
||||||
<date>Aug 13, 2004</date>
|
<date>Aug 13, 2004</date>
|
||||||
@@ -235,6 +235,9 @@ options {
|
|||||||
additional-from-cache <replaceable>boolean</replaceable>;
|
additional-from-cache <replaceable>boolean</replaceable>;
|
||||||
query-source ( ( <replaceable>ipv4_address</replaceable> | * ) | <optional> address ( <replaceable>ipv4_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
query-source ( ( <replaceable>ipv4_address</replaceable> | * ) | <optional> address ( <replaceable>ipv4_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
||||||
query-source-v6 ( ( <replaceable>ipv6_address</replaceable> | * ) | <optional> address ( <replaceable>ipv6_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
query-source-v6 ( ( <replaceable>ipv6_address</replaceable> | * ) | <optional> address ( <replaceable>ipv6_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
||||||
|
use-queryport-pool <replaceable>boolean</replaceable>;
|
||||||
|
queryport-pool-ports <replaceable>integer</replaceable>;
|
||||||
|
queryport-pool-updateinterval <replaceable>integer</replaceable>;
|
||||||
cleaning-interval <replaceable>integer</replaceable>;
|
cleaning-interval <replaceable>integer</replaceable>;
|
||||||
min-roots <replaceable>integer</replaceable>; // not implemented
|
min-roots <replaceable>integer</replaceable>; // not implemented
|
||||||
lame-ttl <replaceable>integer</replaceable>;
|
lame-ttl <replaceable>integer</replaceable>;
|
||||||
@@ -384,6 +387,9 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
|
|||||||
additional-from-cache <replaceable>boolean</replaceable>;
|
additional-from-cache <replaceable>boolean</replaceable>;
|
||||||
query-source ( ( <replaceable>ipv4_address</replaceable> | * ) | <optional> address ( <replaceable>ipv4_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
query-source ( ( <replaceable>ipv4_address</replaceable> | * ) | <optional> address ( <replaceable>ipv4_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
||||||
query-source-v6 ( ( <replaceable>ipv6_address</replaceable> | * ) | <optional> address ( <replaceable>ipv6_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
query-source-v6 ( ( <replaceable>ipv6_address</replaceable> | * ) | <optional> address ( <replaceable>ipv6_address</replaceable> | * ) </optional> ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>;
|
||||||
|
use-queryport-pool <replaceable>boolean</replaceable>;
|
||||||
|
queryport-pool-ports <replaceable>integer</replaceable>;
|
||||||
|
queryport-pool-updateinterval <replaceable>integer</replaceable>;
|
||||||
cleaning-interval <replaceable>integer</replaceable>;
|
cleaning-interval <replaceable>integer</replaceable>;
|
||||||
min-roots <replaceable>integer</replaceable>; // not implemented
|
min-roots <replaceable>integer</replaceable>; // not implemented
|
||||||
lame-ttl <replaceable>integer</replaceable>;
|
lame-ttl <replaceable>integer</replaceable>;
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: server.c,v 1.475 2007/01/12 00:14:51 marka Exp $ */
|
/* $Id: server.c,v 1.476 2007/02/02 02:18:05 marka Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -953,7 +953,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
|
|||||||
const char *str;
|
const char *str;
|
||||||
dns_order_t *order = NULL;
|
dns_order_t *order = NULL;
|
||||||
isc_uint32_t udpsize;
|
isc_uint32_t udpsize;
|
||||||
unsigned int check = 0;
|
unsigned int resopts = 0;
|
||||||
dns_zone_t *zone = NULL;
|
dns_zone_t *zone = NULL;
|
||||||
isc_uint32_t max_clients_per_query;
|
isc_uint32_t max_clients_per_query;
|
||||||
const char *sep = ": view ";
|
const char *sep = ": view ";
|
||||||
@@ -962,6 +962,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
|
|||||||
isc_boolean_t rfc1918;
|
isc_boolean_t rfc1918;
|
||||||
isc_boolean_t empty_zones_enable;
|
isc_boolean_t empty_zones_enable;
|
||||||
const cfg_obj_t *disablelist = NULL;
|
const cfg_obj_t *disablelist = NULL;
|
||||||
|
isc_uint32_t nqports, qports_updateinterval;
|
||||||
|
|
||||||
REQUIRE(DNS_VIEW_VALID(view));
|
REQUIRE(DNS_VIEW_VALID(view));
|
||||||
|
|
||||||
@@ -1184,14 +1185,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
|
|||||||
|
|
||||||
str = cfg_obj_asstring(obj);
|
str = cfg_obj_asstring(obj);
|
||||||
if (strcasecmp(str, "fail") == 0) {
|
if (strcasecmp(str, "fail") == 0) {
|
||||||
check = DNS_RESOLVER_CHECKNAMES |
|
resopts |= DNS_RESOLVER_CHECKNAMES |
|
||||||
DNS_RESOLVER_CHECKNAMESFAIL;
|
DNS_RESOLVER_CHECKNAMESFAIL;
|
||||||
view->checknames = ISC_TRUE;
|
view->checknames = ISC_TRUE;
|
||||||
} else if (strcasecmp(str, "warn") == 0) {
|
} else if (strcasecmp(str, "warn") == 0) {
|
||||||
check = DNS_RESOLVER_CHECKNAMES;
|
resopts |= DNS_RESOLVER_CHECKNAMES;
|
||||||
view->checknames = ISC_FALSE;
|
view->checknames = ISC_FALSE;
|
||||||
} else if (strcasecmp(str, "ignore") == 0) {
|
} else if (strcasecmp(str, "ignore") == 0) {
|
||||||
check = 0;
|
|
||||||
view->checknames = ISC_FALSE;
|
view->checknames = ISC_FALSE;
|
||||||
} else
|
} else
|
||||||
INSIST(0);
|
INSIST(0);
|
||||||
@@ -1210,11 +1210,93 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
|
|||||||
result = ISC_R_UNEXPECTED;
|
result = ISC_R_UNEXPECTED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj = NULL;
|
||||||
|
(void)ns_config_get(maps, "use-queryport-pool", &obj);
|
||||||
|
if (obj == NULL || cfg_obj_asboolean(obj)) {
|
||||||
|
isc_sockaddr_t sa;
|
||||||
|
isc_boolean_t logit4 = ISC_FALSE, logit6 = ISC_FALSE;
|
||||||
|
|
||||||
|
resopts |= (DNS_RESOLVER_USEDISPATCHPOOL4 |
|
||||||
|
DNS_RESOLVER_USEDISPATCHPOOL6);
|
||||||
|
|
||||||
|
/* Check consistency with query-source(-v6) */
|
||||||
|
if (dispatch4 == NULL)
|
||||||
|
resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL4;
|
||||||
|
else {
|
||||||
|
result = dns_dispatch_getlocaladdress(dispatch4, &sa);
|
||||||
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
if (isc_sockaddr_getport(&sa) != 0) {
|
||||||
|
logit4 = ISC_TRUE;
|
||||||
|
resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispatch6 == NULL)
|
||||||
|
resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL6;
|
||||||
|
else {
|
||||||
|
result = dns_dispatch_getlocaladdress(dispatch6, &sa);
|
||||||
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
if (isc_sockaddr_getport(&sa) != 0) {
|
||||||
|
logit6 = ISC_TRUE;
|
||||||
|
resopts &= ~DNS_RESOLVER_USEDISPATCHPOOL6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logit4 && obj != NULL)
|
||||||
|
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
|
||||||
|
"specific query-source port "
|
||||||
|
"cannot coexist with queryport-pool. "
|
||||||
|
"(Pool disabled)");
|
||||||
|
if (logit6 && obj != NULL)
|
||||||
|
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
|
||||||
|
"specific query-source-v6 port "
|
||||||
|
"cannot coexist with queryport-pool. "
|
||||||
|
"(Pool disabled)");
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
|
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
|
||||||
ns_g_socketmgr, ns_g_timermgr,
|
ns_g_socketmgr, ns_g_timermgr,
|
||||||
check, ns_g_dispatchmgr,
|
resopts, ns_g_dispatchmgr,
|
||||||
dispatch4, dispatch6));
|
dispatch4, dispatch6));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Query-port pool parameters.
|
||||||
|
*/
|
||||||
|
obj = NULL;
|
||||||
|
nqports = 8;
|
||||||
|
result = ns_config_get(maps, "queryport-pool-ports", &obj);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
if ((resopts & (DNS_RESOLVER_USEDISPATCHPOOL4 |
|
||||||
|
DNS_RESOLVER_USEDISPATCHPOOL6)) == 0) {
|
||||||
|
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
|
||||||
|
"queryport-pool-ports is effective only "
|
||||||
|
"with 'use-queryport-pool yes' (ignored)");
|
||||||
|
} else
|
||||||
|
nqports = cfg_obj_asuint32(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = NULL;
|
||||||
|
qports_updateinterval = 15;
|
||||||
|
result = ns_config_get(maps, "queryport-pool-updateinterval", &obj);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
if ((resopts & (DNS_RESOLVER_USEDISPATCHPOOL4 |
|
||||||
|
DNS_RESOLVER_USEDISPATCHPOOL6)) == 0) {
|
||||||
|
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
|
||||||
|
"queryport-pool-updateinterval is "
|
||||||
|
"effective only with 'use-queryport-pool "
|
||||||
|
"yes' (ignored)");
|
||||||
|
} else
|
||||||
|
qports_updateinterval = cfg_obj_asuint32(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((resopts & (DNS_RESOLVER_USEDISPATCHPOOL4 |
|
||||||
|
DNS_RESOLVER_USEDISPATCHPOOL6)) != 0) {
|
||||||
|
CHECK(dns_resolver_createdispatchpool(view->resolver,
|
||||||
|
nqports,
|
||||||
|
qports_updateinterval
|
||||||
|
* 60));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the ADB cache size to 1/8th of the max-cache-size.
|
* Set the ADB cache size to 1/8th of the max-cache-size.
|
||||||
*/
|
*/
|
||||||
@@ -1241,7 +1323,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
|
|||||||
result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj);
|
result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj);
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
dns_resolver_setzeronosoattl(view->resolver, cfg_obj_asboolean(obj));
|
dns_resolver_setzeronosoattl(view->resolver, cfg_obj_asboolean(obj));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the resolver's EDNS UDP size.
|
* Set the resolver's EDNS UDP size.
|
||||||
*/
|
*/
|
||||||
@@ -2376,7 +2458,9 @@ scan_interfaces(ns_server_t *server, isc_boolean_t verbose) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr) {
|
add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
|
||||||
|
isc_boolean_t wcardport_ok)
|
||||||
|
{
|
||||||
ns_listenelt_t *lelt = NULL;
|
ns_listenelt_t *lelt = NULL;
|
||||||
dns_acl_t *src_acl = NULL;
|
dns_acl_t *src_acl = NULL;
|
||||||
dns_aclelement_t aelt;
|
dns_aclelement_t aelt;
|
||||||
@@ -2386,7 +2470,8 @@ add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr) {
|
|||||||
REQUIRE(isc_sockaddr_pf(addr) == AF_INET6);
|
REQUIRE(isc_sockaddr_pf(addr) == AF_INET6);
|
||||||
|
|
||||||
isc_sockaddr_any6(&any_sa6);
|
isc_sockaddr_any6(&any_sa6);
|
||||||
if (!isc_sockaddr_equal(&any_sa6, addr)) {
|
if (!isc_sockaddr_equal(&any_sa6, addr) &&
|
||||||
|
(wcardport_ok || isc_sockaddr_getport(addr) != 0)) {
|
||||||
aelt.type = dns_aclelementtype_ipprefix;
|
aelt.type = dns_aclelementtype_ipprefix;
|
||||||
aelt.negative = ISC_FALSE;
|
aelt.negative = ISC_FALSE;
|
||||||
aelt.u.ip_prefix.prefixlen = 128;
|
aelt.u.ip_prefix.prefixlen = 128;
|
||||||
@@ -2438,6 +2523,8 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
|
|||||||
view != NULL;
|
view != NULL;
|
||||||
view = ISC_LIST_NEXT(view, link)) {
|
view = ISC_LIST_NEXT(view, link)) {
|
||||||
dns_dispatch_t *dispatch6;
|
dns_dispatch_t *dispatch6;
|
||||||
|
isc_boolean_t use_portpool = ISC_FALSE;
|
||||||
|
unsigned int resopts;
|
||||||
|
|
||||||
dispatch6 = dns_resolver_dispatchv6(view->resolver);
|
dispatch6 = dns_resolver_dispatchv6(view->resolver);
|
||||||
if (dispatch6 == NULL)
|
if (dispatch6 == NULL)
|
||||||
@@ -2445,7 +2532,19 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
|
|||||||
result = dns_dispatch_getlocaladdress(dispatch6, &addr);
|
result = dns_dispatch_getlocaladdress(dispatch6, &addr);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
result = add_listenelt(mctx, list, &addr);
|
resopts = dns_resolver_getoptions(view->resolver);
|
||||||
|
if ((resopts & (DNS_RESOLVER_USEDISPATCHPOOL4 |
|
||||||
|
DNS_RESOLVER_USEDISPATCHPOOL6)) != 0) {
|
||||||
|
/*
|
||||||
|
* If the resolver uses a dynamic pool of query ports
|
||||||
|
* with a specific source address, some of the current
|
||||||
|
* and future ports may override an existing wildcard
|
||||||
|
* IPv6 port. So we need to allow wildcard match
|
||||||
|
* in this case.
|
||||||
|
*/
|
||||||
|
use_portpool = ISC_TRUE;
|
||||||
|
}
|
||||||
|
result = add_listenelt(mctx, list, &addr, use_portpool);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -2475,12 +2574,12 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
addrp = dns_zone_getnotifysrc6(zone);
|
addrp = dns_zone_getnotifysrc6(zone);
|
||||||
result = add_listenelt(mctx, list, addrp);
|
result = add_listenelt(mctx, list, addrp, ISC_FALSE);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
addrp = dns_zone_getxfrsource6(zone);
|
addrp = dns_zone_getxfrsource6(zone);
|
||||||
result = add_listenelt(mctx, list, addrp);
|
result = add_listenelt(mctx, list, addrp, ISC_FALSE);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
- PERFORMANCE OF THIS SOFTWARE.
|
- PERFORMANCE OF THIS SOFTWARE.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.312 2007/01/29 23:57:22 marka Exp $ -->
|
<!-- File: $Id: Bv9ARM-book.xml,v 1.313 2007/02/02 02:18:05 marka Exp $ -->
|
||||||
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
<title>BIND 9 Administrator Reference Manual</title>
|
<title>BIND 9 Administrator Reference Manual</title>
|
||||||
|
|
||||||
@@ -4443,6 +4443,9 @@ category notify { null; };
|
|||||||
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
|
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> |
|
||||||
<optional> address ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
|
<optional> address ( <replaceable>ip6_addr</replaceable> | <replaceable>*</replaceable> ) </optional>
|
||||||
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
|
<optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional> ) ; </optional>
|
||||||
|
<optional> use-queryport-pool <replaceable>yse_or_no</replaceable>; </optional>
|
||||||
|
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
|
||||||
|
<optional> queryport-pool-interval <replaceable>number</replaceable>; </optional>
|
||||||
<optional> max-transfer-time-in <replaceable>number</replaceable>; </optional>
|
<optional> max-transfer-time-in <replaceable>number</replaceable>; </optional>
|
||||||
<optional> max-transfer-time-out <replaceable>number</replaceable>; </optional>
|
<optional> max-transfer-time-out <replaceable>number</replaceable>; </optional>
|
||||||
<optional> max-transfer-idle-in <replaceable>number</replaceable>; </optional>
|
<optional> max-transfer-idle-in <replaceable>number</replaceable>; </optional>
|
||||||
@@ -6074,7 +6077,7 @@ listen-on-v6 port 1234 { !2001:db8::/32; any; };
|
|||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
<sect3>
|
<sect3 id="query_address">
|
||||||
<title>Query Address</title>
|
<title>Query Address</title>
|
||||||
<para>
|
<para>
|
||||||
If the server doesn't know the answer to a question, it will
|
If the server doesn't know the answer to a question, it will
|
||||||
@@ -6085,22 +6088,61 @@ listen-on-v6 port 1234 { !2001:db8::/32; any; };
|
|||||||
a wildcard IP address (<command>INADDR_ANY</command>)
|
a wildcard IP address (<command>INADDR_ANY</command>)
|
||||||
will be used.
|
will be used.
|
||||||
If <command>port</command> is <command>*</command> or is omitted,
|
If <command>port</command> is <command>*</command> or is omitted,
|
||||||
a random unprivileged port will be used. The <command>avoid-v4-udp-ports</command>
|
a pool of random unprivileged port will be used. See
|
||||||
|
<command>use-queryport-pool</command>,
|
||||||
|
<command>queryport-pool-ports</command> and
|
||||||
|
<command>queryport-pool-updateinterval</command> for how the pool
|
||||||
|
is configured.
|
||||||
|
The <command>avoid-v4-udp-ports</command>
|
||||||
and <command>avoid-v6-udp-ports</command> options can be used
|
and <command>avoid-v6-udp-ports</command> options can be used
|
||||||
to prevent named
|
to prevent named
|
||||||
from selecting certain ports. The defaults are:
|
from selecting certain ports.
|
||||||
|
The defaults are:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<programlisting>query-source address * port *;
|
<programlisting>query-source address * port *;
|
||||||
query-source-v6 address * port *;
|
query-source-v6 address * port *;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><command>use-queryport-pool</command></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Enable they use of query port pools. By default query port
|
||||||
|
pools are enabled unless there is a explicit port defined
|
||||||
|
in <command>query-source</command> or
|
||||||
|
<command>query-source-v6</command>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><command>queryport-pool-ports</command></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specify how many pool ports to use. The default is 8.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><command>queryport-pool-updateinterval</command></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specify how often, in minutes, that the queryport pool
|
||||||
|
should be recreated (new ports selected). The default
|
||||||
|
is 15 minutes.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The address specified in the <command>query-source</command> option
|
The address specified in the <command>query-source</command> option
|
||||||
is used for both UDP and TCP queries, but the port applies only
|
is used for both UDP and TCP queries, but the port applies only
|
||||||
to
|
to UDP queries. TCP queries always use a random
|
||||||
UDP queries. TCP queries always use a random
|
|
||||||
unprivileged port.
|
unprivileged port.
|
||||||
</para>
|
</para>
|
||||||
</note>
|
</note>
|
||||||
@@ -7669,6 +7711,9 @@ query-source-v6 address * port *;
|
|||||||
<optional> query-source <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
|
<optional> query-source <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
|
||||||
<optional> query-source-v6 <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
|
<optional> query-source-v6 <optional> address ( <replaceable>ip_addr</replaceable> | <replaceable>*</replaceable> ) </optional> <optional> port ( <replaceable>ip_port</replaceable> | <replaceable>*</replaceable> ) </optional>; </optional>
|
||||||
};
|
};
|
||||||
|
<optional> use-queryport-pool <replaceable>yse_or_no</replaceable>; </optional>
|
||||||
|
<optional> queryport-pool-ports <replaceable>number</replaceable>; </optional>
|
||||||
|
<optional> queryport-pool-interval <replaceable>number</replaceable>; </optional>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dispatch.c,v 1.127 2006/07/19 00:42:13 marka Exp $ */
|
/* $Id: dispatch.c,v 1.128 2007/02/02 02:18:06 marka Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -282,6 +282,20 @@ reseed_lfsr(isc_lfsr_t *lfsr, void *arg)
|
|||||||
lfsr->state = random();
|
lfsr->state = random();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an unpredictable non-reserved UDP port. We share the QID
|
||||||
|
* framework for this purpose.
|
||||||
|
*/
|
||||||
|
static in_port_t
|
||||||
|
get_randomport(dns_qid_t *qid) {
|
||||||
|
isc_uint32_t p;
|
||||||
|
|
||||||
|
p = isc_lfsr_generate32(&qid->qid_lfsr1, &qid->qid_lfsr2);
|
||||||
|
|
||||||
|
/* XXX: should the range be configurable? */
|
||||||
|
return ((in_port_t)(1024 + (p % (65535 - 1024))));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return an unpredictable message ID.
|
* Return an unpredictable message ID.
|
||||||
*/
|
*/
|
||||||
@@ -1290,20 +1304,26 @@ dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_boolean_t
|
static isc_boolean_t
|
||||||
blacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock) {
|
blacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
|
||||||
|
isc_sockaddr_t *sockaddrp)
|
||||||
|
{
|
||||||
isc_sockaddr_t sockaddr;
|
isc_sockaddr_t sockaddr;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
|
REQUIRE(sock != NULL || sockaddrp != NULL);
|
||||||
|
|
||||||
if (mgr->portlist == NULL)
|
if (mgr->portlist == NULL)
|
||||||
return (ISC_FALSE);
|
return (ISC_FALSE);
|
||||||
|
|
||||||
result = isc_socket_getsockname(sock, &sockaddr);
|
if (sock != NULL) {
|
||||||
if (result != ISC_R_SUCCESS)
|
sockaddrp = &sockaddr;
|
||||||
return (ISC_FALSE);
|
result = isc_socket_getsockname(sock, sockaddrp);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
return (ISC_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if (mgr->portlist != NULL &&
|
if (dns_portlist_match(mgr->portlist, isc_sockaddr_pf(sockaddrp),
|
||||||
dns_portlist_match(mgr->portlist, isc_sockaddr_pf(&sockaddr),
|
isc_sockaddr_getport(sockaddrp)))
|
||||||
isc_sockaddr_getport(&sockaddr)))
|
|
||||||
return (ISC_TRUE);
|
return (ISC_TRUE);
|
||||||
return (ISC_FALSE);
|
return (ISC_FALSE);
|
||||||
}
|
}
|
||||||
@@ -1324,7 +1344,7 @@ local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) {
|
|||||||
if (disp->mgr->portlist != NULL &&
|
if (disp->mgr->portlist != NULL &&
|
||||||
isc_sockaddr_getport(addr) == 0 &&
|
isc_sockaddr_getport(addr) == 0 &&
|
||||||
isc_sockaddr_getport(&disp->local) == 0 &&
|
isc_sockaddr_getport(&disp->local) == 0 &&
|
||||||
blacklisted(disp->mgr, disp->socket))
|
blacklisted(disp->mgr, disp->socket, NULL))
|
||||||
return (ISC_FALSE);
|
return (ISC_FALSE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1669,7 +1689,7 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||||||
dns_dispatch_t **dispp)
|
dns_dispatch_t **dispp)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_dispatch_t *disp;
|
dns_dispatch_t *disp = NULL;
|
||||||
|
|
||||||
REQUIRE(VALID_DISPATCHMGR(mgr));
|
REQUIRE(VALID_DISPATCHMGR(mgr));
|
||||||
REQUIRE(sockmgr != NULL);
|
REQUIRE(sockmgr != NULL);
|
||||||
@@ -1689,10 +1709,14 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||||||
|
|
||||||
LOCK(&mgr->lock);
|
LOCK(&mgr->lock);
|
||||||
|
|
||||||
|
if ((attributes & DNS_DISPATCHATTR_RANDOMPORT) != 0) {
|
||||||
|
REQUIRE(isc_sockaddr_getport(localaddr) == 0);
|
||||||
|
goto createudp;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, see if we have a dispatcher that matches.
|
* See if we have a dispatcher that matches.
|
||||||
*/
|
*/
|
||||||
disp = NULL;
|
|
||||||
result = dispatch_find(mgr, localaddr, attributes, mask, &disp);
|
result = dispatch_find(mgr, localaddr, attributes, mask, &disp);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
disp->refcount++;
|
disp->refcount++;
|
||||||
@@ -1717,6 +1741,7 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createudp:
|
||||||
/*
|
/*
|
||||||
* Nope, create one.
|
* Nope, create one.
|
||||||
*/
|
*/
|
||||||
@@ -1752,7 +1777,8 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||||||
dns_dispatch_t *disp;
|
dns_dispatch_t *disp;
|
||||||
isc_socket_t *sock = NULL;
|
isc_socket_t *sock = NULL;
|
||||||
isc_socket_t *held[DNS_DISPATCH_HELD];
|
isc_socket_t *held[DNS_DISPATCH_HELD];
|
||||||
unsigned int i = 0, j = 0;
|
unsigned int i = 0, j = 0, k = 0;
|
||||||
|
isc_sockaddr_t localaddr_bound;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dispatch_allocate() checks mgr for us.
|
* dispatch_allocate() checks mgr for us.
|
||||||
@@ -1768,11 +1794,30 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
|
|||||||
* from returning the same port to us too quickly.
|
* from returning the same port to us too quickly.
|
||||||
*/
|
*/
|
||||||
memset(held, 0, sizeof(held));
|
memset(held, 0, sizeof(held));
|
||||||
|
localaddr_bound = *localaddr;
|
||||||
getsocket:
|
getsocket:
|
||||||
result = create_socket(sockmgr, localaddr, &sock);
|
if ((attributes & DNS_DISPATCHATTR_RANDOMPORT) != 0) {
|
||||||
|
isc_sockaddr_setport(&localaddr_bound,
|
||||||
|
get_randomport(mgr->qid));
|
||||||
|
if (blacklisted(mgr, NULL, &localaddr_bound)) {
|
||||||
|
if (++k == 1024)
|
||||||
|
attributes &= ~DNS_DISPATCHATTR_RANDOMPORT;
|
||||||
|
goto getsocket;
|
||||||
|
}
|
||||||
|
result = create_socket(sockmgr, &localaddr_bound, &sock);
|
||||||
|
if (result == ISC_R_ADDRINUSE) {
|
||||||
|
if (++k == 1024)
|
||||||
|
attributes &= ~DNS_DISPATCHATTR_RANDOMPORT;
|
||||||
|
goto getsocket;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
result = create_socket(sockmgr, localaddr, &sock);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto deallocate_dispatch;
|
goto deallocate_dispatch;
|
||||||
if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) {
|
if ((attributes & DNS_DISPATCHATTR_RANDOMPORT) == 0 &&
|
||||||
|
isc_sockaddr_getport(localaddr) == 0 &&
|
||||||
|
blacklisted(mgr, sock, NULL))
|
||||||
|
{
|
||||||
if (held[i] != NULL)
|
if (held[i] != NULL)
|
||||||
isc_socket_detach(&held[i]);
|
isc_socket_detach(&held[i]);
|
||||||
held[i++] = sock;
|
held[i++] = sock;
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dispatch.h,v 1.52 2006/12/22 01:59:43 marka Exp $ */
|
/* $Id: dispatch.h,v 1.53 2007/02/02 02:18:06 marka Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_DISPATCH_H
|
#ifndef DNS_DISPATCH_H
|
||||||
#define DNS_DISPATCH_H 1
|
#define DNS_DISPATCH_H 1
|
||||||
@@ -113,6 +113,9 @@ struct dns_dispatchevent {
|
|||||||
* _MAKEQUERY
|
* _MAKEQUERY
|
||||||
* The dispatcher can be used to issue queries to other servers, and
|
* The dispatcher can be used to issue queries to other servers, and
|
||||||
* accept replies from them.
|
* accept replies from them.
|
||||||
|
*
|
||||||
|
* _RANDOMPORT
|
||||||
|
* TBD
|
||||||
*/
|
*/
|
||||||
#define DNS_DISPATCHATTR_PRIVATE 0x00000001U
|
#define DNS_DISPATCHATTR_PRIVATE 0x00000001U
|
||||||
#define DNS_DISPATCHATTR_TCP 0x00000002U
|
#define DNS_DISPATCHATTR_TCP 0x00000002U
|
||||||
@@ -122,6 +125,7 @@ struct dns_dispatchevent {
|
|||||||
#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U
|
#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U
|
||||||
#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
|
#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
|
||||||
#define DNS_DISPATCHATTR_CONNECTED 0x00000080U
|
#define DNS_DISPATCHATTR_CONNECTED 0x00000080U
|
||||||
|
#define DNS_DISPATCHATTR_RANDOMPORT 0x00000100U
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: resolver.h,v 1.53 2006/12/22 01:45:00 marka Exp $ */
|
/* $Id: resolver.h,v 1.54 2007/02/02 02:18:06 marka Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_RESOLVER_H
|
#ifndef DNS_RESOLVER_H
|
||||||
#define DNS_RESOLVER_H 1
|
#define DNS_RESOLVER_H 1
|
||||||
@@ -106,6 +106,8 @@ typedef struct dns_fetchevent {
|
|||||||
|
|
||||||
#define DNS_RESOLVER_CHECKNAMES 0x01
|
#define DNS_RESOLVER_CHECKNAMES 0x01
|
||||||
#define DNS_RESOLVER_CHECKNAMESFAIL 0x02
|
#define DNS_RESOLVER_CHECKNAMESFAIL 0x02
|
||||||
|
#define DNS_RESOLVER_USEDISPATCHPOOL4 0x04
|
||||||
|
#define DNS_RESOLVER_USEDISPATCHPOOL6 0x08
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_resolver_create(dns_view_t *view,
|
dns_resolver_create(dns_view_t *view,
|
||||||
@@ -126,8 +128,6 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
*\li Generally, applications should not create a resolver directly, but
|
*\li Generally, applications should not create a resolver directly, but
|
||||||
* should instead call dns_view_createresolver().
|
* should instead call dns_view_createresolver().
|
||||||
*
|
*
|
||||||
*\li No options are currently defined.
|
|
||||||
*
|
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
*\li 'view' is a valid view.
|
*\li 'view' is a valid view.
|
||||||
@@ -474,6 +474,36 @@ dns_resolver_getzeronosoattl(dns_resolver_t *resolver);
|
|||||||
void
|
void
|
||||||
dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state);
|
dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state);
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_resolver_getoptions(dns_resolver_t *resolver);
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_resolver_createdispatchpool(dns_resolver_t *res, unsigned int ndisps,
|
||||||
|
unsigned int interval);
|
||||||
|
/*%<
|
||||||
|
* Create a pool of dispatches
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
*\li Generally, applications should not create a resolver directly, but
|
||||||
|
* should instead call dns_view_createresolver().
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li 'res' is a valid resolver that has not been frozen. Also it must have
|
||||||
|
* either the _USEDISPATCHPOOL4 or _USEDISPATCHPOOL6 option.
|
||||||
|
*
|
||||||
|
*\li 'taskmgr' is a valid task manager.
|
||||||
|
*
|
||||||
|
*\li 'ndisps' > 0.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
*\li #ISC_R_SUCCESS On success.
|
||||||
|
*
|
||||||
|
*\li Anything else Failure.
|
||||||
|
*/
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
|
||||||
#endif /* DNS_RESOLVER_H */
|
#endif /* DNS_RESOLVER_H */
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: resolver.c,v 1.340 2007/01/08 01:13:38 marka Exp $ */
|
/* $Id: resolver.c,v 1.341 2007/02/02 02:18:06 marka Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
|
#include <isc/random.h>
|
||||||
#include <isc/task.h>
|
#include <isc/task.h>
|
||||||
#include <isc/timer.h>
|
#include <isc/timer.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
@@ -290,13 +291,36 @@ typedef struct alternate {
|
|||||||
ISC_LINK(struct alternate) link;
|
ISC_LINK(struct alternate) link;
|
||||||
} alternate_t;
|
} alternate_t;
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
#define DNS_RESOLVER_USERWLOCK 1
|
||||||
|
#else
|
||||||
|
#define DNS_RESOLVER_USERWLOCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DNS_RESOLVER_USERWLOCK
|
||||||
|
#define RES_INITLOCK(l) isc_rwlock_init((l), 0, 0)
|
||||||
|
#define RES_DESTROYLOCK(l) isc_rwlock_destroy(l)
|
||||||
|
#define RES_LOCK(l, t) RWLOCK((l), (t))
|
||||||
|
#define RES_UNLOCK(l, t) RWUNLOCK((l), (t))
|
||||||
|
#else
|
||||||
|
#define RES_INITLOCK(l) isc_mutex_init(l)
|
||||||
|
#define RES_DESTROYLOCK(l) DESTROYLOCK(l)
|
||||||
|
#define RES_LOCK(l, t) LOCK(l)
|
||||||
|
#define RES_UNLOCK(l, t) UNLOCK(l)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct dns_resolver {
|
struct dns_resolver {
|
||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
isc_mem_t * mctx;
|
isc_mem_t * mctx;
|
||||||
isc_mutex_t lock;
|
isc_mutex_t lock;
|
||||||
isc_mutex_t nlock;
|
isc_mutex_t nlock;
|
||||||
isc_mutex_t primelock;
|
isc_mutex_t primelock;
|
||||||
|
#if DNS_RESOLVER_USERWLOCK
|
||||||
|
isc_rwlock_t poollock;
|
||||||
|
#else
|
||||||
|
isc_mutex_t poollock;
|
||||||
|
#endif
|
||||||
dns_rdataclass_t rdclass;
|
dns_rdataclass_t rdclass;
|
||||||
isc_socketmgr_t * socketmgr;
|
isc_socketmgr_t * socketmgr;
|
||||||
isc_timermgr_t * timermgr;
|
isc_timermgr_t * timermgr;
|
||||||
@@ -307,6 +331,7 @@ struct dns_resolver {
|
|||||||
dns_dispatchmgr_t * dispatchmgr;
|
dns_dispatchmgr_t * dispatchmgr;
|
||||||
dns_dispatch_t * dispatchv4;
|
dns_dispatch_t * dispatchv4;
|
||||||
dns_dispatch_t * dispatchv6;
|
dns_dispatch_t * dispatchv6;
|
||||||
|
unsigned int ndisps;
|
||||||
unsigned int nbuckets;
|
unsigned int nbuckets;
|
||||||
fctxbucket_t * buckets;
|
fctxbucket_t * buckets;
|
||||||
isc_uint32_t lame_ttl;
|
isc_uint32_t lame_ttl;
|
||||||
@@ -324,6 +349,7 @@ struct dns_resolver {
|
|||||||
unsigned int spillatmin;
|
unsigned int spillatmin;
|
||||||
isc_timer_t * spillattimer;
|
isc_timer_t * spillattimer;
|
||||||
isc_boolean_t zero_no_soa_ttl;
|
isc_boolean_t zero_no_soa_ttl;
|
||||||
|
isc_timer_t * disppooltimer;
|
||||||
/* Locked by lock. */
|
/* Locked by lock. */
|
||||||
unsigned int references;
|
unsigned int references;
|
||||||
isc_boolean_t exiting;
|
isc_boolean_t exiting;
|
||||||
@@ -331,10 +357,14 @@ struct dns_resolver {
|
|||||||
unsigned int activebuckets;
|
unsigned int activebuckets;
|
||||||
isc_boolean_t priming;
|
isc_boolean_t priming;
|
||||||
unsigned int spillat;
|
unsigned int spillat;
|
||||||
|
unsigned int nextdisp;
|
||||||
/* Locked by primelock. */
|
/* Locked by primelock. */
|
||||||
dns_fetch_t * primefetch;
|
dns_fetch_t * primefetch;
|
||||||
/* Locked by nlock. */
|
/* Locked by nlock. */
|
||||||
unsigned int nfctx;
|
unsigned int nfctx;
|
||||||
|
/* Locked by poollock. */
|
||||||
|
dns_dispatch_t ** dispatchv4pool;
|
||||||
|
dns_dispatch_t ** dispatchv6pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!')
|
#define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!')
|
||||||
@@ -1143,14 +1173,39 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_query;
|
goto cleanup_query;
|
||||||
} else {
|
} else {
|
||||||
|
int did = 0;
|
||||||
|
isc_uint32_t val;
|
||||||
|
|
||||||
|
if (res->ndisps > 0) {
|
||||||
|
isc_random_get(&val);
|
||||||
|
did = val % res->ndisps;
|
||||||
|
}
|
||||||
switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
|
switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
|
||||||
case PF_INET:
|
case PF_INET:
|
||||||
dns_dispatch_attach(res->dispatchv4,
|
if (res->ndisps > 0) {
|
||||||
&query->dispatch);
|
RES_LOCK(&res->poollock,
|
||||||
|
isc_rwlocktype_read);
|
||||||
|
dns_dispatch_attach(res->dispatchv4pool[did],
|
||||||
|
&query->dispatch);
|
||||||
|
RES_UNLOCK(&res->poollock,
|
||||||
|
isc_rwlocktype_read);
|
||||||
|
} else {
|
||||||
|
dns_dispatch_attach(res->dispatchv4,
|
||||||
|
&query->dispatch);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PF_INET6:
|
case PF_INET6:
|
||||||
dns_dispatch_attach(res->dispatchv6,
|
if (res->ndisps > 0) {
|
||||||
&query->dispatch);
|
RES_LOCK(&res->poollock,
|
||||||
|
isc_rwlocktype_read);
|
||||||
|
dns_dispatch_attach(res->dispatchv6pool[did],
|
||||||
|
&query->dispatch);
|
||||||
|
RES_UNLOCK(&res->poollock,
|
||||||
|
isc_rwlocktype_read);
|
||||||
|
} else {
|
||||||
|
dns_dispatch_attach(res->dispatchv6,
|
||||||
|
&query->dispatch);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = ISC_R_NOTIMPLEMENTED;
|
result = ISC_R_NOTIMPLEMENTED;
|
||||||
@@ -5962,6 +6017,7 @@ destroy(dns_resolver_t *res) {
|
|||||||
|
|
||||||
INSIST(res->nfctx == 0);
|
INSIST(res->nfctx == 0);
|
||||||
|
|
||||||
|
RES_DESTROYLOCK(&res->poollock);
|
||||||
DESTROYLOCK(&res->primelock);
|
DESTROYLOCK(&res->primelock);
|
||||||
DESTROYLOCK(&res->nlock);
|
DESTROYLOCK(&res->nlock);
|
||||||
DESTROYLOCK(&res->lock);
|
DESTROYLOCK(&res->lock);
|
||||||
@@ -5978,12 +6034,26 @@ destroy(dns_resolver_t *res) {
|
|||||||
dns_dispatch_detach(&res->dispatchv4);
|
dns_dispatch_detach(&res->dispatchv4);
|
||||||
if (res->dispatchv6 != NULL)
|
if (res->dispatchv6 != NULL)
|
||||||
dns_dispatch_detach(&res->dispatchv6);
|
dns_dispatch_detach(&res->dispatchv6);
|
||||||
|
if (res->dispatchv4pool != NULL) {
|
||||||
|
for (i = 0; i < res->ndisps; i++)
|
||||||
|
dns_dispatch_detach(&res->dispatchv4pool[i]);
|
||||||
|
isc_mem_put(res->mctx, res->dispatchv4pool,
|
||||||
|
res->ndisps * sizeof(dns_dispatch_t *));
|
||||||
|
}
|
||||||
|
if (res->dispatchv6pool != NULL) {
|
||||||
|
for (i = 0; i < res->ndisps; i++)
|
||||||
|
dns_dispatch_detach(&res->dispatchv6pool[i]);
|
||||||
|
isc_mem_put(res->mctx, res->dispatchv6pool,
|
||||||
|
res->ndisps * sizeof(dns_dispatch_t *));
|
||||||
|
}
|
||||||
while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
|
while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
|
||||||
ISC_LIST_UNLINK(res->alternates, a, link);
|
ISC_LIST_UNLINK(res->alternates, a, link);
|
||||||
if (!a->isaddress)
|
if (!a->isaddress)
|
||||||
dns_name_free(&a->_u._n.name, res->mctx);
|
dns_name_free(&a->_u._n.name, res->mctx);
|
||||||
isc_mem_put(res->mctx, a, sizeof(*a));
|
isc_mem_put(res->mctx, a, sizeof(*a));
|
||||||
}
|
}
|
||||||
|
if (res->disppooltimer != NULL)
|
||||||
|
isc_timer_detach(&res->disppooltimer);
|
||||||
dns_resolver_reset_algorithms(res);
|
dns_resolver_reset_algorithms(res);
|
||||||
dns_resolver_resetmustbesecure(res);
|
dns_resolver_resetmustbesecure(res);
|
||||||
#if USE_ALGLOCK
|
#if USE_ALGLOCK
|
||||||
@@ -6112,6 +6182,11 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
res->spillatmax = 100;
|
res->spillatmax = 100;
|
||||||
res->spillattimer = NULL;
|
res->spillattimer = NULL;
|
||||||
res->zero_no_soa_ttl = ISC_FALSE;
|
res->zero_no_soa_ttl = ISC_FALSE;
|
||||||
|
res->ndisps = 0;
|
||||||
|
res->nextdisp = 0; /* meaningless at this point, but init it */
|
||||||
|
res->dispatchv4pool = NULL;
|
||||||
|
res->dispatchv6pool = NULL;
|
||||||
|
res->disppooltimer = NULL;
|
||||||
|
|
||||||
res->nbuckets = ntasks;
|
res->nbuckets = ntasks;
|
||||||
res->activebuckets = ntasks;
|
res->activebuckets = ntasks;
|
||||||
@@ -6147,7 +6222,8 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
|
|
||||||
res->dispatchv4 = NULL;
|
res->dispatchv4 = NULL;
|
||||||
if (dispatchv4 != NULL)
|
if (dispatchv4 != NULL)
|
||||||
dns_dispatch_attach(dispatchv4, &res->dispatchv4);
|
dns_dispatch_attach(dispatchv4, &res->dispatchv4);
|
||||||
|
|
||||||
res->dispatchv6 = NULL;
|
res->dispatchv6 = NULL;
|
||||||
if (dispatchv6 != NULL)
|
if (dispatchv6 != NULL)
|
||||||
dns_dispatch_attach(dispatchv6, &res->dispatchv6);
|
dns_dispatch_attach(dispatchv6, &res->dispatchv6);
|
||||||
@@ -6172,17 +6248,21 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_nlock;
|
goto cleanup_nlock;
|
||||||
|
|
||||||
|
result = RES_INITLOCK(&res->poollock);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup_primelock;
|
||||||
|
|
||||||
task = NULL;
|
task = NULL;
|
||||||
result = isc_task_create(taskmgr, 0, &task);
|
result = isc_task_create(taskmgr, 0, &task);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_primelock;
|
goto cleanup_poollock;
|
||||||
|
|
||||||
result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
|
result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
|
||||||
task, spillattimer_countdown, res,
|
task, spillattimer_countdown, res,
|
||||||
&res->spillattimer);
|
&res->spillattimer);
|
||||||
isc_task_detach(&task);
|
isc_task_detach(&task);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_primelock;
|
goto cleanup_poollock;
|
||||||
|
|
||||||
#if USE_ALGLOCK
|
#if USE_ALGLOCK
|
||||||
result = isc_rwlock_init(&res->alglock, 0, 0);
|
result = isc_rwlock_init(&res->alglock, 0, 0);
|
||||||
@@ -6212,6 +6292,9 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
isc_timer_detach(&res->spillattimer);
|
isc_timer_detach(&res->spillattimer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
cleanup_poollock:
|
||||||
|
RES_DESTROYLOCK(&res->poollock);
|
||||||
|
|
||||||
cleanup_primelock:
|
cleanup_primelock:
|
||||||
DESTROYLOCK(&res->primelock);
|
DESTROYLOCK(&res->primelock);
|
||||||
|
|
||||||
@@ -7112,3 +7195,254 @@ dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) {
|
|||||||
|
|
||||||
resolver->zero_no_soa_ttl = state;
|
resolver->zero_no_soa_ttl = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_resolver_getoptions(dns_resolver_t *resolver) {
|
||||||
|
REQUIRE(VALID_RESOLVER(resolver));
|
||||||
|
|
||||||
|
return (resolver->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
disppooltimer_update(isc_task_t *task, isc_event_t *event) {
|
||||||
|
dns_resolver_t *res = event->ev_arg;
|
||||||
|
isc_sockaddr_t addr4, addr6;
|
||||||
|
dns_dispatch_t *disp4, *disp6;
|
||||||
|
isc_result_t result;
|
||||||
|
unsigned int nxt;
|
||||||
|
unsigned int attrs_base, attrs, attrmask;
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE((res->options & DNS_RESOLVER_USEDISPATCHPOOL4) != 0 ||
|
||||||
|
(res->options & DNS_RESOLVER_USEDISPATCHPOOL6) != 0);
|
||||||
|
|
||||||
|
UNUSED(task);
|
||||||
|
isc_event_free(&event);
|
||||||
|
|
||||||
|
LOCK(&res->lock);
|
||||||
|
nxt = res->nextdisp++;
|
||||||
|
if (res->nextdisp == res->ndisps)
|
||||||
|
res->nextdisp = 0;
|
||||||
|
UNLOCK(&res->lock);
|
||||||
|
|
||||||
|
attrs_base = 0;
|
||||||
|
attrs_base |= DNS_DISPATCHATTR_UDP;
|
||||||
|
attrs_base |= DNS_DISPATCHATTR_RANDOMPORT;
|
||||||
|
|
||||||
|
attrmask = 0;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_UDP;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_TCP;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_IPV4;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_IPV6;
|
||||||
|
|
||||||
|
RES_LOCK(&res->poollock, isc_rwlocktype_read);
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL4) != 0) {
|
||||||
|
result = dns_dispatch_getlocaladdress(res->dispatchv4pool[nxt],
|
||||||
|
&addr4);
|
||||||
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL6) != 0) {
|
||||||
|
result = dns_dispatch_getlocaladdress(res->dispatchv6pool[nxt],
|
||||||
|
&addr6);
|
||||||
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
RES_UNLOCK(&res->poollock, isc_rwlocktype_read);
|
||||||
|
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL4) != 0) {
|
||||||
|
attrs = attrs_base;
|
||||||
|
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||||
|
|
||||||
|
disp4 = NULL;
|
||||||
|
result = dns_dispatch_getudp(res->dispatchmgr,
|
||||||
|
res->socketmgr,
|
||||||
|
res->taskmgr, &addr4,
|
||||||
|
4096, 1000, 32768, 16411,
|
||||||
|
16433, attrs, attrmask,
|
||||||
|
&disp4);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||||
|
DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
|
||||||
|
"could not update an IPv4 random query "
|
||||||
|
"port: %s",
|
||||||
|
isc_result_totext(result));
|
||||||
|
/* keep the old one */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't try to ensure the new dispatch is unique (see the
|
||||||
|
* comments in dns_resolver_createdispatchpool()).
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL6) != 0) {
|
||||||
|
attrs = attrs_base;
|
||||||
|
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||||
|
|
||||||
|
disp6 = NULL;
|
||||||
|
result = dns_dispatch_getudp(res->dispatchmgr,
|
||||||
|
res->socketmgr,
|
||||||
|
res->taskmgr, &addr6,
|
||||||
|
4096, 1000, 32768, 16411,
|
||||||
|
16433, attrs, attrmask,
|
||||||
|
&disp6);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||||
|
DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
|
||||||
|
"could not update an IPv6 random query "
|
||||||
|
"port: %s",
|
||||||
|
isc_result_totext(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RES_LOCK(&res->poollock, isc_rwlocktype_write);
|
||||||
|
if (disp4 != NULL) {
|
||||||
|
dns_dispatch_detach(&res->dispatchv4pool[nxt]);
|
||||||
|
res->dispatchv4pool[nxt] = disp4;
|
||||||
|
}
|
||||||
|
if (disp6 != NULL) {
|
||||||
|
dns_dispatch_detach(&res->dispatchv6pool[nxt]);
|
||||||
|
res->dispatchv6pool[nxt] = disp6;
|
||||||
|
}
|
||||||
|
RES_UNLOCK(&res->poollock, isc_rwlocktype_write);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_resolver_createdispatchpool(dns_resolver_t *res, unsigned int ndisps,
|
||||||
|
unsigned int tick)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
unsigned int attrs_base, attrs, attrmask;
|
||||||
|
isc_sockaddr_t addr4, addr6;
|
||||||
|
dns_dispatch_t *disp;
|
||||||
|
isc_task_t *task;
|
||||||
|
isc_interval_t interval;
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(!res->frozen); /* meaning we don't have to lock res */
|
||||||
|
REQUIRE(ndisps > 0);
|
||||||
|
REQUIRE((res->options & DNS_RESOLVER_USEDISPATCHPOOL4) != 0 ||
|
||||||
|
(res->options & DNS_RESOLVER_USEDISPATCHPOOL6) != 0);
|
||||||
|
|
||||||
|
attrs_base = 0;
|
||||||
|
attrs_base |= DNS_DISPATCHATTR_UDP;
|
||||||
|
attrs_base |= DNS_DISPATCHATTR_RANDOMPORT;
|
||||||
|
|
||||||
|
attrmask = 0;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_UDP;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_TCP;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_IPV4;
|
||||||
|
attrmask |= DNS_DISPATCHATTR_IPV6;
|
||||||
|
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL4) != 0) {
|
||||||
|
INSIST(res->dispatchv4 != NULL);
|
||||||
|
result = dns_dispatch_getlocaladdress(res->dispatchv4, &addr4);
|
||||||
|
INSIST(result == ISC_R_SUCCESS &&
|
||||||
|
isc_sockaddr_getport(&addr4) == 0);
|
||||||
|
res->dispatchv4pool = isc_mem_get(res->mctx,
|
||||||
|
sizeof(dns_dispatch_t *) *
|
||||||
|
ndisps);
|
||||||
|
if (res->dispatchv4pool == NULL)
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
for (i = 0; i < ndisps; i++)
|
||||||
|
res->dispatchv4pool[i] = NULL;
|
||||||
|
}
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL6) != 0) {
|
||||||
|
INSIST(res->dispatchv6 != NULL);
|
||||||
|
result = dns_dispatch_getlocaladdress(res->dispatchv6, &addr6);
|
||||||
|
INSIST(result == ISC_R_SUCCESS &&
|
||||||
|
isc_sockaddr_getport(&addr6) == 0);
|
||||||
|
res->dispatchv6pool = isc_mem_get(res->mctx,
|
||||||
|
sizeof(dns_dispatch_t *) *
|
||||||
|
ndisps);
|
||||||
|
if (res->dispatchv6pool == NULL) {
|
||||||
|
isc_mem_put(res->mctx, res->dispatchv4pool,
|
||||||
|
sizeof(dns_dispatch_t *) * ndisps);
|
||||||
|
res->dispatchv4pool = NULL;
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
for (i = 0; i < ndisps; i++)
|
||||||
|
res->dispatchv6pool[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ndisps; i++) {
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL4) != 0) {
|
||||||
|
attrs = attrs_base;
|
||||||
|
attrs |= DNS_DISPATCHATTR_IPV4;
|
||||||
|
|
||||||
|
disp = NULL;
|
||||||
|
result = dns_dispatch_getudp(res->dispatchmgr,
|
||||||
|
res->socketmgr,
|
||||||
|
res->taskmgr, &addr4,
|
||||||
|
4096, 1000, 32768, 16411,
|
||||||
|
16433, attrs, attrmask,
|
||||||
|
&disp);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
res->dispatchv4pool[i] = disp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It might be better to ensure all ports are
|
||||||
|
* different, but in practice it's probably okay to
|
||||||
|
* assume dns_dispatch_getudp() made reasonable
|
||||||
|
* choices.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if ((res->options & DNS_RESOLVER_USEDISPATCHPOOL6) != 0) {
|
||||||
|
attrs = attrs_base;
|
||||||
|
attrs |= DNS_DISPATCHATTR_IPV6;
|
||||||
|
|
||||||
|
disp = NULL;
|
||||||
|
result = dns_dispatch_getudp(res->dispatchmgr,
|
||||||
|
res->socketmgr,
|
||||||
|
res->taskmgr, &addr6,
|
||||||
|
4096, 1000, 32768, 16411,
|
||||||
|
16433, attrs, attrmask,
|
||||||
|
&disp);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
res->dispatchv6pool[i] = disp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start update timer */
|
||||||
|
if (tick != 0) {
|
||||||
|
task = NULL;
|
||||||
|
result = isc_task_create(res->taskmgr, 0, &task);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
isc_interval_set(&interval, tick, 0);
|
||||||
|
result = isc_timer_create(res->timermgr, isc_timertype_ticker,
|
||||||
|
NULL, &interval, task,
|
||||||
|
disppooltimer_update,
|
||||||
|
res, &res->disppooltimer);
|
||||||
|
isc_task_detach(&task);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->ndisps = ndisps;
|
||||||
|
res->nextdisp = 0;
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for (i = 0; i < ndisps; i++) {
|
||||||
|
if (res->dispatchv4pool[i] != NULL)
|
||||||
|
dns_dispatch_detach(&res->dispatchv4pool[i]);
|
||||||
|
if (res->dispatchv6pool[i] != NULL)
|
||||||
|
dns_dispatch_detach(&res->dispatchv6pool[i]);
|
||||||
|
}
|
||||||
|
if (res->dispatchv4pool != NULL) {
|
||||||
|
isc_mem_put(res->mctx, res->dispatchv4pool,
|
||||||
|
sizeof(dns_dispatch_t *) * ndisps);
|
||||||
|
}
|
||||||
|
if (res->dispatchv6pool != NULL) {
|
||||||
|
isc_mem_put(res->mctx, res->dispatchv6pool,
|
||||||
|
sizeof(dns_dispatch_t *) * ndisps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: namedconf.c,v 1.72 2006/12/21 06:02:30 marka Exp $ */
|
/* $Id: namedconf.c,v 1.73 2007/02/02 02:18:06 marka Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@@ -790,6 +790,9 @@ view_clauses[] = {
|
|||||||
{ "empty-zones-enable", &cfg_type_boolean, 0 },
|
{ "empty-zones-enable", &cfg_type_boolean, 0 },
|
||||||
{ "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
|
{ "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
|
||||||
{ "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 },
|
{ "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 },
|
||||||
|
{ "use-queryport-pool", &cfg_type_boolean, 0 },
|
||||||
|
{ "queryport-pool-ports", &cfg_type_uint32, 0 },
|
||||||
|
{ "queryport-pool-updateinterval", &cfg_type_uint32, 0 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user