mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
support freezing; basic forwarding
This commit is contained in:
@@ -128,6 +128,60 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
* Anything else Failure.
|
* Anything else Failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_resolver_setforwarders(dns_resolver_t *res,
|
||||||
|
isc_sockaddrlist_t *forwarders);
|
||||||
|
/*
|
||||||
|
* Set the default forwarders to be used by the resolver.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* 'res' is a valid, unfrozen resolver.
|
||||||
|
*
|
||||||
|
* 'forwarders' is a valid nonempty list.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* ISC_R_SUCCESS
|
||||||
|
* ISC_R_NOMEMORY
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_resolver_setfwdpolicy(dns_resolver_t *res, dns_fwdpolicy_t fwdpolicy);
|
||||||
|
/*
|
||||||
|
* Set the default forwarding policy to be used by the resolver.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* 'res' is a valid, unfrozen resolver.
|
||||||
|
*
|
||||||
|
* 'fwdpolicy' is a valid dns_fwdpolicy_t.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*
|
||||||
|
* ISC_R_SUCCESS
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_resolver_freeze(dns_resolver_t *res);
|
||||||
|
/*
|
||||||
|
* Freeze resolver.
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* Certain configuration changes, e.g. setting forwarders,
|
||||||
|
* cannot be made after the resolver is frozen. Fetches
|
||||||
|
* cannot be created until the resolver is frozen.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* 'res' is a valid, unfrozen resolver.
|
||||||
|
*
|
||||||
|
* Ensures:
|
||||||
|
*
|
||||||
|
* 'res' is frozen.
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
|
dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
|
||||||
isc_event_t **eventp);
|
isc_event_t **eventp);
|
||||||
@@ -204,7 +258,7 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name,
|
|||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
* 'res' is a valid resolver.
|
* 'res' is a valid resolver that has been frozen.
|
||||||
*
|
*
|
||||||
* 'name' is a valid name.
|
* 'name' is a valid name.
|
||||||
*
|
*
|
||||||
@@ -241,6 +295,12 @@ dns_resolver_cancelfetch(dns_resolver_t *res, dns_fetch_t *fetch);
|
|||||||
*
|
*
|
||||||
* If 'fetch' has not completed, post its FETCHDONE event with a
|
* If 'fetch' has not completed, post its FETCHDONE event with a
|
||||||
* result code of ISC_R_CANCELED.
|
* result code of ISC_R_CANCELED.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* 'res' is a valid resolver that has been frozen.
|
||||||
|
*
|
||||||
|
* 'fetch' is a valid fetch.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -250,6 +310,10 @@ dns_resolver_destroyfetch(dns_resolver_t *res, dns_fetch_t **fetchp);
|
|||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
|
* 'res' is a valid resolver that has been frozen.
|
||||||
|
*
|
||||||
|
* '*fetchp' is a valid fetch.
|
||||||
|
*
|
||||||
* The caller has received the FETCHDONE event (either because the
|
* The caller has received the FETCHDONE event (either because the
|
||||||
* fetch completed or because dns_resolver_cancelfetch() was called).
|
* fetch completed or because dns_resolver_cancelfetch() was called).
|
||||||
*
|
*
|
||||||
|
@@ -154,6 +154,8 @@ struct fetchctx {
|
|||||||
ISC_LIST(resquery_t) queries;
|
ISC_LIST(resquery_t) queries;
|
||||||
dns_adbfindlist_t finds;
|
dns_adbfindlist_t finds;
|
||||||
dns_adbfind_t * find;
|
dns_adbfind_t * find;
|
||||||
|
dns_adbaddrinfolist_t forwaddrs;
|
||||||
|
isc_sockaddrlist_t forwarders;
|
||||||
/*
|
/*
|
||||||
* # of events we're waiting for.
|
* # of events we're waiting for.
|
||||||
*/
|
*/
|
||||||
@@ -209,23 +211,36 @@ struct dns_resolver {
|
|||||||
isc_socketmgr_t * socketmgr;
|
isc_socketmgr_t * socketmgr;
|
||||||
isc_timermgr_t * timermgr;
|
isc_timermgr_t * timermgr;
|
||||||
dns_view_t * view;
|
dns_view_t * view;
|
||||||
/* Locked by lock. */
|
isc_boolean_t frozen;
|
||||||
unsigned int references;
|
isc_sockaddrlist_t forwarders;
|
||||||
isc_boolean_t exiting;
|
dns_fwdpolicy_t fwdpolicy;
|
||||||
isc_eventlist_t whenshutdown;
|
|
||||||
isc_socket_t * udpsocket4;
|
isc_socket_t * udpsocket4;
|
||||||
isc_socket_t * udpsocket6;
|
isc_socket_t * udpsocket6;
|
||||||
dns_dispatch_t * dispatch4;
|
dns_dispatch_t * dispatch4;
|
||||||
dns_dispatch_t * dispatch6;
|
dns_dispatch_t * dispatch6;
|
||||||
unsigned int nbuckets;
|
unsigned int nbuckets;
|
||||||
unsigned int activebuckets;
|
|
||||||
fctxbucket_t * buckets;
|
fctxbucket_t * buckets;
|
||||||
|
/* Locked by lock. */
|
||||||
|
unsigned int references;
|
||||||
|
isc_boolean_t exiting;
|
||||||
|
isc_eventlist_t whenshutdown;
|
||||||
|
unsigned int activebuckets;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RES_MAGIC 0x52657321U /* Res! */
|
#define RES_MAGIC 0x52657321U /* Res! */
|
||||||
#define VALID_RESOLVER(res) ((res) != NULL && \
|
#define VALID_RESOLVER(res) ((res) != NULL && \
|
||||||
(res)->magic == RES_MAGIC)
|
(res)->magic == RES_MAGIC)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0,
|
||||||
|
* which we also use as an addrinfo flag.
|
||||||
|
*/
|
||||||
|
#define FCTX_ADDRINFO_MARK 0x0001
|
||||||
|
#define FCTX_ADDRINFO_FORWARDER 0x1000
|
||||||
|
#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
|
||||||
|
== 0)
|
||||||
|
#define ISFORWARDER(a) (((a)->flags & \
|
||||||
|
FCTX_ADDRINFO_FORWARDER) != 0)
|
||||||
|
|
||||||
static void destroy(dns_resolver_t *res);
|
static void destroy(dns_resolver_t *res);
|
||||||
static void empty_bucket(dns_resolver_t *res);
|
static void empty_bucket(dns_resolver_t *res);
|
||||||
@@ -384,11 +399,27 @@ fctx_cleanupfinds(fetchctx_t *fctx) {
|
|||||||
fctx->find = NULL;
|
fctx->find = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fctx_cleanupforwaddrs(fetchctx_t *fctx) {
|
||||||
|
dns_adbaddrinfo_t *addr, *next_addr;
|
||||||
|
|
||||||
|
REQUIRE(ISC_LIST_EMPTY(fctx->queries));
|
||||||
|
|
||||||
|
for (addr = ISC_LIST_HEAD(fctx->forwaddrs);
|
||||||
|
addr != NULL;
|
||||||
|
addr = next_addr) {
|
||||||
|
next_addr = ISC_LIST_NEXT(addr, publink);
|
||||||
|
ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
|
||||||
|
dns_adb_freeaddrinfo(fctx->res->view->adb, &addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
fctx_stopeverything(fetchctx_t *fctx) {
|
fctx_stopeverything(fetchctx_t *fctx) {
|
||||||
FCTXTRACE("stopeverything");
|
FCTXTRACE("stopeverything");
|
||||||
fctx_cancelqueries(fctx, ISC_FALSE);
|
fctx_cancelqueries(fctx, ISC_FALSE);
|
||||||
fctx_cleanupfinds(fctx);
|
fctx_cleanupfinds(fctx);
|
||||||
|
fctx_cleanupforwaddrs(fctx);
|
||||||
fctx_stoptimer(fctx);
|
fctx_stoptimer(fctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,8 +767,15 @@ resquery_send(resquery_t *query) {
|
|||||||
dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
|
dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
|
||||||
ISC_LIST_APPEND(qname->list, qrdataset, link);
|
ISC_LIST_APPEND(qname->list, qrdataset, link);
|
||||||
dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
|
dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
|
||||||
if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0)
|
|
||||||
|
/*
|
||||||
|
* Set RD if the client has requested that we do a recursive query,
|
||||||
|
* or if we're sending to a forwarder.
|
||||||
|
*/
|
||||||
|
if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 ||
|
||||||
|
ISFORWARDER(query->addrinfo))
|
||||||
fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
|
fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't have to set opcode because it defaults to query.
|
* We don't have to set opcode because it defaults to query.
|
||||||
*/
|
*/
|
||||||
@@ -1015,6 +1053,8 @@ fctx_getaddresses(fetchctx_t *fctx) {
|
|||||||
isc_stdtime_t now;
|
isc_stdtime_t now;
|
||||||
dns_adbfind_t *find;
|
dns_adbfind_t *find;
|
||||||
unsigned int stdoptions, options;
|
unsigned int stdoptions, options;
|
||||||
|
isc_sockaddr_t *sa;
|
||||||
|
dns_adbaddrinfo_t *ai;
|
||||||
|
|
||||||
FCTXTRACE("getaddresses");
|
FCTXTRACE("getaddresses");
|
||||||
|
|
||||||
@@ -1026,6 +1066,43 @@ fctx_getaddresses(fetchctx_t *fctx) {
|
|||||||
return (DNS_R_SERVFAIL);
|
return (DNS_R_SERVFAIL);
|
||||||
|
|
||||||
res = fctx->res;
|
res = fctx->res;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forwarders.
|
||||||
|
*/
|
||||||
|
|
||||||
|
INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this fctx has forwarders, use them; otherwise the use
|
||||||
|
* resolver's forwarders (if any).
|
||||||
|
*/
|
||||||
|
sa = ISC_LIST_HEAD(fctx->forwarders);
|
||||||
|
if (sa == NULL)
|
||||||
|
sa = ISC_LIST_HEAD(res->forwarders);
|
||||||
|
|
||||||
|
while (sa != NULL) {
|
||||||
|
ai = NULL;
|
||||||
|
result = dns_adb_findaddrinfo(fctx->res->view->adb,
|
||||||
|
sa, &ai);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
ai->flags |= FCTX_ADDRINFO_FORWARDER;
|
||||||
|
ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
|
||||||
|
}
|
||||||
|
sa = ISC_LIST_NEXT(sa, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the forwarding policy is "only", we don't need the addresses
|
||||||
|
* of the nameservers.
|
||||||
|
*/
|
||||||
|
if (res->fwdpolicy == dns_fwdpolicy_only)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal nameservers.
|
||||||
|
*/
|
||||||
|
|
||||||
stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT |
|
stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT |
|
||||||
DNS_ADBFIND_AVOIDFETCHES;
|
DNS_ADBFIND_AVOIDFETCHES;
|
||||||
if (res->dispatch4 != NULL)
|
if (res->dispatch4 != NULL)
|
||||||
@@ -1105,23 +1182,35 @@ fctx_getaddresses(fetchctx_t *fctx) {
|
|||||||
if (result != DNS_R_NOMORE)
|
if (result != DNS_R_NOMORE)
|
||||||
return (result);
|
return (result);
|
||||||
|
|
||||||
if (ISC_LIST_EMPTY(fctx->finds) && fctx->pending > 0) {
|
out:
|
||||||
|
if (ISC_LIST_EMPTY(fctx->finds) && ISC_LIST_EMPTY(fctx->forwaddrs)) {
|
||||||
/*
|
/*
|
||||||
* We're fetching the addresses, but don't have any yet.
|
* We've got no addresses.
|
||||||
* Tell the caller to wait for an answer.
|
|
||||||
*/
|
*/
|
||||||
result = DNS_R_WAIT;
|
if (fctx->pending > 0) {
|
||||||
} else if (ISC_LIST_EMPTY(fctx->finds)) {
|
/*
|
||||||
/*
|
* We're fetching the addresses, but don't have any
|
||||||
* We've lost completely. We don't know any addresses, and
|
* yet. Tell the caller to wait for an answer.
|
||||||
* the ADB has told us it can't get them.
|
*/
|
||||||
*/
|
result = DNS_R_WAIT;
|
||||||
result = ISC_R_FAILURE;
|
} else {
|
||||||
|
/*
|
||||||
|
* We've lost completely. We don't know any
|
||||||
|
* addresses, and the ADB has told us it can't get
|
||||||
|
* them.
|
||||||
|
*/
|
||||||
|
result = ISC_R_FAILURE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We've found some addresses. We might still be looking
|
* We've found some addresses. We might still be looking
|
||||||
* for more addresses.
|
* for more addresses.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* XXXRTH We could sort the forwaddrs here if the caller
|
||||||
|
* wants to use the forwaddrs in "best order" as
|
||||||
|
* opposed to "fixed order".
|
||||||
|
*/
|
||||||
sort_finds(fctx);
|
sort_finds(fctx);
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1129,10 +1218,6 @@ fctx_getaddresses(fetchctx_t *fctx) {
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FCTX_ADDRINFO_MARK 0x01
|
|
||||||
#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
|
|
||||||
== 0)
|
|
||||||
|
|
||||||
static inline dns_adbaddrinfo_t *
|
static inline dns_adbaddrinfo_t *
|
||||||
fctx_nextaddress(fetchctx_t *fctx) {
|
fctx_nextaddress(fetchctx_t *fctx) {
|
||||||
dns_adbfind_t *find;
|
dns_adbfind_t *find;
|
||||||
@@ -1143,7 +1228,20 @@ fctx_nextaddress(fetchctx_t *fctx) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move to the next find.
|
* Find the first unmarked forwarder (if any).
|
||||||
|
*/
|
||||||
|
for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
|
||||||
|
addrinfo != NULL;
|
||||||
|
addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
|
||||||
|
if (UNMARKED(addrinfo)) {
|
||||||
|
addrinfo->flags |= FCTX_ADDRINFO_MARK;
|
||||||
|
fctx->find = NULL;
|
||||||
|
return (addrinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No forwarders. Move to the next find.
|
||||||
*/
|
*/
|
||||||
find = fctx->find;
|
find = fctx->find;
|
||||||
if (find == NULL)
|
if (find == NULL)
|
||||||
@@ -1199,6 +1297,7 @@ fctx_try(fetchctx_t *fctx) {
|
|||||||
*/
|
*/
|
||||||
fctx_cancelqueries(fctx, ISC_TRUE);
|
fctx_cancelqueries(fctx, ISC_TRUE);
|
||||||
fctx_cleanupfinds(fctx);
|
fctx_cleanupfinds(fctx);
|
||||||
|
fctx_cleanupforwaddrs(fctx);
|
||||||
result = fctx_getaddresses(fctx);
|
result = fctx_getaddresses(fctx);
|
||||||
if (result == DNS_R_WAIT) {
|
if (result == DNS_R_WAIT) {
|
||||||
/*
|
/*
|
||||||
@@ -1519,6 +1618,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
fctx->want_shutdown = ISC_FALSE;
|
fctx->want_shutdown = ISC_FALSE;
|
||||||
ISC_LIST_INIT(fctx->queries);
|
ISC_LIST_INIT(fctx->queries);
|
||||||
ISC_LIST_INIT(fctx->finds);
|
ISC_LIST_INIT(fctx->finds);
|
||||||
|
ISC_LIST_INIT(fctx->forwaddrs);
|
||||||
|
ISC_LIST_INIT(fctx->forwarders);
|
||||||
fctx->find = NULL;
|
fctx->find = NULL;
|
||||||
fctx->pending = 0;
|
fctx->pending = 0;
|
||||||
fctx->validating = 0;
|
fctx->validating = 0;
|
||||||
@@ -3111,6 +3212,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
}
|
}
|
||||||
fctx_cancelqueries(fctx, ISC_TRUE);
|
fctx_cancelqueries(fctx, ISC_TRUE);
|
||||||
fctx_cleanupfinds(fctx);
|
fctx_cleanupfinds(fctx);
|
||||||
|
fctx_cleanupforwaddrs(fctx);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Try again.
|
* Try again.
|
||||||
@@ -3146,6 +3248,19 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
*** Resolver Methods
|
*** Resolver Methods
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_forwarders(dns_resolver_t *res) {
|
||||||
|
isc_sockaddr_t *sa, *next_sa;
|
||||||
|
|
||||||
|
for (sa = ISC_LIST_HEAD(res->forwarders);
|
||||||
|
sa != NULL;
|
||||||
|
sa = next_sa) {
|
||||||
|
next_sa = ISC_LIST_NEXT(sa, link);
|
||||||
|
ISC_LIST_UNLINK(res->forwarders, sa, link);
|
||||||
|
isc_mem_put(res->mctx, sa, sizeof *sa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy(dns_resolver_t *res) {
|
destroy(dns_resolver_t *res) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@@ -3171,6 +3286,7 @@ destroy(dns_resolver_t *res) {
|
|||||||
dns_dispatch_detach(&res->dispatch6);
|
dns_dispatch_detach(&res->dispatch6);
|
||||||
if (res->udpsocket6 != NULL)
|
if (res->udpsocket6 != NULL)
|
||||||
isc_socket_detach(&res->udpsocket6);
|
isc_socket_detach(&res->udpsocket6);
|
||||||
|
free_forwarders(res);
|
||||||
res->magic = 0;
|
res->magic = 0;
|
||||||
isc_mem_put(res->mctx, res, sizeof *res);
|
isc_mem_put(res->mctx, res, sizeof *res);
|
||||||
}
|
}
|
||||||
@@ -3323,9 +3439,16 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_udpsocket6;
|
goto cleanup_udpsocket6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forwarding.
|
||||||
|
*/
|
||||||
|
ISC_LIST_INIT(res->forwarders);
|
||||||
|
res->fwdpolicy = dns_fwdpolicy_none;
|
||||||
|
|
||||||
res->references = 1;
|
res->references = 1;
|
||||||
res->exiting = ISC_FALSE;
|
res->exiting = ISC_FALSE;
|
||||||
|
res->frozen = ISC_FALSE;
|
||||||
ISC_LIST_INIT(res->whenshutdown);
|
ISC_LIST_INIT(res->whenshutdown);
|
||||||
|
|
||||||
result = isc_mutex_init(&res->lock);
|
result = isc_mutex_init(&res->lock);
|
||||||
@@ -3369,6 +3492,68 @@ dns_resolver_create(dns_view_t *view,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_resolver_setforwarders(dns_resolver_t *res,
|
||||||
|
isc_sockaddrlist_t *forwarders)
|
||||||
|
{
|
||||||
|
isc_sockaddr_t *sa, *nsa;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the default forwarders to be used by the resolver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(!res->frozen);
|
||||||
|
REQUIRE(!ISC_LIST_EMPTY(*forwarders));
|
||||||
|
|
||||||
|
if (!ISC_LIST_EMPTY(res->forwarders))
|
||||||
|
free_forwarders(res);
|
||||||
|
|
||||||
|
for (sa = ISC_LIST_HEAD(*forwarders);
|
||||||
|
sa != NULL;
|
||||||
|
sa = ISC_LIST_NEXT(sa, link)) {
|
||||||
|
nsa = isc_mem_get(res->mctx, sizeof *nsa);
|
||||||
|
if (nsa == NULL) {
|
||||||
|
free_forwarders(res);
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
/* XXXRTH Create and use isc_sockaddr_copy(). */
|
||||||
|
*nsa = *sa;
|
||||||
|
ISC_LINK_INIT(nsa, link);
|
||||||
|
ISC_LIST_APPEND(res->forwarders, nsa, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_resolver_setfwdpolicy(dns_resolver_t *res, dns_fwdpolicy_t fwdpolicy) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the default forwarding policy to be used by the resolver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(!res->frozen);
|
||||||
|
|
||||||
|
res->fwdpolicy = fwdpolicy;
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_resolver_freeze(dns_resolver_t *res) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Freeze resolver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(!res->frozen);
|
||||||
|
|
||||||
|
res->frozen = ISC_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
|
dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
|
||||||
REQUIRE(VALID_RESOLVER(source));
|
REQUIRE(VALID_RESOLVER(source));
|
||||||
@@ -3562,6 +3747,7 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name,
|
|||||||
(void)forwarders;
|
(void)forwarders;
|
||||||
|
|
||||||
REQUIRE(VALID_RESOLVER(res));
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(res->frozen);
|
||||||
/* XXXRTH Check for meta type */
|
/* XXXRTH Check for meta type */
|
||||||
REQUIRE(DNS_RDATASET_VALID(nameservers));
|
REQUIRE(DNS_RDATASET_VALID(nameservers));
|
||||||
REQUIRE(forwarders == NULL);
|
REQUIRE(forwarders == NULL);
|
||||||
@@ -3646,6 +3832,8 @@ dns_resolver_cancelfetch(dns_resolver_t *res, dns_fetch_t *fetch) {
|
|||||||
dns_fetchevent_t *event, *next_event;
|
dns_fetchevent_t *event, *next_event;
|
||||||
isc_task_t *etask;
|
isc_task_t *etask;
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(res->frozen);
|
||||||
REQUIRE(DNS_FETCH_VALID(fetch));
|
REQUIRE(DNS_FETCH_VALID(fetch));
|
||||||
fctx = fetch->private;
|
fctx = fetch->private;
|
||||||
|
|
||||||
@@ -3684,6 +3872,8 @@ dns_resolver_destroyfetch(dns_resolver_t *res, dns_fetch_t **fetchp) {
|
|||||||
unsigned int bucketnum;
|
unsigned int bucketnum;
|
||||||
isc_boolean_t bucket_empty = ISC_FALSE;
|
isc_boolean_t bucket_empty = ISC_FALSE;
|
||||||
|
|
||||||
|
REQUIRE(VALID_RESOLVER(res));
|
||||||
|
REQUIRE(res->frozen);
|
||||||
REQUIRE(fetchp != NULL);
|
REQUIRE(fetchp != NULL);
|
||||||
fetch = *fetchp;
|
fetch = *fetchp;
|
||||||
REQUIRE(DNS_FETCH_VALID(fetch));
|
REQUIRE(DNS_FETCH_VALID(fetch));
|
||||||
|
Reference in New Issue
Block a user