/* 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 * rmessage;
} dns_valarg_t;
+typedef struct {
+ fetchctx_t * fctx;
+ dns_message_t * rmessage;
+} dns_chkarg_t;
+
struct dns_fetch {
unsigned int magic;
isc_mem_t * mctx;
isc_result_t *eresultp);
static void validated(isc_task_t *task, isc_event_t *event);
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);
-static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name,
+static void 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_message_t *rmessage,
+ dns_name_t *name,
dns_rdatatype_t type,
dns_name_t **noqname);
static void fctx_increference(fetchctx_t *fctx);
}
static isc_result_t
-valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
+valcreate(fetchctx_t *fctx, dns_message_t *rmessage,
+ 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)
valarg->fctx = fctx;
valarg->addrinfo = addrinfo;
+ valarg->rmessage = rmessage;
if (!ISC_LIST_EMPTY(fctx->validators))
valoptions |= DNS_VALIDATOR_DEFER;
valoptions &= ~DNS_VALIDATOR_DEFER;
result = dns_validator_create(fctx->res->view, name, type, rdataset,
- sigrdataset, fctx->rmessage,
+ sigrdataset, rmessage,
valoptions, task, validated, valarg,
&validator);
if (result == ISC_R_SUCCESS) {
empty = fctx_decreference(query->fctx);
UNLOCK(&res->buckets[bucket].lock);
+ dns_message_detach(&query->rmessage);
+
query->magic = 0;
isc_mem_put(query->mctx, query, sizeof(*query));
*queryp = NULL;
if (fctx->fwdpolicy == dns_fwdpolicy_first &&
ISFORWARDER(query->addrinfo))
{
- add_bad(fctx, query->addrinfo, ISC_R_TIMEDOUT,
+ add_bad(fctx, query->rmessage,
+ query->addrinfo, ISC_R_TIMEDOUT,
badns_forwarder);
}
/*
* No route to remote.
*/
- add_bad(fctx, query->addrinfo, sevent->result,
+ add_bad(fctx, query->rmessage, query->addrinfo,
+ sevent->result,
badns_unreachable);
fctx_cancelquery(&query, NULL, NULL, true,
false);
INSIST(ISC_LIST_EMPTY(fctx->validators));
- dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
-
query = isc_mem_get(fctx->mctx, sizeof(*query));
if (query == NULL) {
result = ISC_R_NOMEMORY;
goto stop_idle_timer;
}
+ query->rmessage = NULL;
+ result = dns_message_create(fctx->mctx, DNS_MESSAGE_INTENTPARSE,
+ &query->rmessage);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup_query;
+ }
query->mctx = fctx->mctx;
query->options = options;
query->attributes = 0;
break;
}
if (result != ISC_R_SUCCESS)
- goto cleanup_query;
+ goto cleanup_rmessage;
}
isc_sockaddr_setport(&addr, 0);
if (query->dscp == -1)
isc_sockettype_tcp,
&query->tcpsocket);
if (result != ISC_R_SUCCESS)
- goto cleanup_query;
+ goto cleanup_rmessage;
#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
result = isc_socket_bind(query->tcpsocket, &addr, 0);
if (query->dispatch != NULL)
dns_dispatch_detach(&query->dispatch);
+ cleanup_rmessage:
+ dns_message_detach(&query->rmessage);
+
cleanup_query:
if (query->connects == 0) {
query->magic = 0;
* exceeds 512 bytes from broken servers.
*/
if ((query->options & DNS_FETCHOPT_EDNS512) != 0) {
- add_bad(fctx, query->addrinfo, sevent->result,
+ add_bad(fctx, query->rmessage,
+ query->addrinfo, sevent->result,
badns_unreachable);
}
fctx_cancelquery(&query, NULL, NULL, true, false);
}
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];
return;
if (reason == DNS_R_UNEXPECTEDRCODE &&
- fctx->rmessage->rcode == dns_rcode_servfail &&
+ 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);
if (result != ISC_R_SUCCESS)
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;
}
/*
"isc_timer_create: %s",
isc_result_totext(iresult));
result = ISC_R_UNEXPECTED;
- goto cleanup_rmessage;
+ goto cleanup_qmessage;
}
/*
return (ISC_R_SUCCESS);
- 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 ttl;
unsigned options;
uint32_t bucketnum;
+ dns_message_t *rmessage;
UNUSED(task); /* for now */
res = fctx->res;
addrinfo = valarg->addrinfo;
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
+ rmessage = valarg->rmessage;
vevent = (dns_validatorevent_t *)event;
fctx->vresult = vevent->result;
dns_db_detachnode(fctx->cache, &node);
}
result = fctx->vresult;
- add_bad(fctx, addrinfo, result, badns_validation);
+ add_bad(fctx, rmessage, addrinfo, result,
+ badns_validation);
isc_event_free(&event);
UNLOCK(&res->buckets[bucketnum].lock);
INSIST(fctx->validator == NULL);
/*
* Cache DS NXDOMAIN separately to other types.
*/
- if (fctx->rmessage->rcode == dns_rcode_nxdomain &&
+ if (rmessage->rcode == dns_rcode_nxdomain &&
fctx->type != dns_rdatatype_ds)
covers = dns_rdatatype_any;
else
covers == dns_rdatatype_any && res->zero_no_soa_ttl)
ttl = 0;
- result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
+ result = ncache_adderesult(rmessage, fctx->cache, node,
covers, now, ttl, vevent->optout,
vevent->secure, ardataset, &eresult);
if (result != ISC_R_SUCCESS)
{
isc_result_t tresult;
dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, vevent->name,
+ tresult = findnoqname(fctx, rmessage, vevent->name,
vevent->rdataset->type, &noqname);
if (tresult == ISC_R_SUCCESS && noqname != NULL) {
tresult = dns_rdataset_addnoqname(vevent->rdataset,
/*
* Cache any NS/NSEC records that happened to be validated.
*/
- result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
+ result = dns_message_firstname(rmessage, DNS_SECTION_AUTHORITY);
while (result == ISC_R_SUCCESS) {
name = NULL;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
+ dns_message_currentname(rmessage, DNS_SECTION_AUTHORITY,
&name);
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
if (result != ISC_R_SUCCESS)
continue;
}
- result = dns_message_nextname(fctx->rmessage,
+ result = dns_message_nextname(rmessage,
DNS_SECTION_AUTHORITY);
}
}
static inline isc_result_t
-findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
+findnoqname(fetchctx_t *fctx, dns_message_t *rmessage,
+ dns_name_t *name, dns_rdatatype_t type,
dns_name_t **noqnamep)
{
dns_rdataset_t *nrdataset, *next, *sigrdataset;
#define NXND(x) ((x) == ISC_R_SUCCESS)
section = DNS_SECTION_AUTHORITY;
- for (result = dns_message_firstname(fctx->rmessage, section);
+ for (result = dns_message_firstname(rmessage, section);
result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, section)) {
+ result = dns_message_nextname(rmessage, section)) {
dns_name_t *nsec = NULL;
- dns_message_currentname(fctx->rmessage, section, &nsec);
+ dns_message_currentname(rmessage, 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,
+cache_name(fetchctx_t *fctx, dns_message_t *rmessage,
+ dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
isc_stdtime_t now)
{
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
{
isc_result_t tresult;
dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, name,
+ tresult = findnoqname(fctx, rmessage,
+ name,
rdataset->type,
&noqname);
if (tresult == ISC_R_SUCCESS &&
* having to remember which
* rdatasets needed validation.
*/
- result = valcreate(fctx, addrinfo,
- name, rdataset->type,
+ result = valcreate(fctx, rmessage,
+ addrinfo, name,
+ rdataset->type,
rdataset,
sigrdataset,
valoptions, task);
{
isc_result_t tresult;
dns_name_t *noqname = NULL;
- tresult = findnoqname(fctx, name,
+ tresult = findnoqname(fctx, rmessage, 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, rmessage, 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 *rmessage,
+ dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
{
isc_result_t result;
dns_section_t section;
for (section = DNS_SECTION_ANSWER;
section <= DNS_SECTION_ADDITIONAL;
section++) {
- result = dns_message_firstname(fctx->rmessage, section);
+ result = dns_message_firstname(rmessage, section);
while (result == ISC_R_SUCCESS) {
name = NULL;
- dns_message_currentname(fctx->rmessage, section,
+ dns_message_currentname(rmessage, section,
&name);
if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
- result = cache_name(fctx, name, addrinfo, now);
+ result = cache_name(fctx, rmessage, name,
+ addrinfo, now);
if (result != ISC_R_SUCCESS)
break;
}
- result = dns_message_nextname(fctx->rmessage, section);
+ result = dns_message_nextname(rmessage, 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 *rmessage,
+ dns_adbaddrinfo_t *addrinfo, dns_rdatatype_t covers,
+ isc_stdtime_t now)
{
isc_result_t result, eresult;
dns_name_t *name;
* XXXMPA remove when we follow cnames and adjust the setting
* of FCTX_ATTR_WANTNCACHE in noanswer_response().
*/
- INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0);
+ INSIST(rmessage->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,
+ result = dns_message_firstname(rmessage,
DNS_SECTION_AUTHORITY);
while (result == ISC_R_SUCCESS) {
tname = NULL;
- dns_message_currentname(fctx->rmessage,
+ dns_message_currentname(rmessage,
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(rmessage,
DNS_SECTION_AUTHORITY);
}
if (result != ISC_R_NOMORE)
/*
* Do negative response validation.
*/
- result = valcreate(fctx, addrinfo, name, fctx->type,
+ result = valcreate(fctx, rmessage, addrinfo, name, fctx->type,
NULL, NULL, valoptions,
res->buckets[fctx->bucketnum].task);
/*
fctx->res->zero_no_soa_ttl)
ttl = 0;
- result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
+ result = ncache_adderesult(rmessage, fctx->cache, node,
covers, now, ttl, false,
false, ardataset, &eresult);
if (result != ISC_R_SUCCESS)
check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
dns_section_t section)
{
- fetchctx_t *fctx = arg;
+ dns_chkarg_t *chkarg = arg;
+ fetchctx_t *fctx = chkarg->fctx;
+ dns_message_t *rmessage = chkarg->rmessage;
isc_result_t result;
dns_name_t *name = NULL;
dns_rdataset_t *rdataset = NULL;
(fctx->type == dns_rdatatype_ns &&
dns_name_equal(&fctx->name, dns_rootname)));
- result = dns_message_findname(fctx->rmessage, section, addname,
+ result = dns_message_findname(rmessage, section, addname,
dns_rdatatype_any, 0, &name, NULL);
if (result == ISC_R_SUCCESS) {
external = !dns_name_issubdomain(name, &fctx->domain);
}
}
+ dns_message_detach(&chkarg->rmessage);
+ isc_mem_put(fctx->mctx, chkarg, sizeof(*chkarg));
+
return (ISC_R_SUCCESS);
}
#endif
static void
-chase_additional(fetchctx_t *fctx) {
+chase_additional(fetchctx_t *fctx, dns_message_t *rmessage) {
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(rmessage, section);
result == ISC_R_SUCCESS;
- result = dns_message_nextname(fctx->rmessage, section)) {
+ result = dns_message_nextname(rmessage, section)) {
dns_name_t *name = NULL;
dns_rdataset_t *rdataset;
- dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
+ dns_message_currentname(rmessage, DNS_SECTION_ADDITIONAL,
&name);
if ((name->attributes & DNS_NAMEATTR_CHASE) == 0)
continue;
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
if (CHASE(rdataset)) {
+ dns_chkarg_t *chkarg;
+ chkarg = isc_mem_get(fctx->mctx,
+ sizeof(*chkarg));
+ chkarg->fctx = fctx;
+ dns_message_attach(rmessage, &chkarg->rmessage);
rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
(void)dns_rdataset_additionaldata(rdataset,
check_related,
- fctx);
+ chkarg);
rescan = true;
}
}
#define LOOK_FOR_GLUE_IN_ANSWER 0x2
static isc_result_t
-noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
- unsigned int look_in_options)
+noanswer_response(fetchctx_t *fctx, dns_message_t *message,
+ dns_name_t *oqname, unsigned int look_in_options)
{
isc_result_t result;
- dns_message_t *message;
dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name;
dns_rdataset_t *rdataset, *ns_rdataset;
bool aa, negative_response;
} else
section = DNS_SECTION_AUTHORITY;
- message = fctx->rmessage;
-
/*
* Setup qname.
*/
* we're not following a chain.)
*/
if (!negative_response && ns_name != NULL && oqname == NULL) {
+ dns_chkarg_t *chkarg;
/*
* We already know ns_name is a subdomain of fctx->domain.
* If ns_name is equal to fctx->domain, we're not making
*/
INSIST(ns_rdataset != NULL);
FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
+ chkarg = isc_mem_get(fctx->mctx,
+ sizeof(*chkarg));
+ chkarg->fctx = fctx;
+ dns_message_attach(message, &chkarg->rmessage);
(void)dns_rdataset_additionaldata(ns_rdataset, check_related,
- fctx);
+ chkarg);
#if CHECK_FOR_GLUE_IN_ANSWER
/*
* Look in the answer section for "glue" that is incorrectly
*/
if ((look_in_options & LOOK_FOR_GLUE_IN_ANSWER) != 0 &&
(fctx->type == dns_rdatatype_aaaa ||
- fctx->type == dns_rdatatype_a))
+ fctx->type == dns_rdatatype_a)) {
+ dns_chkarg_t *chkarg;
+ chkarg = isc_mem_get(fctx->mctx, sizeof(*chkarg));
+ chkarg->fctx = fctx;
+ dns_message_attach(message, &chkarg->rmessage);
(void)dns_rdataset_additionaldata(ns_rdataset,
- check_answer, fctx);
+ check_answer, chkarg);
+ }
#endif
FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING);
/*
}
static isc_result_t
-answer_response(fetchctx_t *fctx) {
+answer_response(fetchctx_t *fctx, dns_message_t *message) {
isc_result_t result;
- dns_message_t *message = NULL;
dns_name_t *name = NULL, *qname = NULL, *ns_name = NULL;
dns_name_t *aname = NULL, *cname = NULL, *dname = NULL;
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
FCTXTRACE("answer_response");
- message = fctx->rmessage;
qname = &fctx->name;
view = fctx->res->view;
type = fctx->type;
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link))
{
+ dns_chkarg_t *chkarg;
if (!validinanswer(rdataset, fctx)) {
return (DNS_R_FORMERR);
}
rdataset->attributes |= DNS_RDATASETATTR_ANSWER;
rdataset->attributes |= DNS_RDATASETATTR_CACHE;
rdataset->trust = trust;
+ rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
+ chkarg = isc_mem_get(fctx->mctx,
+ sizeof(*chkarg));
+ chkarg->fctx = fctx;
+ dns_message_attach(message, &chkarg->rmessage);
(void)dns_rdataset_additionaldata(rdataset,
check_related,
- fctx);
+ chkarg);
}
} else if (aname != NULL) {
+ dns_chkarg_t *chkarg;
if (!validinanswer(ardataset, fctx))
return (DNS_R_FORMERR);
if ((ardataset->type == dns_rdatatype_a ||
ardataset->attributes |= DNS_RDATASETATTR_ANSWER;
ardataset->attributes |= DNS_RDATASETATTR_CACHE;
ardataset->trust = trust;
+ chkarg = isc_mem_get(fctx->mctx,
+ sizeof(*chkarg));
+ chkarg->fctx = fctx;
+ dns_message_attach(message, &chkarg->rmessage);
(void)dns_rdataset_additionaldata(ardataset, check_related,
- fctx);
+ chkarg);
for (sigrdataset = ISC_LIST_HEAD(aname->list);
sigrdataset != NULL;
sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
if (rdataset->type == dns_rdatatype_ns ||
(rdataset->type == dns_rdatatype_rrsig &&
rdataset->covers == dns_rdatatype_ns)) {
+ dns_chkarg_t *chkarg;
name->attributes |=
DNS_NAMEATTR_CACHE;
rdataset->attributes |=
* Mark any additional data related
* to this rdataset.
*/
+ chkarg = isc_mem_get(fctx->mctx,
+ sizeof(*chkarg));
+ chkarg->fctx = fctx;
+ dns_message_attach(message,
+ &chkarg->rmessage);
(void)dns_rdataset_additionaldata(
rdataset,
check_related,
- fctx);
+ chkarg);
done = true;
}
}
}
static bool
-iscname(fetchctx_t *fctx) {
+iscname(fetchctx_t *fctx, dns_message_t *rmessage) {
isc_result_t result;
- result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER,
+ result = dns_message_findname(rmessage, DNS_SECTION_ANSWER,
&fctx->name, dns_rdatatype_cname, 0,
NULL, NULL);
return (result == ISC_R_SUCCESS ? true : false);
}
static bool
-betterreferral(fetchctx_t *fctx) {
+betterreferral(fetchctx_t *fctx, dns_message_t *message) {
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);
result == ISC_R_SUCCESS;
}
optvalue = isc_buffer_current(&optbuf);
compute_cc(query, cookie, sizeof(cookie));
- INSIST(query->fctx->rmessage->cc_bad == 0 &&
- query->fctx->rmessage->cc_ok == 0);
+ INSIST(query->rmessage->cc_bad == 0 &&
+ query->rmessage->cc_ok == 0);
if (optlen >= 8U &&
memcmp(cookie, optvalue, 8) == 0) {
- query->fctx->rmessage->cc_ok = 1;
+ query->rmessage->cc_ok = 1;
inc_stats(query->fctx->res,
dns_resstatscounter_cookieok);
addrinfo = query->addrinfo;
addrinfo, optvalue,
optlen);
} else
- query->fctx->rmessage->cc_bad = 1;
+ query->rmessage->cc_bad = 1;
isc_buffer_forward(&optbuf, optlen);
inc_stats(query->fctx->res,
dns_resstatscounter_cookiein);
goto done;
}
- message = fctx->rmessage;
+ message = query->rmessage;
if (query->tsig != NULL) {
result = dns_message_setquerytsig(message, query->tsig);
case dns_rcode_refused:
case dns_rcode_servfail:
default:
- result = same_question(fctx);
+ result = same_question(fctx, message);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("response did not match question", result);
nextitem = true;
}
isc_buffer_init(&b, code, sizeof(code) - 1);
- dns_rcode_totext(fctx->rmessage->rcode, &b);
+ dns_rcode_totext(message->rcode, &b);
code[isc_buffer_usedlength(&b)] = '\0';
FCTXTRACE2("remote server broken: returned ", code);
goto done;
* Is the server lame?
*/
if (res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
- is_lame(fctx)) {
+ is_lame(fctx, message)) {
inc_stats(res, dns_resstatscounter_lame);
log_lame(fctx, query->addrinfo);
result = dns_adb_marklame(fctx->adb, query->addrinfo,
if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 ||
ISFORWARDER(query->addrinfo))
{
- result = answer_response(fctx);
+ result = answer_response(fctx, message);
if (result != ISC_R_SUCCESS)
FCTXTRACE3("answer_response (AA/fwd)", result);
- } else if (iscname(fctx) &&
+ } else if (iscname(fctx, message) &&
fctx->type != dns_rdatatype_any &&
fctx->type != dns_rdatatype_cname)
{
* answer when a CNAME is followed. We should treat
* it as a valid answer.
*/
- result = answer_response(fctx);
+ result = answer_response(fctx, message);
if (result != ISC_R_SUCCESS)
FCTXTRACE3("answer_response (!ANY/!CNAME)",
result);
} else if (fctx->type != dns_rdatatype_ns &&
- !betterreferral(fctx)) {
+ !betterreferral(fctx, message)) {
/*
* Lame response !!!.
*/
- result = answer_response(fctx);
+ result = answer_response(fctx, message);
if (result != ISC_R_SUCCESS)
FCTXTRACE3("answer_response (!NS)", result);
} else {
* validation, we must invoke the following
* special kludge to treat it as a referral.
*/
- result = noanswer_response(fctx, NULL,
- LOOK_FOR_NS_IN_ANSWER);
+ result = noanswer_response(fctx,
+ message,
+ NULL,
+ LOOK_FOR_NS_IN_ANSWER);
if (result != ISC_R_SUCCESS)
FCTXTRACE3("noanswer_response (NS)",
result);
* record. LOOK_FOR_GLUE_IN_ANSWER will handle
* such a corner case.
*/
- result = noanswer_response(fctx, NULL,
+ result = noanswer_response(fctx,
+ message,
+ NULL,
LOOK_FOR_GLUE_IN_ANSWER);
if (result != ISC_R_SUCCESS)
FCTXTRACE3("noanswer_response", result);
/*
* NXDOMAIN, NXRDATASET, or referral.
*/
- result = noanswer_response(fctx, NULL, 0);
+ result = noanswer_response(fctx, message, NULL, 0);
switch (result) {
case ISC_R_SUCCESS:
case DNS_R_CHASEDSSERVERS:
/*
* Follow additional section data chains.
*/
- chase_additional(fctx);
+ chase_additional(fctx, message);
/*
* Cache the cacheable parts of the message. This may also cause
* work to be queued to the DNSSEC validator.
*/
if (WANTCACHE(fctx)) {
- result = cache_message(fctx, query->addrinfo, now);
+ result = cache_message(fctx, message, query->addrinfo,
+ now);
if (result != ISC_R_SUCCESS) {
FCTXTRACE3("cache_message complete", result);
goto done;
/*
* Cache any negative cache entries in the message.
*/
- result = ncache_message(fctx, query->addrinfo, covers, now);
+ result = ncache_message(fctx, message, query->addrinfo, covers, now);
if (result != ISC_R_SUCCESS)
FCTXTRACE3("ncache_message complete", result);
}
* Add this server to the list of bad servers for
* this fctx.
*/
- add_bad(fctx, addrinfo, broken_server, broken_type);
+ add_bad(fctx, message, addrinfo,
+ broken_server, broken_type);
}
if (get_nameservers) {
FCTXTRACE("nextitem");
inc_stats(fctx->res, dns_resstatscounter_nextitem);
INSIST(query->dispentry != NULL);
- dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
result = dns_dispatch_getnext(query->dispentry, &devent);
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
fctx_done(fctx, result, __LINE__);
} else if (result == DNS_R_CHASEDSSERVERS) {
unsigned int n;
- add_bad(fctx, addrinfo, result, broken_type);
+ add_bad(fctx, query->rmessage, addrinfo, result, broken_type);
fctx_cancelqueries(fctx, true, false);
fctx_cleanupfinds(fctx);
fctx_cleanupforwaddrs(fctx);