resolver.c revision 09ab38c151751b76b8043275422239463eb70cbd
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 1999-2003 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
7e4d75a5daeaaf8a7f559f9bd7fbf540184e235cMark Andrews * copyright notice and this permission notice appear in all copies.
823ca3c14f1596341bdd50707c01f3b529b75b4aAutomatic Updater * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * PERFORMANCE OF THIS SOFTWARE.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein "res %p: %s", (r), (m))
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater#define FCTXTRACE(m) isc_log_write(dns_lctx, \
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein "fctx %p(%s): %s %s", \
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein "fetch %p (fctx %p(%s)): %s", \
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein "resquery %p (fctx %p(%s)): %s", \
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * The maximum time we will wait for a single query.
37d266d288410d1ead241c02a8a1dbcb0160be46Michael Graff#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC)
37d266d288410d1ead241c02a8a1dbcb0160be46Michael Graff * We need to allow a individual query time to complete / timeout.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U)
d0783e645b149fcea7e7f22cd43f87b5d188b055Mark Andrews/* The default time in seconds for the whole query to live. */
d0783e645b149fcea7e7f22cd43f87b5d188b055Mark Andrews#define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence#define MAXIMUM_QUERY_TIMEOUT 30 /* The maximum time in seconds for the whole query to live. */
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater * Maximum EDNS0 input packet size.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater * This defines the maximum number of timeouts we will permit before we
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater * disable EDNS0 on the query.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewstypedef struct query {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /* Locked by task event serialization. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int sends;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int connects;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int udpsize;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int count;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!')
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
af9cfbc64363b61aa5903dd916e9fbc152084d4cMark Andrews#define RESQUERY_CONNECTING(q) ((q)->connects > 0)
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define RESQUERY_CANCELED(q) (((q)->attributes & \
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewstypedef enum {
ef22fffeebffacbcbce1f8d68d0c3f29a7d4a59eEvan Hunt fetchstate_init = 0, /*%< Start event has not run yet. */
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews fetchstate_done /*%< FETCHDONE events posted. */
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrencetypedef enum {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /*% Not locked. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int magic;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int options;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /*% Locked by appropriate bucket lock. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /*% Locked by task event serialization. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * The number of events we're waiting for.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int pending;
6add3af8397580475ab9fa10ac8c1269465cff87Mark Andrews * The number of times we've "restarted" the current
6add3af8397580475ab9fa10ac8c1269465cff87Mark Andrews * nameserver set. This acts as a failsafe to prevent
6add3af8397580475ab9fa10ac8c1269465cff87Mark Andrews * us from pounding constantly on a particular set of
6add3af8397580475ab9fa10ac8c1269465cff87Mark Andrews * servers that, for whatever reason, are not giving
8f80322fb58bac39c84bb76cb2bc82406bd6a9ecBrian Wellington * us useful responses, but are responding in such a
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * way that they are not marked "bad".
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int restarts;
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews * The number of timeouts that have occurred since we
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews * last successfully received a response packet. This
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews * is used for EDNS0 black hole detection.
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews unsigned int timeouts;
ef22fffeebffacbcbce1f8d68d0c3f29a7d4a59eEvan Hunt * Look aside state for DS lookups.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Number of queries that reference this context.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int nqueries;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * The reason to print when logging a successful
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * response to a query.
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews const char * reason;
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews * Random numbers to use for mixing up server addresses.
171d0db7f93bf796f870713d6208b21893401cfcBrian Wellington * Fetch-local statistics for detailed logging.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews isc_result_t vresult; /*%< validation result */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int neterr;
af9cfbc64363b61aa5903dd916e9fbc152084d4cMark Andrews unsigned int badresp;
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews unsigned int valfail;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
af9cfbc64363b61aa5903dd916e9fbc152084d4cMark Andrews#define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC)
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence#define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define SHUTTINGDOWN(f) (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \
5eb91bd90e3ad3426e5e3213031556a737cf3809Mark Andrews#define WANTCACHE(f) (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0)
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define WANTNCACHE(f) (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0)
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define NEEDEDNS0(f) (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0)
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)
5eb91bd90e3ad3426e5e3213031556a737cf3809Mark Andrewstypedef struct {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int magic;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence#define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h')
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence#define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrencetypedef struct fctxbucket {
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrencetypedef struct alternate {
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews unsigned int hashval;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30)
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews /* Unlocked. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int options;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int nbuckets;
ef22fffeebffacbcbce1f8d68d0c3f29a7d4a59eEvan Hunt /* Locked by lock. */
ef22fffeebffacbcbce1f8d68d0c3f29a7d4a59eEvan Hunt unsigned int references;
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews /* Bad cache. */
1cb73c69f76c8c2c66b767a8b9ad04f3988cf6a9Mark Andrews unsigned int badcount;
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews unsigned int badhash;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int badsweep;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /* Locked by primelock. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /* Locked by nlock. */
af9cfbc64363b61aa5903dd916e9fbc152084d4cMark Andrews unsigned int nfctx;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC)
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews * (0x008) which we also use as an addrinfo flag.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic isc_result_t resquery_send(resquery_t *query);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic void resquery_response(isc_task_t *task, isc_event_t *event);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic void resquery_connected(isc_task_t *task, isc_event_t *event);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic isc_boolean_t fctx_unlink(fetchctx_t *fctx);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic isc_result_t ncache_adderesult(dns_message_t *message,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsstatic void validated(isc_task_t *task, isc_event_t *event);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsstatic isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsstatic void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsstatic inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * Increment resolver-related statistics counters.
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updaterstatic inline void
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsinc_stats(dns_resolver_t *res, isc_statscounter_t counter) {
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews isc_stats_increment(res->view->resstats, counter);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsstatic inline void
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsdec_stats(dns_resolver_t *res, isc_statscounter_t counter) {
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews isc_stats_decrement(res->view->resstats, counter);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsvalcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews dns_rdatatype_t type, dns_rdataset_t *rdataset,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews dns_rdataset_t *sigrdataset, unsigned int valoptions,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews valarg = isc_mem_get(fctx->mctx, sizeof(*valarg));
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews result = dns_validator_create(fctx->res->view, name, type, rdataset,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews ISC_LIST_APPEND(fctx->validators, validator, link);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsrrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews unsigned int labels;
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsfix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * A DS RRset can appear anywhere in a zone, even for a delegation-only
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * zone. So a response to an explicit query for this type should be
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * excluded from delegation-only fixup.
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * SOA, NS, and DNSKEY can only exist at a zone apex, so a postive
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * response to a query for these types can never violate the
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * delegation-only assumption: if the query name is below a
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * zone cut, the response should normally be a referral, which should
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * be accepted; if the query name is below a zone cut but the server
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * happens to have authority for the zone of the query name, the
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * response is a (non-referral) answer. But this does not violate
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * delegation-only because the query name must be in a different zone
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * due to the "apex-only" nature of these types. Note that if the
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * remote server happens to have authority for a child zone of a
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * delegation-only zone, we may still incorrectly "fix" the response
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * with NXDOMAIN for queries for other types. Unfortunately it's
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * generally impossible to differentiate this case from violation of
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * the delegation-only assumption. Once the resolver learns the
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt * correct zone cut, possibly via a separate query for an "apex-only"
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt * type, queries for other types will be resolved correctly.
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt * A query for type ANY will be accepted if it hits an exceptional
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * type above in the answer section as it should be from a child
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * Also accept answers with RRSIG records from the child zone.
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * Direct queries for RRSIG records should not be answered from
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * the parent zone.
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater if (message->counts[DNS_SECTION_ANSWER] != 0 &&
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt result = dns_message_firstname(message, DNS_SECTION_ANSWER);
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews dns_message_currentname(message, DNS_SECTION_ANSWER,
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * RRsig from child?
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * Direct query for apex records or DS.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Indirect query for apex records or DS.
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * A NODATA response to a DS query?
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews /* Look for referral or indication of answer from child zone? */
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater if (message->counts[DNS_SECTION_AUTHORITY] == 0)
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
47ee25b1f58a5924c51b59194b84621b9b7b6ba5Mark Andrews dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /* NS or SOA records. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * If a query for ANY causes a negative
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * response, we can be sure that this is
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * an empty node. For other type of queries
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * we cannot differentiate an empty node
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * from a node that just doesn't have that
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * type of record. We only accept the former
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews if (message->counts[DNS_SECTION_ANSWER] == 0 &&
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews } else if (dns_name_issubdomain(name, domain)) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews /* Referral or answer from child zone. */
800fb35bf0c1cfcd82b542944b0d29e1837d8a09Automatic Updater result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews * Start the lifetime timer for fctx.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * This is also used for stopping the idle timer; in that
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * case we must purge events already posted to ensure that
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence * no further idle events are delivered.
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence return (isc_timer_reset(fctx->timer, isc_timertype_once,
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic inline void
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * We don't return a result if resetting the timer to inactive fails
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * since there's nothing to be done about it. Resetting to inactive
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * should never fail anyway, since the code as currently written
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * cannot fail in that case.
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews result = isc_timer_reset(fctx->timer, isc_timertype_inactive,
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews "isc_timer_reset(): %s",
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsfctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Start the idle timer for fctx. The lifetime timer continues
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews * to be in effect.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews return (isc_timer_reset(fctx->timer, isc_timertype_once,
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt * Stopping the idle timer is equivalent to calling fctx_starttimer(), but
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * we use fctx_stopidletimer for readability in the code below.
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrewsstatic inline void
bdb1394788a677d0b6e8499ba1ece17a73f476c7Mark Andrews isc_mem_put(query->mctx, query, sizeof(*query));
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsfctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews unsigned int factor;
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews isc_sockaddr_format(&query->addrinfo->sockaddr,
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Should we update the RTT?
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * We have both the start and finish times for this
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * packet, so we can compute a real RTT.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * We don't have an RTT for this query. Maybe the
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * packet was lost, or maybe this server is very
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * slow. We don't know. Increase the RTT.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence * Don't adjust timeout on EDNS queries unless we have
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * seen a EDNS response.
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt (query->addrinfo->flags & FCTX_ADDRINFO_EDNSOK) == 0) {
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Replace the current RTT with our value.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews /* Remember that the server has been tried. */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews dns_adb_changeflags(fctx->adb, query->addrinfo,
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt * Age RTTs of servers not tried.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Check for any outstanding socket events. If they exist, cancel
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * them and let the event handlers finish the cleanup. The resolver
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence * only needs to worry about managing the connect and send events;
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence * the dispatcher manages the recv events.
5236050c0f819b727dfc4850133f5194f346f76fDanny Mayer * Cancel the connect.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews socket = dns_dispatch_getentrysocket(query->dispentry);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Cancel the pending send.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews if (query->exclusivesocket && query->dispentry != NULL)
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrews socket = dns_dispatch_getentrysocket(query->dispentry);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews socket = dns_dispatch_getsocket(query->dispatch);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews dns_dispatch_removeresponse(&query->dispentry, deventp);
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query)))
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * It's safe to destroy the query now.
1a03b5e68553c37e9cc0097368909dfc37fb8cefMark Andrewsfctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff fctx_cancelquery(&query, NULL, NULL, no_response);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews ISC_LIST_UNLINK(fctx->altfinds, find, publink);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsstatic inline void
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsfctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) {
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graffstatic inline void
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrewsfctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
ca81c3971cd0c9cfd830c0a18289d4d1b0f9de01David Lawrence unsigned int count = 0;
45f36932943c02159a8907380fc79dd70e2184f1Evan Hunt unsigned int old_spillat;
45f36932943c02159a8907380fc79dd70e2184f1Evan Hunt unsigned int new_spillat = 0; /* initialized to silence
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson compiler warnings */
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Caller must be holding the appropriate bucket lock.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Keep some record of fetch result for logging later (if required).
d736db6dc53e615e3f2d66d1ddbe28473694d107Michael Graff fctx->duration = isc_time_microdiff(&now, &fctx->start);
d736db6dc53e615e3f2d66d1ddbe28473694d107Michael Graff ISC_LIST_UNLINK(fctx->events, event, ev_link);
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews * Negative results must be indicated in event->result.
7d2b275f7e9238e2c709737601f6260b5a9a4ee1Mark Andrews if (dns_rdataset_isassociated(event->rdataset) &&
347ccc2716b45b8c72a1021d7a74faab49d3eefaBrian Wellington INSIST(event->result == DNS_R_NCACHENXDOMAIN ||
count++;
&i, ISC_TRUE);
if (logit)
* isc_socket_sendto/connect() was in progress.
case ISC_R_SUCCESS:
case ISC_R_HOSTUNREACH:
case ISC_R_NETUNREACH:
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
case ISC_R_CONNREFUSED:
if (retry) {
static inline isc_result_t
return (result);
unsigned int seconds;
unsigned int us;
static isc_result_t
unsigned int options)
unsigned int srtt;
return (result);
goto stop_idle_timer;
int pf;
if (!have_addr) {
switch (pf) {
case PF_INET:
&addr);
case PF_INET6:
&addr);
goto cleanup_query;
goto cleanup_query;
#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
goto cleanup_socket;
if (have_addr) {
case AF_INET:
case AF_INET6:
goto cleanup_query;
goto cleanup_query;
case PF_INET:
case PF_INET6:
goto cleanup_query;
goto cleanup_socket;
goto cleanup_dispatch;
return (ISC_R_SUCCESS);
return (result);
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static struct tried *
return (tried);
return (NULL);
static struct tried *
return (tried);
return (NULL);
#ifdef ISC_PLATFORM_USESIT
#ifdef AES_SIT
case AF_INET:
case AF_INET6:
#ifdef HMAC_SHA1_SIT
case AF_INET:
case AF_INET6:
#ifdef HMAC_SHA256_SIT
case AF_INET:
case AF_INET6:
static isc_result_t
isc_region_t r;
unsigned ednsopt = 0;
goto cleanup_temps;
goto cleanup_temps;
task,
goto cleanup_temps;
if (secure_domain)
goto cleanup_message;
goto cleanup_message;
DNS_SECTION_QUESTION, 0);
goto cleanup_message;
!useedns)
#ifdef ISC_PLATFORM_USESIT
if (hint != 0U)
if (udpsize == 0U)
#ifdef ISC_PLATFORM_USESIT
#ifdef ISC_PLATFORM_USESIT
if (reqnsid) {
ednsopt++;
#ifdef ISC_PLATFORM_USESIT
if (reqsit) {
ednsopt++;
udpsize = 0;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
query);
goto cleanup_message;
if (connecting) {
goto cleanup_message;
return (ISC_R_SUCCESS);
if (cleanup_cctx)
return (result);
unsigned int attrs;
case ISC_R_SUCCESS:
attrs = 0;
case ISC_R_NETUNREACH:
case ISC_R_HOSTUNREACH:
case ISC_R_CONNREFUSED:
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
case ISC_R_CONNECTIONRESET:
if (retry) {
unsigned int bucketnum;
if (want_try)
else if (want_done)
else if (destroy) {
if (bucket_empty)
static inline isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static inline isc_boolean_t
return (all_bad);
isc_buffer_t b;
switch (badtype) {
case badns_unreachable:
case badns_response:
case badns_validation:
if (port != 0)
port);
static isc_boolean_t
int order;
unsigned int nlabels;
static isc_result_t
unsigned int stdoptions = 0;
return (DNS_R_SERVFAIL);
unsigned int labels;
return (result);
goto out;
return (result);
if (need_alternate) {
int family;
alternate_t *a;
a != NULL;
if (!a->isaddress) {
&ai, 0);
publink);
out:
if (all_bad) {
if (badcache &&
return (result);
int match;
match > 0)
if (aborted) {
static inline dns_adbaddrinfo_t *
return (addrinfo);
return (addrinfo);
return (addrinfo);
else if (retrying)
static isc_boolean_t
unsigned int bucketnum;
return (ISC_TRUE);
return (ISC_FALSE);
&cevent);
unsigned int bucketnum;
if (destroy) {
if (bucket_empty)
unsigned int bucketnum;
if (!done) {
} else if (destroy) {
if (bucket_empty)
static inline isc_result_t
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
static isc_result_t
unsigned int findoptions = 0;
return (ISC_R_NOMEMORY);
goto cleanup_fetch;
goto cleanup_info;
unsigned int labels;
NULL);
goto cleanup_name;
goto cleanup_name;
goto cleanup_name;
goto cleanup_name;
goto cleanup_domain;
goto cleanup_qmessage;
goto cleanup_rmessage;
goto cleanup_rmessage;
return (ISC_R_SUCCESS);
return (result);
static inline isc_boolean_t
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
int order;
unsigned int labels;
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
static inline isc_result_t
return (DNS_R_FORMERR);
return (result);
return (DNS_R_FORMERR);
return (ISC_R_SUCCESS);
static isc_boolean_t
unsigned int bucketnum;
if (!locked)
goto unlock;
if (!locked)
if (destroy)
return (bucket_empty);
unsigned options;
if (bucket_empty)
goto cleanup_event;
!negative &&
NULL,
NULL,
NULL);
0, NULL);
else if (sentresponse)
if (negative &&
if (negative) {
&node);
goto noanswer_response;
ttl = 0;
goto noanswer_response;
goto answer_response;
noqname);
goto noanswer_response;
options = 0;
goto noanswer_response;
goto noanswer_response;
if (sentresponse) {
if (bucket_empty)
goto cleanup_event;
goto cleanup_event;
&name);
&nsnode);
sigrdataset, 0,
NULL);
== ISC_R_SUCCESS);
static inline isc_result_t
unsigned int labels;
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (result);
fctx)))
if (!exists) {
return (result);
static inline isc_result_t
unsigned int options;
unsigned int valoptions = 0;
return (result);
!need_validation) {
return (result);
return (result);
sizeof(typebuf));
sizeof(classbuf));
if (fail) {
return (DNS_R_BADNAME);
* Cache this rdataset/sigrdataset pair as
options = 0;
&noqname);
tresult =
if (!need_validation &&
eresult =
eresult =
options = 0;
task);
return (result);
static inline isc_result_t
section++) {
&name);
return (result);
static isc_result_t
if (secure)
return (result);
static inline isc_result_t
unsigned int valoptions = 0;
return (result);
if (secure_domain) {
&tname);
return (result);
if (need_validation) {
return (result);
goto unlock;
goto unlock;
ttl = 0;
goto unlock;
return (result);
if (gluing) {
if (external)
static isc_result_t
return (ISC_R_SUCCESS);
gluing);
&rdataset);
gluing);
return (ISC_R_SUCCESS);
static isc_result_t
#ifndef CHECK_FOR_GLUE_IN_ANSWER
#define CHECK_FOR_GLUE_IN_ANSWER 0
static isc_result_t
&name);
fctx);
if (rescan)
goto again;
static inline isc_result_t
return (result);
return (result);
return (ISC_R_SUCCESS);
static inline isc_result_t
unsigned int nlabels;
int order;
return (result);
return (result);
return (DNS_R_FORMERR);
return (result);
static isc_boolean_t
int match;
return (ISC_TRUE);
return (ISC_TRUE);
sizeof(typebuf));
sizeof(classbuf));
return (ISC_FALSE);
return (ISC_TRUE);
static isc_boolean_t
return (ISC_TRUE);
return (ISC_TRUE);
return (ISC_TRUE);
sizeof(classbuf));
return (ISC_FALSE);
return (ISC_TRUE);
static isc_result_t
unsigned int look_in_options)
return (ISC_R_SUCCESS);
sizeof(tbuf));
sizeof(nbuf));
sizeof(qbuf));
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
if (aa)
return (result);
if (negative_response) {
if (aa)
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
if (aa)
return (result);
return (DNS_R_CHASEDSSERVERS);
return (ISC_R_SUCCESS);
return (DNS_R_FORMERR);
sizeof(tbuf));
sizeof(dbuf));
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
fctx);
return (result);
return (DNS_R_DELEGATION);
return (ISC_R_SUCCESS);
static isc_result_t
unsigned int aflag;
aflag = 0;
return (DNS_R_FORMERR);
rdataset)) {
return (DNS_R_SERVFAIL);
&& !found_cname) {
&& !found_type) {
return (DNS_R_FORMERR);
&tname);
return (result);
name,
&tname,
return (DNS_R_SERVFAIL);
&& !found_type) {
if (found) {
if (!chaining) {
if (aflag ==
if (aa)
} else if (external) {
(void)dns_rdataset_additionaldata(
fctx);
if (want_chaining) {
if (wanted_chaining)
aflag = 0;
return (DNS_R_FORMERR);
&dname);
return (result);
return (DNS_R_SERVFAIL);
if (found) {
if (!chaining) {
if (aflag ==
if (aa)
} else if (external) {
if (found_dname) {
NULL);
return (result);
&fqname);
if (wanted_chaining)
return (result);
if (!have_answer) {
return (DNS_R_FORMERR);
if (chaining) {
return (DNS_R_FORMERR);
if (!external) {
(void)dns_rdataset_additionaldata(
fctx);
return (result);
static isc_boolean_t
return (bucket_empty);
unsigned int bucketnum;
goto cleanup;
goto cleanup;
&nameservers);
if (!locked)
if (bucket_empty)
ISC_FALSE) ||
unsigned char *p, *nsid;
goto cleanup;
goto cleanup;
p = buf;
for (i = 0; i < nsid_len; i++) {
p = pbuf;
for (i = 0; i < nsid_len; i++) {
*p++ = nsid[i];
sizeof(addrbuf));
static isc_boolean_t
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
#ifdef ISC_PLATFORM_USESIT
unsigned char *sit;
switch (optcode) {
case DNS_OPT_NSID:
#ifdef ISC_PLATFORM_USESIT
case DNS_OPT_SIT:
unsigned int options;
unsigned int findoptions;
goto done;
goto done;
goto done;
goto done;
switch (result) {
case ISC_R_UNEXPECTEDEND:
goto done;
case DNS_R_FORMERR:
goto done;
goto done;
#ifdef notyet
#ifdef ISC_PLATFORM_USESIT
goto done;
goto done;
sizeof(addrbuf));
sizeof(addrbuf));
addrbuf);
if (truncated) {
goto done;
goto done;
case dns_rcode_nxdomain:
case dns_rcode_servfail:
case dns_rcode_formerr:
case dns_rcode_refused:
unsigned int version;
#ifdef ISC_PLATFORM_USESIT
switch (version) {
goto done;
goto done;
goto done;
sizeof(classbuf));
sizeof(addrbuf));
goto done;
goto force_referral;
goto done;
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_CHASEDSSERVERS:
case DNS_R_DELEGATION:
goto done;
goto done;
goto done;
done:
if (keep_trying) {
if (get_nameservers) {
findoptions = 0;
NULL);
} else if (resend) {
alternate_t *a;
if (!a->isaddress)
#if USE_ALGLOCK
#if USE_MBSLOCK
unsigned int count;
if (logit)
unsigned int options,
unsigned int i, buckets_created = 0;
unsigned dispattr;
return (ISC_R_NOMEMORY);
goto cleanup_res;
for (i = 0; i < ntasks; i++) {
goto cleanup_buckets;
goto cleanup_buckets;
#ifdef ISC_PLATFORM_USETHREADS
goto cleanup_buckets;
goto cleanup_dispatches;
goto cleanup_lock;
goto cleanup_nlock;
goto cleanup_primelock;
goto cleanup_primelock;
#if USE_ALGLOCK
goto cleanup_spillattimer;
#if USE_MBSLOCK
goto cleanup_alglock;
return (ISC_R_SUCCESS);
#if USE_MBSLOCK
#if USE_ALGLOCK
for (i = 0; i < buckets_created; i++) {
return (result);
if (want_priming) {
if (need_destroy)
static inline isc_boolean_t
unsigned int options)
return (ISC_FALSE);
return (ISC_FALSE);
unsigned int bucketnum;
unsigned int count = 0;
unsigned int spillat;
unsigned int spillatmin;
return (ISC_R_NOMEMORY);
goto unlock;
goto unlock;
count++;
goto unlock;
goto unlock;
if (new_fctx) {
if (destroy)
return (result);
unsigned int bucketnum;
if (bucket_empty)
alternate_t *a;
if (a == NULL)
return (ISC_R_NOMEMORY);
return (result);
return (ISC_R_SUCCESS);
goto unlock;
goto unlock;
unsigned int newsize;
if (grow)
unsigned int i, hashval;
goto cleanup;
goto cleanup;
goto unlock;
return (answer);
isc_uint64_t t;
goto unlock;
sizeof(typebuf));
#if USE_ALGLOCK
#if USE_ALGLOCK
unsigned int alg)
unsigned char *new;
unsigned char *algorithms;
return (ISC_R_RANGE);
#if USE_ALGLOCK
goto cleanup;
goto cleanup;
*algorithms);
#if USE_ALGLOCK
return (result);
unsigned int alg)
unsigned char *algorithms;
#if USE_ALGLOCK
goto unlock;
#if USE_ALGLOCK
if (found)
return (ISC_FALSE);
#if USE_ALGLOCK
#if USE_ALGLOCK
unsigned int digest_type)
unsigned char *new;
unsigned char *digests;
return (ISC_R_RANGE);
#if USE_ALGLOCK
goto cleanup;
goto cleanup;
*digests);
#if USE_ALGLOCK
return (result);
unsigned int digest_type)
unsigned char *digests;
#if USE_ALGLOCK
goto unlock;
#if USE_ALGLOCK
if (found)
return (ISC_FALSE);
#if USE_MBSLOCK
#if USE_MBSLOCK
#if USE_MBSLOCK
goto cleanup;
#if USE_MBSLOCK
return (result);
#if USE_MBSLOCK
goto unlock;
#if USE_MBSLOCK
return (value);
if (seconds == 0)