#include <isc/platform.h>
#include <isc/print.h>
#include <isc/random.h>
+#include <isc/refcount.h>
#include <isc/siphash.h>
#include <isc/socket.h>
#include <isc/stats.h>
/* Locked by task event serialization. */
unsigned int magic;
fetchctx_t *fctx;
+ dns_message_t *rmessage;
isc_mem_t *mctx;
dns_dispatchmgr_t *dispatchmgr;
dns_dispatch_t *dispatch;
isc_time_t expires;
isc_interval_t interval;
dns_message_t *qmessage;
- dns_message_t *rmessage;
ISC_LIST(resquery_t) queries;
dns_adbfindlist_t finds;
dns_adbfind_t *find;
typedef struct {
dns_adbaddrinfo_t *addrinfo;
fetchctx_t *fctx;
+ dns_message_t *message;
} dns_valarg_t;
struct dns_fetch {
static bool
maybe_destroy(fetchctx_t *fctx, bool locked);
static void
-add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
- badnstype_t badtype);
+add_bad(fetchctx_t *fctx, dns_message_t *rmessage, dns_adbaddrinfo_t *addrinfo,
+ isc_result_t reason, badnstype_t badtype);
static inline isc_result_t
-findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
- dns_name_t **noqname);
+findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name,
+ dns_rdatatype_t type, dns_name_t **noqname);
static void
fctx_increference(fetchctx_t *fctx);
static bool
}
static isc_result_t
-valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
- dns_rdatatype_t type, dns_rdataset_t *rdataset,
+valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo,
+ dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset, unsigned int valoptions,
isc_task_t *task) {
dns_validator_t *validator = NULL;
valarg->fctx = fctx;
valarg->addrinfo = addrinfo;
+ valarg->message = message;
if (!ISC_LIST_EMPTY(fctx->validators)) {
valoptions |= DNS_VALIDATOR_DEFER;
}
result = dns_validator_create(fctx->res->view, name, type, rdataset,
- sigrdataset, fctx->rmessage, valoptions,
- task, validated, valarg, &validator);
+ sigrdataset, message, valoptions, task,
+ validated, valarg, &validator);
if (result == ISC_R_SUCCESS) {
inc_stats(fctx->res, dns_resstatscounter_val);
if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
empty = fctx_decreference(query->fctx);
UNLOCK(&res->buckets[bucket].lock);
+ if (query->rmessage != NULL) {
+ dns_message_detach(&query->rmessage);
+ }
+
query->magic = 0;
isc_mem_put(query->mctx, query, sizeof(*query));
*/
if (fctx->fwdpolicy == dns_fwdpolicy_first &&
ISFORWARDER(query->addrinfo)) {
- add_bad(fctx, query->addrinfo, ISC_R_TIMEDOUT,
- badns_forwarder);
+ add_bad(fctx, query->rmessage, query->addrinfo,
+ ISC_R_TIMEDOUT, badns_forwarder);
}
/*
/*
* No route to remote.
*/
- add_bad(fctx, query->addrinfo, sevent->result,
- badns_unreachable);
+ add_bad(fctx, query->rmessage, query->addrinfo,
+ sevent->result, badns_unreachable);
fctx_cancelquery(&query, NULL, NULL, true, false);
retry = true;
break;
INSIST(ISC_LIST_EMPTY(fctx->validators));
- dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
-
query = isc_mem_get(fctx->mctx, sizeof(*query));
+ query->rmessage = NULL;
+ result = dns_message_create(fctx->mctx, DNS_MESSAGE_INTENTPARSE,
+ &query->rmessage);
query->mctx = fctx->mctx;
query->options = options;
query->attributes = 0;
cleanup_query:
if (query->connects == 0) {
query->magic = 0;
+ dns_message_detach(&query->rmessage);
isc_mem_put(fctx->mctx, query, sizeof(*query));
}
* exceeds 512 bytes from broken servers.
*/
if ((query->options & DNS_FETCHOPT_EDNS512) != 0) {
- add_bad(fctx, query->addrinfo, sevent->result,
- badns_unreachable);
+ add_bad(fctx, query->rmessage, query->addrinfo,
+ sevent->result, badns_unreachable);
}
fctx_cancelquery(&query, NULL, NULL, true, false);
retry = true;
}
static void
-add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
- badnstype_t badtype) {
+add_bad(fetchctx_t *fctx, dns_message_t *rmessage, dns_adbaddrinfo_t *addrinfo,
+ isc_result_t reason, badnstype_t badtype) {
char namebuf[DNS_NAME_FORMATSIZE];
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
char classbuf[64];
}
if (reason == DNS_R_UNEXPECTEDRCODE &&
- fctx->rmessage->rcode == dns_rcode_servfail &&
- ISFORWARDER(addrinfo))
+ rmessage->rcode == dns_rcode_servfail && ISFORWARDER(addrinfo))
{
return;
}
if (reason == DNS_R_UNEXPECTEDRCODE) {
isc_buffer_init(&b, code, sizeof(code) - 1);
- dns_rcode_totext(fctx->rmessage->rcode, &b);
+ dns_rcode_totext(rmessage->rcode, &b);
code[isc_buffer_usedlength(&b)] = '\0';
spc = " ";
} else if (reason == DNS_R_UNEXPECTEDOPCODE) {
isc_buffer_init(&b, code, sizeof(code) - 1);
- dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b);
+ dns_opcode_totext((dns_opcode_t)rmessage->opcode, &b);
code[isc_buffer_usedlength(&b)] = '\0';
spc = " ";
} else {
isc_counter_detach(&fctx->qc);
fcount_decr(fctx);
isc_timer_detach(&fctx->timer);
- dns_message_detach(&fctx->rmessage);
dns_message_detach(&fctx->qmessage);
if (dns_name_countlabels(&fctx->domain) > 0) {
dns_name_free(&fctx->domain, fctx->mctx);
goto cleanup_fcount;
}
- fctx->rmessage = NULL;
- result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
- &fctx->rmessage);
-
- if (result != ISC_R_SUCCESS) {
- goto cleanup_qmessage;
- }
-
/*
* Compute an expiration time for the entire fetch.
*/
"isc_time_nowplusinterval: %s",
isc_result_totext(iresult));
result = ISC_R_UNEXPECTED;
- goto cleanup_rmessage;
+ goto cleanup_qmessage;
}
/*
UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_create: %s",
isc_result_totext(iresult));
result = ISC_R_UNEXPECTED;
- goto cleanup_rmessage;
+ goto cleanup_qmessage;
}
/*
dns_db_detach(&fctx->cache);
isc_timer_detach(&fctx->timer);
-cleanup_rmessage:
- dns_message_detach(&fctx->rmessage);
-
cleanup_qmessage:
dns_message_detach(&fctx->qmessage);
* Handle Responses
*/
static inline bool
-is_lame(fetchctx_t *fctx) {
- dns_message_t *message = fctx->rmessage;
+is_lame(fetchctx_t *fctx, dns_message_t *message) {
dns_name_t *name;
dns_rdataset_t *rdataset;
isc_result_t result;
}
static isc_result_t
-same_question(fetchctx_t *fctx) {
+same_question(fetchctx_t *fctx, dns_message_t *message) {
isc_result_t result;
- dns_message_t *message = fctx->rmessage;
dns_name_t *name;
dns_rdataset_t *rdataset;
uint32_t bucketnum;
dns_fixedname_t fwild;
dns_name_t *wild = NULL;
+ dns_message_t *message;
UNUSED(task); /* for now */
REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
valarg = event->ev_arg;
+ message = valarg->message;
fctx = valarg->fctx;
+
REQUIRE(VALID_FCTX(fctx));
res = fctx->res;
addrinfo = valarg->addrinfo;
}
}
result = fctx->vresult;
- add_bad(fctx, addrinfo, result, badns_validation);
+ add_bad(fctx, message, addrinfo, result, badns_validation);
isc_event_free(&event);
UNLOCK(&res->buckets[bucketnum].lock);
INSIST(fctx->validator == NULL);
} else {
fctx_try(fctx, true, true); /* Locks bucket. */
}
+
return;
}
/*
* Cache DS NXDOMAIN separately to other types.
*/
- if (fctx->rmessage->rcode == dns_rcode_nxdomain &&
- fctx->type != dns_rdatatype_ds)
- {
+ if (message->rcode == dns_rcode_nxdomain &&
+ fctx->type != dns_rdatatype_ds) {
covers = dns_rdatatype_any;
} else {
covers = fctx->type;
ttl = 0;
}
- result = ncache_adderesult(
- fctx->rmessage, fctx->cache, node, covers, now,
- fctx->res->view->minncachettl, ttl, vevent->optout,
- vevent->secure, ardataset, &eresult);
+ result = ncache_adderesult(message, fctx->cache, node, covers,
+ now, fctx->res->view->minncachettl,
+ ttl, vevent->optout, vevent->secure,
+ ardataset, &eresult);
if (result != ISC_R_SUCCESS) {
goto noanswer_response;
}
{
isc_result_t tresult;
dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, vevent->name,
+ tresult = findnoqname(fctx, message, vevent->name,
vevent->rdataset->type, &noqname);
if (tresult == ISC_R_SUCCESS && noqname != NULL) {
tresult = dns_rdataset_addnoqname(vevent->rdataset,
/*
* Cache any SOA/NS/NSEC records that happened to be validated.
*/
- result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
+ result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
while (result == ISC_R_SUCCESS) {
name = NULL;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
- &name);
+ dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link))
{
continue;
}
}
- result = dns_message_nextname(fctx->rmessage,
- DNS_SECTION_AUTHORITY);
+ result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
}
/*
cleanup_event:
INSIST(node == NULL);
+ dns_message_detach(&message);
isc_event_free(&event);
}
}
static inline isc_result_t
-findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
- dns_name_t **noqnamep) {
+findnoqname(fetchctx_t *fctx, dns_message_t *message, dns_name_t *name,
+ dns_rdatatype_t type, dns_name_t **noqnamep) {
dns_rdataset_t *nrdataset, *next, *sigrdataset;
dns_rdata_rrsig_t rrsig;
isc_result_t result;
#define NXND(x) ((x) == ISC_R_SUCCESS)
section = DNS_SECTION_AUTHORITY;
- for (result = dns_message_firstname(fctx->rmessage, section);
+ for (result = dns_message_firstname(message, section);
result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, section))
+ result = dns_message_nextname(message, section))
{
dns_name_t *nsec = NULL;
- dns_message_currentname(fctx->rmessage, section, &nsec);
+ dns_message_currentname(message, section, &nsec);
for (nrdataset = ISC_LIST_HEAD(nsec->list); nrdataset != NULL;
nrdataset = next) {
bool data = false, exists = false;
}
static inline isc_result_t
-cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
- isc_stdtime_t now) {
+cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
+ dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) {
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
dns_rdataset_t *addedrdataset = NULL;
dns_rdataset_t *ardataset = NULL, *asigrdataset = NULL;
rdataset->type != dns_rdatatype_rrsig) {
isc_result_t tresult;
dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, name,
- rdataset->type,
- &noqname);
+ tresult = findnoqname(
+ fctx, message, name,
+ rdataset->type, &noqname);
if (tresult == ISC_R_SUCCESS &&
noqname != NULL) {
(void)dns_rdataset_addnoqname(
* rdatasets needed validation.
*/
result = valcreate(
- fctx, addrinfo, name,
+ fctx, message, addrinfo, name,
rdataset->type, rdataset,
sigrdataset, valoptions, task);
}
rdataset->type != dns_rdatatype_rrsig) {
isc_result_t tresult;
dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, name,
+ tresult = findnoqname(fctx, message, name,
rdataset->type, &noqname);
if (tresult == ISC_R_SUCCESS && noqname != NULL)
{
vtype = dns_rdatatype_dname;
}
}
- result = valcreate(fctx, addrinfo, name, vtype, valrdataset,
- valsigrdataset, valoptions, task);
+
+ result = valcreate(fctx, message, addrinfo, name, vtype,
+ valrdataset, valsigrdataset, valoptions,
+ task);
}
if (result == ISC_R_SUCCESS && have_answer) {
}
static inline isc_result_t
-cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
- isc_stdtime_t now) {
+cache_message(fetchctx_t *fctx, dns_message_t *message,
+ dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) {
isc_result_t result;
dns_section_t section;
dns_name_t *name;
for (section = DNS_SECTION_ANSWER; section <= DNS_SECTION_ADDITIONAL;
section++) {
- result = dns_message_firstname(fctx->rmessage, section);
+ result = dns_message_firstname(message, section);
while (result == ISC_R_SUCCESS) {
name = NULL;
- dns_message_currentname(fctx->rmessage, section, &name);
+ dns_message_currentname(message, section, &name);
if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
- result = cache_name(fctx, name, addrinfo, now);
+ result = cache_name(fctx, name, message,
+ addrinfo, now);
if (result != ISC_R_SUCCESS) {
break;
}
}
- result = dns_message_nextname(fctx->rmessage, section);
+ result = dns_message_nextname(message, section);
}
if (result != ISC_R_NOMORE) {
break;
}
static inline isc_result_t
-ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
- dns_rdatatype_t covers, isc_stdtime_t now) {
+ncache_message(fetchctx_t *fctx, dns_message_t *message,
+ dns_adbaddrinfo_t *addrinfo, dns_rdatatype_t covers,
+ isc_stdtime_t now) {
isc_result_t result, eresult;
dns_name_t *name;
dns_resolver_t *res;
* XXXMPA remove when we follow cnames and adjust the setting
* of FCTX_ATTR_WANTNCACHE in rctx_answer_none().
*/
- INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0);
+ INSIST(message->counts[DNS_SECTION_ANSWER] == 0);
/*
* Is DNSSEC validation required for this name?
dns_rdataset_t *trdataset;
dns_name_t *tname;
- result = dns_message_firstname(fctx->rmessage,
- DNS_SECTION_AUTHORITY);
+ result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
while (result == ISC_R_SUCCESS) {
tname = NULL;
- dns_message_currentname(fctx->rmessage,
- DNS_SECTION_AUTHORITY, &tname);
+ dns_message_currentname(message, DNS_SECTION_AUTHORITY,
+ &tname);
for (trdataset = ISC_LIST_HEAD(tname->list);
trdataset != NULL;
trdataset = ISC_LIST_NEXT(trdataset, link))
{
trdataset->trust = dns_trust_pending_answer;
}
- result = dns_message_nextname(fctx->rmessage,
+ result = dns_message_nextname(message,
DNS_SECTION_AUTHORITY);
}
if (result != ISC_R_NOMORE) {
/*
* Do negative response validation.
*/
- result = valcreate(fctx, addrinfo, name, fctx->type, NULL, NULL,
- valoptions,
+ result = valcreate(fctx, message, addrinfo, name, fctx->type,
+ NULL, NULL, valoptions,
res->buckets[fctx->bucketnum].task);
/*
* If validation is necessary, return now. Otherwise continue
ttl = 0;
}
- result = ncache_adderesult(fctx->rmessage, fctx->cache, node, covers,
- now, fctx->res->view->minncachettl, ttl,
- false, false, ardataset, &eresult);
+ result = ncache_adderesult(message, fctx->cache, node, covers, now,
+ fctx->res->view->minncachettl, ttl, false,
+ false, ardataset, &eresult);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
static isc_result_t
check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
dns_section_t section) {
- fetchctx_t *fctx = arg;
+ respctx_t *rctx = arg;
+ fetchctx_t *fctx = rctx->fctx;
isc_result_t result;
dns_name_t *name = NULL;
dns_rdataset_t *rdataset = NULL;
gluing = (GLUING(fctx) || (fctx->type == dns_rdatatype_ns &&
dns_name_equal(&fctx->name, dns_rootname)));
- result = dns_message_findname(fctx->rmessage, section, addname,
+ result = dns_message_findname(rctx->query->rmessage, section, addname,
dns_rdatatype_any, 0, &name, NULL);
if (result == ISC_R_SUCCESS) {
external = !dns_name_issubdomain(name, &fctx->domain);
isc_mem_put(mctx, buf, buflen);
}
-static bool
-iscname(fetchctx_t *fctx) {
+static inline bool
+iscname(dns_message_t *message, dns_name_t *name) {
isc_result_t result;
- result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER,
- &fctx->name, dns_rdatatype_cname, 0, NULL,
- NULL);
+ result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
+ dns_rdatatype_cname, 0, NULL, NULL);
return (result == ISC_R_SUCCESS ? true : false);
}
static bool
-betterreferral(fetchctx_t *fctx) {
+betterreferral(respctx_t *rctx) {
isc_result_t result;
dns_name_t *name;
dns_rdataset_t *rdataset;
- dns_message_t *message = fctx->rmessage;
- for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
+ for (result = dns_message_firstname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY);
result == ISC_R_SUCCESS;
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))
+ result = dns_message_nextname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY))
{
name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
- if (!isstrictsubdomain(name, &fctx->domain)) {
+ dns_message_currentname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY, &name);
+ if (!isstrictsubdomain(name, &rctx->fctx->domain)) {
continue;
}
for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
}
if (query->tsig != NULL) {
- result = dns_message_setquerytsig(fctx->rmessage, query->tsig);
+ result = dns_message_setquerytsig(query->rmessage, query->tsig);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("unable to set query tsig", result);
rctx_done(&rctx, result);
}
if (query->tsigkey) {
- result = dns_message_settsigkey(fctx->rmessage, query->tsigkey);
+ result = dns_message_settsigkey(query->rmessage,
+ query->tsigkey);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("unable to set tsig key", result);
rctx_done(&rctx, result);
}
}
- dns_message_setclass(fctx->rmessage, fctx->res->rdclass);
+ dns_message_setclass(query->rmessage, fctx->res->rdclass);
if ((rctx.retryopts & DNS_FETCHOPT_TCP) == 0) {
if ((rctx.retryopts & DNS_FETCHOPT_NOEDNS0) == 0) {
*/
rctx_logpacket(&rctx);
- if (fctx->rmessage->rdclass != fctx->res->rdclass) {
+ if (query->rmessage->rdclass != fctx->res->rdclass) {
rctx.resend = true;
FCTXTRACE("bad class");
rctx_done(&rctx, result);
/*
* Process receive opt record.
*/
- rctx.opt = dns_message_getopt(fctx->rmessage);
+ rctx.opt = dns_message_getopt(query->rmessage);
if (rctx.opt != NULL) {
rctx_opt(&rctx);
}
- if (fctx->rmessage->cc_bad && (rctx.retryopts & DNS_FETCHOPT_TCP) == 0)
+ if (query->rmessage->cc_bad && (rctx.retryopts & DNS_FETCHOPT_TCP) == 0)
{
/*
* If the COOKIE is bad, assume it is an attack and
* the same question.
* FORMERR/NOTIMP if they have a question section then it must match.
*/
- switch (fctx->rmessage->rcode) {
+ switch (query->rmessage->rcode) {
case dns_rcode_notimp:
case dns_rcode_formerr:
- if (fctx->rmessage->counts[DNS_SECTION_QUESTION] == 0) {
+ if (query->rmessage->counts[DNS_SECTION_QUESTION] == 0) {
break;
}
/* FALLTHROUGH */
case dns_rcode_refused:
case dns_rcode_servfail:
default:
- result = same_question(fctx);
+ result = same_question(fctx, query->rmessage);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("response did not match question", result);
rctx.nextitem = true;
* If the message is signed, check the signature. If not, this
* returns success anyway.
*/
- result = dns_message_checksig(fctx->rmessage, fctx->res->view);
+ result = dns_message_checksig(query->rmessage, fctx->res->view);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("signature check failed", result);
rctx_done(&rctx, result);
/*
* The dispatcher should ensure we only get responses with QR set.
*/
- INSIST((fctx->rmessage->flags & DNS_MESSAGEFLAG_QR) != 0);
+ INSIST((query->rmessage->flags & DNS_MESSAGEFLAG_QR) != 0);
/*
* INSIST() that the message comes from the place we sent it to,
* since the dispatch code should ensure this.
/*
* Deal with truncated responses by retrying using TCP.
*/
- if ((fctx->rmessage->flags & DNS_MESSAGEFLAG_TC) != 0) {
+ if ((query->rmessage->flags & DNS_MESSAGEFLAG_TC) != 0) {
rctx.truncated = true;
}
/*
* Is it a query response?
*/
- if (fctx->rmessage->opcode != dns_opcode_query) {
+ if (query->rmessage->opcode != dns_opcode_query) {
rctx.broken_server = DNS_R_UNEXPECTEDOPCODE;
rctx.next_server = true;
FCTXTRACE("invalid message opcode");
/*
* Update statistics about erroneous responses.
*/
- switch (fctx->rmessage->rcode) {
+ switch (query->rmessage->rcode) {
case dns_rcode_noerror:
/* no error */
break;
* to validate the names in the response message.
*/
if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0) {
- checknames(fctx->rmessage);
+ checknames(query->rmessage);
}
/*
/*
* Did we get any answers?
*/
- if (fctx->rmessage->counts[DNS_SECTION_ANSWER] > 0 &&
- (fctx->rmessage->rcode == dns_rcode_noerror ||
- fctx->rmessage->rcode == dns_rcode_yxdomain ||
- fctx->rmessage->rcode == dns_rcode_nxdomain))
+ if (query->rmessage->counts[DNS_SECTION_ANSWER] > 0 &&
+ (query->rmessage->rcode == dns_rcode_noerror ||
+ query->rmessage->rcode == dns_rcode_yxdomain ||
+ query->rmessage->rcode == dns_rcode_nxdomain))
{
result = rctx_answer(&rctx);
if (result == ISC_R_COMPLETE) {
return;
}
- } else if (fctx->rmessage->counts[DNS_SECTION_AUTHORITY] > 0 ||
- fctx->rmessage->rcode == dns_rcode_noerror ||
- fctx->rmessage->rcode == dns_rcode_nxdomain)
+ } else if (query->rmessage->counts[DNS_SECTION_AUTHORITY] > 0 ||
+ query->rmessage->rcode == dns_rcode_noerror ||
+ query->rmessage->rcode == dns_rcode_nxdomain)
{
/*
* This might be an NXDOMAIN, NXRRSET, or referral.
*/
if (WANTCACHE(fctx)) {
isc_result_t tresult;
- tresult = cache_message(fctx, query->addrinfo, rctx.now);
+ tresult = cache_message(fctx, query->rmessage, query->addrinfo,
+ rctx.now);
if (tresult != ISC_R_SUCCESS) {
FCTXTRACE3("cache_message complete", tresult);
rctx_done(&rctx, tresult);
rctx_answer_init(respctx_t *rctx) {
fetchctx_t *fctx = rctx->fctx;
- rctx->aa = ((fctx->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0);
+ rctx->aa = ((rctx->query->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0);
if (rctx->aa) {
rctx->trust = dns_trust_authanswer;
} else {
fetchctx_t *fctx = rctx->fctx;
resquery_t *query = rctx->query;
- result = dns_message_parse(fctx->rmessage, &rctx->devent->buffer, 0);
+ result = dns_message_parse(query->rmessage, &rctx->devent->buffer, 0);
if (result == ISC_R_SUCCESS) {
return (ISC_R_SUCCESS);
}
switch (result) {
case ISC_R_UNEXPECTEDEND:
- if (fctx->rmessage->question_ok &&
- (fctx->rmessage->flags & DNS_MESSAGEFLAG_TC) != 0 &&
+ if (query->rmessage->question_ok &&
+ (query->rmessage->flags & DNS_MESSAGEFLAG_TC) != 0 &&
(rctx->retryopts & DNS_FETCHOPT_TCP) == 0)
{
/*
}
optvalue = isc_buffer_current(&optbuf);
compute_cc(query, cookie, sizeof(cookie));
- INSIST(fctx->rmessage->cc_bad == 0 &&
- fctx->rmessage->cc_ok == 0);
+ INSIST(query->rmessage->cc_bad == 0 &&
+ query->rmessage->cc_ok == 0);
if (optlen >= 8U &&
memcmp(cookie, optvalue, 8) == 0) {
- fctx->rmessage->cc_ok = 1;
+ query->rmessage->cc_ok = 1;
inc_stats(fctx->res,
dns_resstatscounter_cookieok);
addrinfo = query->addrinfo;
dns_adb_setcookie(fctx->adb, addrinfo,
optvalue, optlen);
} else {
- fctx->rmessage->cc_bad = 1;
+ query->rmessage->cc_bad = 1;
}
isc_buffer_forward(&optbuf, optlen);
inc_stats(fctx->res,
* EDNS support.
*/
if (rctx->opt == NULL && !EDNSOK(query->addrinfo) &&
- (fctx->rmessage->rcode == dns_rcode_noerror ||
- fctx->rmessage->rcode == dns_rcode_nxdomain ||
- fctx->rmessage->rcode == dns_rcode_refused ||
- fctx->rmessage->rcode == dns_rcode_yxdomain) &&
+ (query->rmessage->rcode == dns_rcode_noerror ||
+ query->rmessage->rcode == dns_rcode_nxdomain ||
+ query->rmessage->rcode == dns_rcode_refused ||
+ query->rmessage->rcode == dns_rcode_yxdomain) &&
bad_edns(fctx, &query->addrinfo->sockaddr))
{
dns_message_logpacket(
- fctx->rmessage, "received packet (bad edns) from",
+ query->rmessage, "received packet (bad edns) from",
&query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
fctx->res->mctx);
dns_adb_changeflags(fctx->adb, query->addrinfo,
DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_NOEDNS0);
} else if (rctx->opt == NULL &&
- (fctx->rmessage->flags & DNS_MESSAGEFLAG_TC) == 0 &&
+ (query->rmessage->flags & DNS_MESSAGEFLAG_TC) == 0 &&
!EDNSOK(query->addrinfo) &&
- (fctx->rmessage->rcode == dns_rcode_noerror ||
- fctx->rmessage->rcode == dns_rcode_nxdomain) &&
+ (query->rmessage->rcode == dns_rcode_noerror ||
+ query->rmessage->rcode == dns_rcode_nxdomain) &&
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
{
/*
* and NXDOMAIN.
*/
dns_message_logpacket(
- fctx->rmessage, "received packet (no opt) from",
+ query->rmessage, "received packet (no opt) from",
&query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
fctx->res->mctx);
*/
if (rctx->opt != NULL && !EDNSOK(query->addrinfo) &&
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0 &&
- (fctx->rmessage->rcode == dns_rcode_noerror ||
- fctx->rmessage->rcode == dns_rcode_nxdomain ||
- fctx->rmessage->rcode == dns_rcode_refused ||
- fctx->rmessage->rcode == dns_rcode_yxdomain))
+ (query->rmessage->rcode == dns_rcode_noerror ||
+ query->rmessage->rcode == dns_rcode_nxdomain ||
+ query->rmessage->rcode == dns_rcode_refused ||
+ query->rmessage->rcode == dns_rcode_yxdomain))
{
dns_adb_changeflags(fctx->adb, query->addrinfo,
FCTX_ADDRINFO_EDNSOK, FCTX_ADDRINFO_EDNSOK);
fetchctx_t *fctx = rctx->fctx;
resquery_t *query = rctx->query;
- if ((fctx->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0 ||
+ if ((query->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0 ||
ISFORWARDER(query->addrinfo))
{
result = rctx_answer_positive(rctx);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("rctx_answer_positive (AA/fwd)", result);
}
- } else if (iscname(fctx) && fctx->type != dns_rdatatype_any &&
+ } else if (iscname(query->rmessage, &fctx->name) &&
+ fctx->type != dns_rdatatype_any &&
fctx->type != dns_rdatatype_cname)
{
/*
FCTXTRACE3("rctx_answer_positive (!ANY/!CNAME)",
result);
}
- } else if (fctx->type != dns_rdatatype_ns && !betterreferral(fctx)) {
+ } else if (fctx->type != dns_rdatatype_ns && !betterreferral(rctx)) {
result = rctx_answer_positive(rctx);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("rctx_answer_positive (!NS)", result);
* We didn't end with an incomplete chain, so the rcode should be
* "no error".
*/
- if (fctx->rmessage->rcode != dns_rcode_noerror) {
+ if (rctx->query->rmessage->rcode != dns_rcode_noerror) {
log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE "
"indicates error");
return (DNS_R_FORMERR);
fetchctx_t *fctx = rctx->fctx;
dns_rdataset_t *rdataset = NULL;
- for (result = dns_message_firstname(fctx->rmessage, DNS_SECTION_ANSWER);
+ for (result = dns_message_firstname(rctx->query->rmessage,
+ DNS_SECTION_ANSWER);
result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, DNS_SECTION_ANSWER))
+ result = dns_message_nextname(rctx->query->rmessage,
+ DNS_SECTION_ANSWER))
{
int order;
unsigned int nlabels;
dns_namereln_t namereln;
dns_name_t *name = NULL;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_ANSWER,
- &name);
+ dns_message_currentname(rctx->query->rmessage,
+ DNS_SECTION_ANSWER, &name);
namereln = dns_name_fullcompare(&fctx->name, name, &order,
&nlabels);
switch (namereln) {
rdataset->trust = rctx->trust;
(void)dns_rdataset_additionaldata(rdataset, check_related,
- fctx);
+ rctx);
}
return (ISC_R_SUCCESS);
rctx->ardataset->attributes |= DNS_RDATASETATTR_ANSWER;
rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE;
rctx->ardataset->trust = rctx->trust;
- (void)dns_rdataset_additionaldata(rctx->ardataset, check_related, fctx);
+ (void)dns_rdataset_additionaldata(rctx->ardataset, check_related, rctx);
for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list);
sigrdataset != NULL;
bool done = false;
isc_result_t result;
- result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
+ result = dns_message_firstname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY);
while (!done && result == ISC_R_SUCCESS) {
dns_name_t *name = NULL;
bool external;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
- &name);
+ dns_message_currentname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY, &name);
external = !dns_name_issubdomain(name, &fctx->domain);
if (!external) {
* to this rdataset.
*/
(void)dns_rdataset_additionaldata(
- rdataset, check_related, fctx);
+ rdataset, check_related, rctx);
done = true;
}
}
}
- result = dns_message_nextname(fctx->rmessage,
+ result = dns_message_nextname(rctx->query->rmessage,
DNS_SECTION_AUTHORITY);
}
}
* Sometimes we can tell if its a negative response by looking at
* the message header.
*/
- if (fctx->rmessage->rcode == dns_rcode_nxdomain ||
- (fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0 &&
- fctx->rmessage->counts[DNS_SECTION_AUTHORITY] == 0))
+ if (rctx->query->rmessage->rcode == dns_rcode_nxdomain ||
+ (rctx->query->rmessage->counts[DNS_SECTION_ANSWER] == 0 &&
+ rctx->query->rmessage->counts[DNS_SECTION_AUTHORITY] == 0))
{
rctx->negative = true;
}
/*
* Trigger lookups for DNS nameservers.
*/
- if (rctx->negative && fctx->rmessage->rcode == dns_rcode_noerror &&
+ if (rctx->negative &&
+ rctx->query->rmessage->rcode == dns_rcode_noerror &&
fctx->type == dns_rdatatype_ds && rctx->soa_name != NULL &&
dns_name_equal(rctx->soa_name, &fctx->name) &&
!dns_name_equal(&fctx->name, dns_rootname))
section = DNS_SECTION_AUTHORITY;
}
- result = dns_message_firstname(fctx->rmessage, section);
+ result = dns_message_firstname(rctx->query->rmessage, section);
if (result != ISC_R_SUCCESS) {
return (ISC_R_SUCCESS);
}
while (!finished) {
dns_name_t *name = NULL;
- dns_message_currentname(fctx->rmessage, section, &name);
- result = dns_message_nextname(fctx->rmessage, section);
+ dns_message_currentname(rctx->query->rmessage, section, &name);
+ result = dns_message_nextname(rctx->query->rmessage, section);
if (result != ISC_R_SUCCESS) {
finished = true;
}
/*
* Cache DS NXDOMAIN separately to other types.
*/
- if (fctx->rmessage->rcode == dns_rcode_nxdomain &&
+ if (rctx->query->rmessage->rcode == dns_rcode_nxdomain &&
fctx->type != dns_rdatatype_ds)
{
covers = dns_rdatatype_any;
/*
* Cache any negative cache entries in the message.
*/
- result = ncache_message(fctx, rctx->query->addrinfo, covers, rctx->now);
+ result = ncache_message(fctx, rctx->query->rmessage,
+ rctx->query->addrinfo, covers, rctx->now);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("ncache_message complete", result);
}
REQUIRE(!rctx->ns_in_answer && !rctx->glue_in_answer);
- result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
+ result = dns_message_firstname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY);
if (result != ISC_R_SUCCESS) {
return (ISC_R_SUCCESS);
}
while (!finished) {
dns_name_t *name = NULL;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
- &name);
- result = dns_message_nextname(fctx->rmessage,
+ dns_message_currentname(rctx->query->rmessage,
+ DNS_SECTION_AUTHORITY, &name);
+ result = dns_message_nextname(rctx->query->rmessage,
DNS_SECTION_AUTHORITY);
if (result != ISC_R_SUCCESS) {
finished = true;
INSIST(rctx->ns_rdataset != NULL);
FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
(void)dns_rdataset_additionaldata(rctx->ns_rdataset, check_related,
- fctx);
+ rctx);
#if CHECK_FOR_GLUE_IN_ANSWER
/*
* Look in the answer section for "glue" that is incorrectly
*/
static void
rctx_additional(respctx_t *rctx) {
- fetchctx_t *fctx = rctx->fctx;
bool rescan;
dns_section_t section = DNS_SECTION_ADDITIONAL;
isc_result_t result;
again:
rescan = false;
- for (result = dns_message_firstname(fctx->rmessage, section);
+ for (result = dns_message_firstname(rctx->query->rmessage, section);
result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, section))
+ result = dns_message_nextname(rctx->query->rmessage, section))
{
dns_name_t *name = NULL;
dns_rdataset_t *rdataset;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
- &name);
+ dns_message_currentname(rctx->query->rmessage,
+ DNS_SECTION_ADDITIONAL, &name);
if ((name->attributes & DNS_NAMEATTR_CHASE) == 0) {
continue;
}
if (CHASE(rdataset)) {
rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
(void)dns_rdataset_additionaldata(
- rdataset, check_related, fctx);
+ rdataset, check_related, rctx);
rescan = true;
}
}
* Add this server to the list of bad servers for
* this fctx.
*/
- add_bad(fctx, addrinfo, rctx->broken_server, rctx->broken_type);
+ add_bad(fctx, rctx->query->rmessage, addrinfo,
+ rctx->broken_server, rctx->broken_type);
}
if (rctx->get_nameservers) {
FCTXTRACE("nextitem");
inc_stats(rctx->fctx->res, dns_resstatscounter_nextitem);
INSIST(rctx->query->dispentry != NULL);
- dns_message_reset(rctx->fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
result = dns_dispatch_getnext(rctx->query->dispentry, &rctx->devent);
if (result != ISC_R_SUCCESS) {
fctx_done(rctx->fctx, result, __LINE__);
fetchctx_t *fctx = rctx->fctx;
unsigned int n;
- add_bad(fctx, addrinfo, result, rctx->broken_type);
+ add_bad(fctx, rctx->query->rmessage, addrinfo, result,
+ rctx->broken_type);
fctx_cancelqueries(fctx, true, false);
fctx_cleanupfinds(fctx);
fctx_cleanupforwaddrs(fctx);
#endif /* HAVE_DNSTAP */
dns_message_logfmtpacket(
- rctx->fctx->rmessage, "received packet from",
+ rctx->query->rmessage, "received packet from",
&rctx->query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_PACKETS, &dns_master_style_comment,
ISC_LOG_DEBUG(10), rctx->fctx->res->mctx);
resquery_t *query = rctx->query;
isc_buffer_t b;
char code[64];
+ dns_rcode_t rcode = rctx->query->rmessage->rcode;
- if (fctx->rmessage->rcode == dns_rcode_noerror ||
- fctx->rmessage->rcode == dns_rcode_yxdomain ||
- fctx->rmessage->rcode == dns_rcode_nxdomain)
+ if (rcode == dns_rcode_noerror || rcode == dns_rcode_yxdomain ||
+ rcode == dns_rcode_nxdomain)
{
return (ISC_R_SUCCESS);
}
- if ((fctx->rmessage->rcode == dns_rcode_formerr) &&
+ if ((rcode == dns_rcode_formerr) &&
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
{
/*
*/
add_bad_edns(fctx, &query->addrinfo->sockaddr);
inc_stats(fctx->res, dns_resstatscounter_edns0fail);
- } else if (fctx->rmessage->rcode == dns_rcode_formerr) {
+ } else if (rcode == dns_rcode_formerr) {
if (ISFORWARDER(query->addrinfo)) {
/*
* This forwarder doesn't understand us,
log_formerr(fctx, "server sent FORMERR");
result = DNS_R_FORMERR;
}
- } else if (fctx->rmessage->rcode == dns_rcode_badvers) {
+ } else if (rcode == dns_rcode_badvers) {
unsigned int version;
#if DNS_EDNS_VERSION > 0
unsigned int flags, mask;
rctx->broken_server = DNS_R_BADVERS;
rctx->next_server = true;
#endif /* if DNS_EDNS_VERSION > 0 */
- } else if (fctx->rmessage->rcode == dns_rcode_badcookie &&
- fctx->rmessage->cc_ok)
+ } else if (rcode == dns_rcode_badcookie && rctx->query->rmessage->cc_ok)
{
/*
* We have recorded the new cookie.
}
isc_buffer_init(&b, code, sizeof(code) - 1);
- dns_rcode_totext(fctx->rmessage->rcode, &b);
+ dns_rcode_totext(rcode, &b);
code[isc_buffer_usedlength(&b)] = '\0';
FCTXTRACE2("remote server broken: returned ", code);
rctx_done(rctx, result);
resquery_t *query = rctx->query;
if (fctx->res->lame_ttl == 0 || ISFORWARDER(query->addrinfo) ||
- !is_lame(fctx)) {
+ !is_lame(fctx, query->rmessage))
+ {
return (ISC_R_SUCCESS);
}
if (ISFORWARDER(rctx->query->addrinfo) ||
!dns_view_isdelegationonly(fctx->res->view, &fctx->domain) ||
dns_name_equal(&fctx->domain, &fctx->name) ||
- !fix_mustbedelegationornxdomain(fctx->rmessage, fctx))
+ !fix_mustbedelegationornxdomain(rctx->query->rmessage, fctx))
{
return;
}