query.c revision c631ff56bfe13f7b47ff01950364f4db423bf21a
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * Copyright (C) 1999-2003 Internet Software Consortium.
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * purpose with or without fee is hereby granted, provided that the above
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * copyright notice and this permission notice appear in all copies.
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
475b1ed9cced1f92ce34bc2e59b3065dae48f366Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
NS_QUERYATTR_PARTIALANSWER) != 0)
NS_QUERYATTR_CACHEOK) != 0)
NS_QUERYATTR_RECURSIONOK) != 0)
NS_QUERYATTR_RECURSING) != 0)
NS_QUERYATTR_CACHEGLUEOK) != 0)
NS_QUERYATTR_WANTRECURSION) != 0)
NS_CLIENTATTR_WANTDNSSEC) != 0)
NS_CLIENTATTR_WANTAD) != 0)
NS_CLIENTATTR_HAVECOOKIE) != 0)
NS_CLIENTATTR_WANTCOOKIE) != 0)
NS_QUERYATTR_NOAUTHORITY) != 0)
NS_QUERYATTR_NOADDITIONAL) != 0)
NS_QUERYATTR_SECURE) != 0)
NS_QUERYATTR_DNS64) != 0)
NS_QUERYATTR_DNS64EXCLUDE) != 0)
NS_QUERYATTR_REDIRECT) != 0)
DNS_RDATASETATTR_NOQNAME) != 0)
#ifdef WANT_QUERYTRACE
#define CTRACE(l,m) do { \
client, (m)); \
#define CTRACE(l,m) ((void)m)
typedef struct client_additionalctx {
static isc_result_t
static isc_boolean_t
static isc_boolean_t
switch (result) {
case DNS_R_SERVFAIL:
case DNS_R_FORMERR:
link);
sizeof(*dbversion));
sizeof(isc_boolean_t));
if (everything) {
static inline isc_result_t
return (result);
return (ISC_R_SUCCESS);
static inline isc_buffer_t *
isc_region_t r;
return (NULL);
return (NULL);
return (dbuf);
isc_region_t r;
static inline dns_name_t *
isc_region_t r;
return (NULL);
return (name);
static inline dns_rdataset_t *
return (NULL);
return (rdataset);
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);
return (result);
return (result);
static inline ns_dbversion_t *
return (NULL);
return (dbversion);
static inline isc_result_t
return (DNS_R_REFUSED);
return (DNS_R_REFUSED);
return (DNS_R_SERVFAIL);
goto approved;
return (DNS_R_REFUSED);
goto approved;
NS_QUERYATTR_QUERYOKVALID) != 0) {
NS_QUERYATTR_QUERYOK) == 0) {
return (DNS_R_REFUSED);
goto approved;
return (DNS_R_REFUSED);
return (ISC_R_SUCCESS);
static inline isc_result_t
unsigned int ztoptions;
DNS_ZTFIND_NOEXACT : 0;
&zone);
goto fail;
versionp);
goto fail;
return (DNS_R_PARTIALMATCH);
return (ISC_R_SUCCESS);
fail:
return (result);
const char *failed;
static isc_result_t
sizeof(qnamebuf));
return (ISC_R_SUCCESS);
return (result);
static inline isc_result_t
return (DNS_R_REFUSED);
goto refuse;
if (check_acl) {
ISC_TRUE);
} else if (log) {
sizeof(msg));
goto refuse;
return (ISC_R_SUCCESS);
return (result);
static inline isc_result_t
unsigned int namelabels;
unsigned int zonelabels;
zonelabels = 0;
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 cleanup;
goto found;
goto cleanup;
goto cleanup;
goto cleanup;
#ifdef ALLOW_FILTER_AAAA
goto addname;
goto addname;
goto aaaa_lookup;
dns_rdatatype_a, 0,
goto addname;
#ifdef ALLOW_FILTER_AAAA
goto addname;
goto addname;
goto addname;
goto addname;
#ifdef ALLOW_FILTER_AAAA
if (have_a &&
goto addname;
if (!added_something)
goto cleanup;
if (need_addname)
client);
return (eresult);
static inline isc_result_t
return (result);
goto cleanup;
return (result);
static isc_result_t
isc_buffer_t b;
goto cleanup;
goto cleanup;
goto findauthdb;
goto try_cache;
&cfname);
goto findauthdb;
goto try_cache;
&cfname);
goto try_cache;
goto foundcache;
NULL);
goto try_cache;
goto found;
goto try_glue;
goto found;
goto cleanup;
goto cleanup;
goto findglue;
&cfname);
goto findglue;
goto cleanup;
goto foundcache;
fname);
goto cleanup;
goto cleanup;
goto cleanup;
goto aaaa_lookup;
goto setcache;
goto foundcache;
goto foundcache;
&cfname);
&mname)) {
if (!added_something)
goto cleanup;
if (need_addname)
return (eresult);
static isc_result_t
isc_region_t r;
unsigned int flags = 0;
return (ISC_R_SUCCESS);
goto cleanup;
goto cleanup;
goto cleanup;
&dns64_rdata);
goto cleanup;
dns_rdatatype_aaaa, &r);
link);
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
isc_region_t r;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
dns_rdatatype_aaaa, &r);
goto cleanup;
goto cleanup;
static inline isc_result_t
return (ISC_R_SUCCESS);
return (result);
goto cleanup;
goto cleanup;
goto cleanup;
section);
return (eresult);
static inline isc_result_t
return (result);
goto cleanup;
goto cleanup;
return (eresult);
static isc_result_t
isc_region_t r;
return (result);
return (result);
return (result);
return (result);
return (result);
== ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
0, NULL);
0, NULL);
static isc_boolean_t
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
isc_buffer_t b;
return (secure);
static isc_boolean_t
goto again;
return (ISC_TRUE);
return (ISC_FALSE);
static isc_boolean_t
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
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;
goto cleanup;
* If the answer is secure only add NS records if they are secure * when the client may be looking for AD in the response.
goto cleanup;
unsigned int count;
goto cleanup;
goto addnsec3;
goto addnsec3;
goto cleanup;
&rname);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
unsigned int options;
int order;
goto cleanup;
goto cleanup;
if (labels == 0U)
goto cleanup;
goto cleanup;
if (!ispositive)
goto cleanup;
goto cleanup;
goto cleanup;
if (ispositive)
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
if (!ispositive)
&olabels);
&nlabels);
goto cleanup;
if (have_wname) {
goto again;
unsigned int labels;
int errorloglevel;
if (fetch_canceled) {
unsigned int options;
static isc_result_t
if (!resuming)
return (result);
return (ISC_R_NOMEMORY);
return (ISC_R_NOMEMORY);
return (result);
static inline isc_result_t
return (DNS_R_SERVFAIL);
return (ISC_R_SUCCESS);
static dns_rpz_zbits_t
switch (rpz_type) {
case DNS_RPZ_TYPE_CLIENT_IP:
case DNS_RPZ_TYPE_QNAME:
case DNS_RPZ_TYPE_IP:
case DNS_RPZ_TYPE_NSDNAME:
case DNS_RPZ_TYPE_NSIP:
INSIST(0);
return (zbits);
static isc_result_t
return (result);
return (result);
return (result);
return (result);
static isc_result_t
switch (rpz_type) {
case DNS_RPZ_TYPE_CLIENT_IP:
case DNS_RPZ_TYPE_QNAME:
case DNS_RPZ_TYPE_IP:
case DNS_RPZ_TYPE_NSDNAME:
case DNS_RPZ_TYPE_NSIP:
INSIST(0);
first = 0;
&prefix);
return (ISC_R_FAILURE);
if (first == 0) {
++first;
return (ISC_R_SUCCESS);
static isc_result_t
return (DNS_R_SERVFAIL);
return (DNS_R_NXDOMAIN);
&rdsiter);
return (DNS_R_SERVFAIL);
return (DNS_R_SERVFAIL);
* Ask again to get the right DNS_R_DNAME/NXRRSET/...
switch (result) {
case ISC_R_SUCCESS:
return (DNS_R_CNAME);
return (ISC_R_SUCCESS);
case DNS_R_NXRRSET:
return (result);
case DNS_R_DNAME:
case DNS_R_NXDOMAIN:
case DNS_R_EMPTYNAME:
return (DNS_R_NXDOMAIN);
return (DNS_R_SERVFAIL);
static isc_result_t
while (zbits != 0) {
switch (result) {
case DNS_R_NXDOMAIN:
case DNS_R_SERVFAIL:
return (DNS_R_SERVFAIL);
return (ISC_R_SUCCESS);
static isc_result_t
if (zbits == 0)
return (ISC_R_SUCCESS);
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_GLUE:
case DNS_R_ZONECUT:
case DNS_R_EMPTYNAME:
case DNS_R_EMPTYWILD:
case DNS_R_NXDOMAIN:
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NXRRSET:
case DNS_R_NCACHENXRRSET:
case ISC_R_NOTFOUND:
return (ISC_R_SUCCESS);
case DNS_R_DELEGATION:
case DNS_R_DUPLICATE:
case DNS_R_DROP:
return (result);
case DNS_R_CNAME:
case DNS_R_DNAME:
return (ISC_R_SUCCESS);
result);
return (DNS_R_SERVFAIL);
case dns_rdatatype_a:
case dns_rdatatype_aaaa:
return (result);
return (ISC_R_SUCCESS);
static isc_result_t
return (result);
static isc_result_t
if (zbits == 0)
return (ISC_R_SUCCESS);
if (zbits == 0)
return (ISC_R_SUCCESS);
switch (result) {
case DNS_R_NXDOMAIN:
case DNS_R_SERVFAIL:
return (DNS_R_SERVFAIL);
* st->m.rpz->num > rpz->num or st->m.type >= rpz_type
* could publish "evil.com A 10.2.3.4" and request
* evil.com to get the same information.
unsigned int labels;
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
static isc_result_t
int qresult_type;
int rpz_ver;
return (DNS_R_DISALLOWED);
return (DNS_R_DISALLOWED);
return (ISC_R_NOMEMORY);
switch (qresult) {
case ISC_R_SUCCESS:
case DNS_R_GLUE:
case DNS_R_ZONECUT:
qresult_type = 0;
case DNS_R_EMPTYNAME:
case DNS_R_NXRRSET:
case DNS_R_NXDOMAIN:
case DNS_R_EMPTYWILD:
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
case DNS_R_CNAME:
case DNS_R_DNAME:
case DNS_R_DELEGATION:
case ISC_R_NOTFOUND:
case ISC_R_FAILURE:
case ISC_R_TIMEDOUT:
case DNS_R_BROKENCHAIN:
return (ISC_R_SUCCESS);
qresult);
return (ISC_R_SUCCESS);
if (allowed == 0)
return (ISC_R_SUCCESS);
if (zbits != 0) {
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
DNS_RPZ_TYPE_NSDNAME) == 0 &&
DNS_RPZ_TYPE_NSIP) == 0) {
goto cleanup;
resuming);
goto cleanup;
switch (result) {
case ISC_R_SUCCESS:
goto cleanup;
case DNS_R_DELEGATION:
case DNS_R_DUPLICATE:
case DNS_R_DROP:
goto cleanup;
case DNS_R_EMPTYNAME:
case DNS_R_NXRRSET:
case DNS_R_EMPTYWILD:
case DNS_R_NXDOMAIN:
case DNS_R_NCACHENXDOMAIN:
case DNS_R_NCACHENXRRSET:
case ISC_R_NOTFOUND:
case DNS_R_CNAME:
case DNS_R_DNAME:
0, NULL);
case ISC_R_TIMEDOUT:
case DNS_R_BROKENCHAIN:
case ISC_R_FAILURE:
goto cleanup;
&rdataset);
goto cleanup;
goto cleanup;
DNS_RPZ_TYPE_NSDNAME) == 0 &&
DNS_RPZ_TYPE_NSIP) == 0)
return (result);
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_TRUE);
* Add a CNAME to the query response, including translating foo.evil.com and
* foo.evil.com CNAME foo.evil.com.example.com
static isc_result_t
unsigned int labels;
return (result);
return (result);
return (ISC_R_SUCCESS);
#define QUERY_ERROR(r) \
eresult = r; \
#define RECURSE_ERROR(r) \
QUERY_ERROR(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);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
#define NS_NAME_INIT(A,B) \
&rfc1918names[i],
&found);
unsigned int dboptions;
skip++;
&name);
goto again;
if (exact)
} else if (!exact)
if (skip != 0U)
found);
#ifdef ALLOW_FILTER_AAAA
static isc_boolean_t
return (ISC_TRUE);
return (ISC_TRUE);
return (ISC_FALSE);
static isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static isc_uint32_t
goto cleanup;
goto cleanup;
goto cleanup;
return (ttl);
static isc_boolean_t
unsigned int flags = 0;
unsigned int i, count;
return (ISC_TRUE);
for (i = 0; i < count; i++) {
return (ISC_TRUE);
return (ISC_FALSE);
static isc_result_t
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
ISC_TRUE);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
goto nxrrset;
return (ISC_R_NOTFOUND);
return (result);
static isc_result_t
unsigned int options;
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
options = 0;
return (ISC_R_NOTFOUND);
goto nxrrset;
return (DNS_R_CONTINUE);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (result);
static isc_result_t
unsigned int n, nlabels;
int order;
isc_buffer_t b;
unsigned int options;
options = 0;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto resume;
flags = 0;
if (failcache &&
sizeof(typename));
goto cleanup;
sizeof(classname));
goto cleanup;
&tversion);
goto cleanup;
if (is_zone) {
if (is_zone) {
goto cleanup;
goto cleanup;
goto cleanup;
DNS_RDATASETATTR_NEGATIVE) != 0) {
&nc_rdataset);
if (wouldlog) {
if (resp_result ==
goto cleanup;
goto cleanup;
switch (rresult) {
case ISC_R_SUCCESS:
case DNS_R_DISALLOWED:
goto norpz;
case DNS_R_DELEGATION:
goto cleanup;
goto cleanup;
case DNS_RPZ_POLICY_TCP_ONLY:
goto cleanup;
case DNS_RPZ_POLICY_DROP:
goto cleanup;
case DNS_RPZ_POLICY_NXDOMAIN:
case DNS_RPZ_POLICY_NODATA:
case DNS_RPZ_POLICY_RECORD:
case DNS_RPZ_POLICY_WILDCNAME:
NULL);
goto cleanup;
goto cleanup;
case DNS_RPZ_POLICY_CNAME:
* Add overridding CNAME from a named.conf
goto cleanup;
goto cleanup;
INSIST(0);
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_GLUE:
case DNS_R_ZONECUT:
case ISC_R_NOTFOUND:
if (dns64)
if (dns64_exclude)
goto cleanup;
goto cleanup;
case DNS_R_DELEGATION:
if (is_zone) {
&tversion);
&sigrdataset);
&fname);
goto db_find;
goto db_find;
&sigrdataset);
else if (dns64)
resuming);
if (dns64)
if (dns64_exclude)
goto cleanup;
case DNS_R_EMPTYNAME:
case DNS_R_NXRRSET:
if (dns64)
goto cleanup;
goto cleanup;
if (dns64_excluded)
goto db_find;
if (redirected)
goto cleanup;
!(ns_g_nonearest &&
unsigned int count;
unsigned int skip;
dbuf,
found);
goto cleanup;
NULL);
goto cleanup;
&sigrdataset);
goto cleanup;
case DNS_R_EMPTYWILD:
case DNS_R_NXDOMAIN:
if (!empty_wild) {
goto iszone_nxrrset;
goto ncache_nxrrset;
NULL);
goto cleanup;
goto iszone_nxrrset;
goto ncache_nxrrset;
ttl = 0;
section);
goto cleanup;
if (empty_wild)
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
goto iszone_nxrrset;
goto ncache_nxrrset;
NULL);
goto cleanup;
goto iszone_nxrrset;
goto ncache_nxrrset;
case DNS_R_NCACHENXRRSET:
if (dns64)
goto cleanup;
goto cleanup;
if (dns64_excluded)
goto db_find;
goto cleanup;
case DNS_R_CNAME:
NULL);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto addauth;
case DNS_R_DNAME:
NULL);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto addauth;
goto cleanup;
#ifdef ALLOW_FILTER_AAAA
ISC_TRUE);
#ifdef ALLOW_FILTER_AAAA
goto cleanup;
#ifdef ALLOW_FILTER_AAAA
#ifdef ALLOW_FILTER_AAAA
#ifdef ALLOW_FILTER_AAAA
if (!is_zone) {
goto addauth;
sizeof(namebuf));
goto nxrrset_rrsig;
goto cleanup;
#ifdef ALLOW_FILTER_AAAA
dns_rdatatype_a, 0,
} else if (authoritative ||
NS_CLIENTATTR_FILTER_AAAA_RC) != 0) {
goto cleanup;
goto db_find;
if (is_zone)
NS_CLIENTATTR_WANTEXPIRE) != 0) &&
if (dns64) {
if (dns64_exclude) {
if (!is_zone)
goto cleanup;
goto cleanup;
if (is_zone)
goto iszone_nxrrset;
goto ncache_nxrrset;
goto cleanup;
if (is_zone) {
goto restart;
if (resuming &&
return (eresult);
onbuf);
sizeof(namebuf));
sizeof(classname));
sizeof(typename));
switch (qtype) {
case dns_rdatatype_any:
case dns_rdatatype_ixfr:
case dns_rdatatype_axfr:
case dns_rdatatype_maila:
case dns_rdatatype_mailb:
case dns_rdatatype_tkey:
if (!ns_g_noaa)