query.c revision 78838d3e0cd62423c23de5503910e01884d2104b
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * Copyright (C) 1999, 2000 Internet Software Consortium.
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * Permission to use, copy, modify, and distribute this software for any
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * purpose with or without fee is hereby granted, provided that the above
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * copyright notice and this permission notice appear in all copies.
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley/* $Id: query.c,v 1.161 2000/12/11 19:19:12 bwelling Exp $ */
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley#endif /* DNS_OPT_NEWCODES */
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley#define PARTIALANSWER(c) (((c)->query.attributes & \
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley#define RECURSIONOK(c) (((c)->query.attributes & \
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley#define CACHEGLUEOK(c) (((c)->query.attributes & \
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley#define WANTRECURSION(c) (((c)->query.attributes & \
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley#define CTRACE(m) ((void)m)
726290e9d5b720b736fa39d9f7d92c2efb7d1f24Bob Halley#define QTRACE(m) ((void)m)
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halleyquery_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halley dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halleystatic inline void
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halleyquery_adda6rrset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset,
f94f59d746daffc38356d0a019b64eb01d2341c0Bob Halleyquery_find(ns_client_t *client, dns_fetchevent_t *event);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * Increment query statistics counters.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleycount_query(dns_zone_t *zone, isc_boolean_t is_zone, dns_statscounter_t counter)
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley isc_uint64_t *zonestats = dns_zone_getstatscounters(zone);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleystatic inline void
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * client->query.qname was dynamically allocated.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleystatic inline void
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleyquery_reset(ns_client_t *client, isc_boolean_t everything) {
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley unsigned int i;
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * Reset the query state of a client to its default state.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * Cancel the fetch if it's running.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * Cleanup any active versions.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley dns_db_closeversion(dbversion->db, &dbversion->version,
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley ISC_LIST_INITANDAPPEND(client->query.freeversions,
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * Clean up free versions.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0;
38980568375a6505452550b5677104ab44291b66Bob Halley * If we're not freeing everything, we keep the first three
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * dbversions structures around.
38980568375a6505452550b5677104ab44291b66Bob Halley ISC_LIST_UNLINK(client->query.freeversions, dbversion,
19f08273e2592fa48608ec1ac5e021b4b3489030Bob Halley for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley ISC_LIST_UNLINK(client->query.namebufs, dbuf, link);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
38980568375a6505452550b5677104ab44291b66Bob Halley * Allocate a name buffer.
800b03baba638ddb3f67cc0d2ad2e70042fe8525Mark Andrews result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley CTRACE("query_newnamebuf: isc_buffer_allocate failed: done");
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleystatic inline isc_buffer_t *
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * Return a name buffer with space for a maximal name, allocating
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * a new one if necessary.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley CTRACE("query_getnamebuf: query_newnamebuf failed: done");
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley CTRACE("query_getnamebuf: query_newnamebuf failed: done");
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleystatic inline void
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleyquery_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * 'name' is using space in 'dbuf', but 'dbuf' has not yet been
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley * adjusted to take account of that. We do the adjustment.
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halley client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleystatic inline void
c56c5586b49ccddbaf7e2b5c6c06adee1c509253Bob Halleyquery_releasename(ns_client_t *client, dns_name_t **namep) {
38980568375a6505452550b5677104ab44291b66Bob Halley * 'name' is no longer needed. Return it to our pool of temporary
38980568375a6505452550b5677104ab44291b66Bob Halley * names. If it is using a name buffer, relinquish its exclusive
38980568375a6505452550b5677104ab44291b66Bob Halley * rights on the buffer.
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halley INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halley client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halleystatic inline dns_name_t *
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halleyquery_newname(ns_client_t *client, isc_buffer_t *dbuf,
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halley REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halley result = dns_message_gettempname(client->message, &name);
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halley CTRACE("query_newname: dns_message_gettempname failed: done");
08f8af2a42ddd2b87f1d67c09c0ba057b3253f29Bob Halley client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
e7dbdb25475cdca583dd41f053da2d7c53622b6cBob Halleystatic inline dns_rdataset_t *
0b16ae54f714bed65d749e3f601a29246cd98672Mark Andrews result = dns_message_gettemprdataset(client->message, &rdataset);
0b16ae54f714bed65d749e3f601a29246cd98672Mark Andrews "dns_message_gettemprdataset failed: done");
0358d65e0709c6e34876ec45f914d6e4f38ec241Mark Andrewsstatic inline void
0b16ae54f714bed65d749e3f601a29246cd98672Mark Andrewsquery_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
static inline isc_result_t
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
static inline ns_dbversion_t *
return (NULL);
return (dbversion);
return (result);
static inline ns_dbversion_t *
return (NULL);
return (dbversion);
static inline isc_result_t
unsigned int ztoptions;
DNS_ZTFIND_NOEXACT : 0;
&zone);
goto fail;
goto refuse;
goto fail;
if (new_zone) {
goto refuse;
NS_QUERYATTR_QUERYOKVALID) != 0) {
NS_QUERYATTR_QUERYOK) == 0)
goto refuse;
if (check_acl) {
goto refuse;
return (ISC_R_SUCCESS);
fail:
return (result);
static inline isc_result_t
return (DNS_R_REFUSED);
NS_QUERYATTR_QUERYOKVALID) != 0) {
NS_QUERYATTR_QUERYOK) == 0)
goto refuse;
if (check_acl) {
goto refuse;
return (ISC_R_SUCCESS);
return (result);
static inline isc_result_t
#ifdef DNS_OPT_NEWCODES_LIVE
versionp);
return (result);
static isc_result_t
unsigned int dboptions;
goto cleanup;
if (is_zone) {
goto db_find;
goto cleanup;
goto db_find;
return (result);
static inline isc_boolean_t
section++) {
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
isc_buffer_t b;
return (ISC_R_SUCCESS);
goto cleanup;
goto cleanup;
goto cleanup;
goto try_cache;
goto found;
goto try_glue;
goto found;
goto cleanup;
goto cleanup;
goto addname;
goto addname;
dns_rdatatype_a, 0,
goto addname;
goto addname;
goto addname;
dns_rdatatype_a6, 0,
goto addname;
goto addname;
goto addname;
goto addname;
if (!added_something)
goto cleanup;
if (need_addname)
client);
return (eresult);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
static inline isc_result_t
return (result);
goto cleanup;
goto cleanup;
if (zero_ttl) {
return (eresult);
static inline isc_result_t
return (result);
goto cleanup;
goto cleanup;
return (eresult);
static inline isc_result_t
isc_region_t r;
return (result);
return (result);
return (result);
return (ISC_R_SUCCESS);
isc_buffer_t b;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
if (is_zone) {
goto cleanup;
goto db_find;
goto cleanup;
if (use_zone) {
goto cleanup;
static inline isc_result_t
* Should get help with this from rdata.c
switch (type) {
case dns_rdatatype_tkey:
return (DNS_R_NOTIMP);
case dns_rdatatype_tsig:
return (DNS_R_FORMERR);
case dns_rdatatype_ixfr:
case dns_rdatatype_axfr:
case dns_rdatatype_mailb:
case dns_rdatatype_maila:
return (DNS_R_REFUSED);
return (ISC_R_SUCCESS);
static isc_result_t
return (result);
return (ISC_R_NOMEMORY);
return (ISC_R_NOMEMORY);
return (result);
static inline isc_result_t
goto cleanup;
if (!is_zone) {
goto cleanup;
return (result);
#define QUERY_ERROR(r) \
eresult = r; \
static isc_result_t
case dns_rdatatype_a:
return (ISC_R_SUCCESS);
case dns_rdatatype_aaaa:
return (ISC_R_SUCCESS);
return (ISC_R_NOTIMPLEMENTED);
return (INT_MAX);
return (INT_MAX);
case NS_SORTLISTTYPE_1ELEMENT:
case NS_SORTLISTTYPE_2ELEMENT:
case NS_SORTLISTTYPE_NONE:
INSIST(0);
int order;
isc_buffer_t b;
goto cleanup;
goto cleanup;
goto cleanup;
goto resume;
goto cleanup;
if (is_zone)
qtype = 0;
qcount = 0;
qcount++;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
is_zone &&
goto cleanup;
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_GLUE:
#ifdef DNS_OPT_NEWCODES_LIVE
case DNS_R_ZONECUT:
case ISC_R_NOTFOUND:
#ifdef DNS_OPT_NEWCODES_LIVE
goto cleanup;
case DNS_R_DELEGATION:
#ifdef DNS_OPT_NEWCODES_LIVE
if (is_zone) {
goto db_find;
&sigrdataset);
goto cleanup;
case DNS_R_NXRRSET:
goto cleanup;
&tname);
goto cleanup;
case DNS_R_NXDOMAIN:
goto cleanup;
goto cleanup;
&tname);
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
goto ncachenxrrset;
case DNS_R_NCACHENXRRSET:
goto cleanup;
case DNS_R_CNAME:
goto cleanup;
goto cleanup;
goto cleanup;
goto addauth;
case DNS_R_DNAME:
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto addauth;
goto cleanup;
goto cleanup;
goto cleanup;
if (!want_restart) {
if (is_zone) {
goto restart;
case dns_rdatatype_any:
case dns_rdatatype_ixfr:
case dns_rdatatype_axfr:
case dns_rdatatype_maila:
case dns_rdatatype_mailb:
case dns_rdatatype_tkey: