mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 20:02:06 -04:00
4253. [bug] Address fetch context reference count handling error
on socket error. [RT#40945]
This commit is contained in:
parent
e939674d53
commit
2f450fcd29
2 changed files with 57 additions and 43 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
4253. [bug] Address fetch context reference count handling error
|
||||
on socket error. [RT#40945]
|
||||
|
||||
4252. [func] Add support for automating the generation CDS and
|
||||
CDNSKEY rrsets to named and dnssec-signzone.
|
||||
[RT #40424]
|
||||
|
|
|
|||
|
|
@ -1787,8 +1787,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
}
|
||||
|
||||
query->dispentry = NULL;
|
||||
fctx_increference(fctx);
|
||||
query->fctx = fctx;
|
||||
query->fctx = fctx; /* reference added by caller */
|
||||
query->tsig = NULL;
|
||||
query->tsigkey = NULL;
|
||||
ISC_LINK_INIT(query, link);
|
||||
|
|
@ -1842,11 +1841,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
if (query->dispatch != NULL)
|
||||
dns_dispatch_detach(&query->dispatch);
|
||||
|
||||
LOCK(&res->buckets[fctx->bucketnum].lock);
|
||||
INSIST(fctx->references > 1);
|
||||
fctx->references--;
|
||||
UNLOCK(&res->buckets[fctx->bucketnum].lock);
|
||||
|
||||
cleanup_query:
|
||||
if (query->connects == 0) {
|
||||
query->magic = 0;
|
||||
|
|
@ -3661,6 +3655,8 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
|
|||
isc_result_t result;
|
||||
dns_adbaddrinfo_t *addrinfo = NULL;
|
||||
dns_resolver_t *res;
|
||||
unsigned int bucketnum;
|
||||
isc_boolean_t bucket_empty;
|
||||
|
||||
FCTXTRACE("try");
|
||||
|
||||
|
|
@ -3733,10 +3729,17 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
|
|||
}
|
||||
}
|
||||
|
||||
bucketnum = fctx->bucketnum;
|
||||
fctx_increference(fctx);
|
||||
result = fctx_query(fctx, addrinfo, fctx->options);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
else if (retrying)
|
||||
LOCK(&res->buckets[bucketnum].lock);
|
||||
bucket_empty = fctx_decreference(fctx);
|
||||
UNLOCK(&res->buckets[bucketnum].lock);
|
||||
if (bucket_empty)
|
||||
empty_bucket(res);
|
||||
} else if (retrying)
|
||||
inc_stats(res, dns_resstatscounter_retry);
|
||||
}
|
||||
|
||||
|
|
@ -7612,6 +7615,9 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
isc_result_t broken_server;
|
||||
badnstype_t broken_type = badns_response;
|
||||
isc_boolean_t no_response;
|
||||
unsigned int bucketnum;
|
||||
dns_resolver_t *res;
|
||||
isc_boolean_t bucket_empty;
|
||||
#ifdef HAVE_DNSTAP
|
||||
unsigned char zone[DNS_NAME_MAXWIRE];
|
||||
dns_dtmsgtype_t dtmsgtype;
|
||||
|
|
@ -7628,10 +7634,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
QTRACE("response");
|
||||
|
||||
res = fctx->res;
|
||||
if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET)
|
||||
inc_stats(fctx->res, dns_resstatscounter_responsev4);
|
||||
inc_stats(res, dns_resstatscounter_responsev4);
|
||||
else
|
||||
inc_stats(fctx->res, dns_resstatscounter_responsev6);
|
||||
inc_stats(res, dns_resstatscounter_responsev6);
|
||||
|
||||
(void)isc_timer_touch(fctx->timer);
|
||||
|
||||
|
|
@ -7643,7 +7650,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
finish = NULL;
|
||||
no_response = ISC_FALSE;
|
||||
|
||||
if (fctx->res->exiting) {
|
||||
if (res->exiting) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
FCTXTRACE("resolver shutting down");
|
||||
goto done;
|
||||
|
|
@ -7757,7 +7764,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
resend = ISC_TRUE;
|
||||
add_bad_edns(fctx,
|
||||
&query->addrinfo->sockaddr);
|
||||
inc_stats(fctx->res,
|
||||
inc_stats(res,
|
||||
dns_resstatscounter_edns0fail);
|
||||
} else {
|
||||
broken_server = result;
|
||||
|
|
@ -7781,8 +7788,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
options |= DNS_FETCHOPT_NOEDNS0;
|
||||
resend = ISC_TRUE;
|
||||
add_bad_edns(fctx, &query->addrinfo->sockaddr);
|
||||
inc_stats(fctx->res,
|
||||
dns_resstatscounter_edns0fail);
|
||||
inc_stats(res, dns_resstatscounter_edns0fail);
|
||||
} else {
|
||||
broken_server = DNS_R_UNEXPECTEDRCODE;
|
||||
keep_trying = ISC_TRUE;
|
||||
|
|
@ -7804,15 +7810,14 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_PACKETS,
|
||||
&dns_master_style_comment,
|
||||
ISC_LOG_DEBUG(10),
|
||||
fctx->res->mctx);
|
||||
ISC_LOG_DEBUG(10), res->mctx);
|
||||
|
||||
#ifdef HAVE_DNSTAP
|
||||
/*
|
||||
* Log the response via dnstap.
|
||||
*/
|
||||
memset(&zr, 0, sizeof(zr));
|
||||
result = dns_compress_init(&cctx, -1, fctx->res->mctx);
|
||||
result = dns_compress_init(&cctx, -1, res->mctx);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_buffer_init(&zb, zone, sizeof(zone));
|
||||
dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE);
|
||||
|
|
@ -7827,8 +7832,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
else
|
||||
dtmsgtype = DNS_DTTYPE_RR;
|
||||
|
||||
dns_dt_send(fctx->res->view, dtmsgtype,
|
||||
&query->addrinfo->sockaddr,
|
||||
dns_dt_send(res->view, dtmsgtype, &query->addrinfo->sockaddr,
|
||||
ISC_TF((query->options & DNS_FETCHOPT_TCP) != 0),
|
||||
&zr, &query->start, NULL, &devent->buffer);
|
||||
#endif /* HAVE_DNSTAP */
|
||||
|
|
@ -7854,7 +7858,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
* If the message is signed, check the signature. If not, this
|
||||
* returns success anyway.
|
||||
*/
|
||||
result = dns_message_checksig(message, fctx->res->view);
|
||||
result = dns_message_checksig(message, res->view);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
FCTXTRACE3("signature check failed", result);
|
||||
goto done;
|
||||
|
|
@ -7890,7 +7894,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER,
|
||||
ISC_LOG_DEBUG(3),
|
||||
fctx->res->mctx);
|
||||
res->mctx);
|
||||
dns_adb_changeflags(fctx->adb, query->addrinfo,
|
||||
DNS_FETCHOPT_NOEDNS0,
|
||||
DNS_FETCHOPT_NOEDNS0);
|
||||
|
|
@ -7914,8 +7918,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
&query->addrinfo->sockaddr,
|
||||
DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER,
|
||||
ISC_LOG_DEBUG(3),
|
||||
fctx->res->mctx);
|
||||
ISC_LOG_DEBUG(3), res->mctx);
|
||||
dns_adb_changeflags(fctx->adb, query->addrinfo,
|
||||
DNS_FETCHOPT_NOEDNS0,
|
||||
DNS_FETCHOPT_NOEDNS0);
|
||||
|
|
@ -7943,7 +7946,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
truncated = ISC_TRUE;
|
||||
|
||||
if (truncated) {
|
||||
inc_stats(fctx->res, dns_resstatscounter_truncated);
|
||||
inc_stats(res, dns_resstatscounter_truncated);
|
||||
if ((options & DNS_FETCHOPT_TCP) != 0) {
|
||||
broken_server = DNS_R_TRUNCATEDTCP;
|
||||
keep_trying = ISC_TRUE;
|
||||
|
|
@ -7972,25 +7975,25 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
if (message->rcode != dns_rcode_noerror) {
|
||||
switch (message->rcode) {
|
||||
case dns_rcode_nxdomain:
|
||||
inc_stats(fctx->res, dns_resstatscounter_nxdomain);
|
||||
inc_stats(res, dns_resstatscounter_nxdomain);
|
||||
break;
|
||||
case dns_rcode_servfail:
|
||||
inc_stats(fctx->res, dns_resstatscounter_servfail);
|
||||
inc_stats(res, dns_resstatscounter_servfail);
|
||||
break;
|
||||
case dns_rcode_formerr:
|
||||
inc_stats(fctx->res, dns_resstatscounter_formerr);
|
||||
inc_stats(res, dns_resstatscounter_formerr);
|
||||
break;
|
||||
case dns_rcode_refused:
|
||||
inc_stats(fctx->res, dns_resstatscounter_refused);
|
||||
inc_stats(res, dns_resstatscounter_refused);
|
||||
break;
|
||||
case dns_rcode_badvers:
|
||||
inc_stats(fctx->res, dns_resstatscounter_badvers);
|
||||
inc_stats(res, dns_resstatscounter_badvers);
|
||||
break;
|
||||
case dns_rcode_badcookie:
|
||||
inc_stats(fctx->res, dns_resstatscounter_badcookie);
|
||||
inc_stats(res, dns_resstatscounter_badcookie);
|
||||
break;
|
||||
default:
|
||||
inc_stats(fctx->res, dns_resstatscounter_othererror);
|
||||
inc_stats(res, dns_resstatscounter_othererror);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -8039,7 +8042,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
* Remember that they may not like EDNS0.
|
||||
*/
|
||||
add_bad_edns(fctx, &query->addrinfo->sockaddr);
|
||||
inc_stats(fctx->res, dns_resstatscounter_edns0fail);
|
||||
inc_stats(res, dns_resstatscounter_edns0fail);
|
||||
} else if (message->rcode == dns_rcode_formerr) {
|
||||
if (ISFORWARDER(query->addrinfo)) {
|
||||
/*
|
||||
|
|
@ -8174,13 +8177,13 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
/*
|
||||
* Is the server lame?
|
||||
*/
|
||||
if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
|
||||
if (res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
|
||||
is_lame(fctx)) {
|
||||
inc_stats(fctx->res, dns_resstatscounter_lame);
|
||||
inc_stats(res, dns_resstatscounter_lame);
|
||||
log_lame(fctx, query->addrinfo);
|
||||
result = dns_adb_marklame(fctx->adb, query->addrinfo,
|
||||
&fctx->name, fctx->type,
|
||||
now + fctx->res->lame_ttl);
|
||||
now + res->lame_ttl);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
|
||||
|
|
@ -8196,7 +8199,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
* Enforce delegations only zones like NET and COM.
|
||||
*/
|
||||
if (!ISFORWARDER(query->addrinfo) &&
|
||||
dns_view_isdelegationonly(fctx->res->view, &fctx->domain) &&
|
||||
dns_view_isdelegationonly(res->view, &fctx->domain) &&
|
||||
!dns_name_equal(&fctx->domain, &fctx->name) &&
|
||||
fix_mustbedelegationornxdomain(message, fctx)) {
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
|
|
@ -8208,7 +8211,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
|
||||
dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
|
||||
dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
|
||||
dns_rdataclass_format(fctx->res->rdclass, classbuf,
|
||||
dns_rdataclass_format(res->rdclass, classbuf,
|
||||
sizeof(classbuf));
|
||||
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
||||
sizeof(addrbuf));
|
||||
|
|
@ -8220,7 +8223,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
domainbuf, namebuf, typebuf, classbuf, addrbuf);
|
||||
}
|
||||
|
||||
if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0)
|
||||
if ((res->options & DNS_RESOLVER_CHECKNAMES) != 0)
|
||||
checknames(message);
|
||||
|
||||
/*
|
||||
|
|
@ -8462,7 +8465,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
name = &fctx->name;
|
||||
else
|
||||
name = &fctx->domain;
|
||||
result = dns_view_findzonecut(fctx->res->view,
|
||||
result = dns_view_findzonecut(res->view,
|
||||
name, fname,
|
||||
now, findoptions,
|
||||
ISC_TRUE,
|
||||
|
|
@ -8513,10 +8516,18 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
* Resend (probably with changed options).
|
||||
*/
|
||||
FCTXTRACE("resend");
|
||||
inc_stats(fctx->res, dns_resstatscounter_retry);
|
||||
inc_stats(res, dns_resstatscounter_retry);
|
||||
bucketnum = fctx->bucketnum;
|
||||
fctx_increference(fctx);
|
||||
result = fctx_query(fctx, addrinfo, options);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
LOCK(&res->buckets[bucketnum].lock);
|
||||
bucket_empty = fctx_decreference(fctx);
|
||||
UNLOCK(&res->buckets[bucketnum].lock);
|
||||
if (bucket_empty)
|
||||
empty_bucket(res);
|
||||
}
|
||||
} else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
|
||||
/*
|
||||
* All has gone well so far, but we are waiting for the
|
||||
|
|
@ -8543,7 +8554,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
FCTXTRACE("suspending DS lookup to find parent's NS records");
|
||||
|
||||
result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
|
||||
result = dns_resolver_createfetch(res, &fctx->nsname,
|
||||
dns_rdatatype_ns,
|
||||
NULL, NULL, NULL,
|
||||
fctx->options, task,
|
||||
|
|
|
|||
Loading…
Reference in a new issue