dns_fwdpolicy_t fwdpolicy;
isc_sockaddrlist_t bad;
ISC_LIST(struct tried) edns;
- isc_sockaddrlist_t bad_edns;
dns_validator_t *validator;
ISC_LIST(dns_validator_t) validators;
dns_db_t *cache;
return result;
}
-static bool
-bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
- for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL;
- sa = ISC_LIST_NEXT(sa, link))
- {
- if (isc_sockaddr_equal(sa, address)) {
- return true;
- }
- }
-
- return false;
-}
-
-static void
-add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
- isc_sockaddr_t *sa;
-
-#ifdef ENABLE_AFL
- if (dns_fuzzing_resolver) {
- return;
- }
-#endif /* ifdef ENABLE_AFL */
- if (bad_edns(fctx, address)) {
- return;
- }
-
- sa = isc_mem_get(fctx->mctx, sizeof(*sa));
-
- *sa = *address;
- ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link);
-}
-
static struct tried *
triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
struct tried *tried;
isc_mem_put(fctx->mctx, tried, sizeof(*tried));
}
- for (sa = ISC_LIST_HEAD(fctx->bad_edns); sa != NULL; sa = next_sa) {
- next_sa = ISC_LIST_NEXT(sa, link);
- ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
- isc_mem_put(fctx->mctx, sa, sizeof(*sa));
- }
-
isc_counter_detach(&fctx->qc);
if (fctx->gqc != NULL) {
isc_counter_detach(&fctx->gqc);
ISC_LIST_INIT(fctx->forwarders);
ISC_LIST_INIT(fctx->bad);
ISC_LIST_INIT(fctx->edns);
- ISC_LIST_INIT(fctx->bad_edns);
ISC_LIST_INIT(fctx->validators);
atomic_init(&fctx->attributes, 0);
*/
rctx->retryopts |= DNS_FETCHOPT_NOEDNS0;
rctx->resend = true;
- add_bad_edns(fctx, &query->addrinfo->sockaddr);
inc_stats(fctx->res, dns_resstatscounter_edns0fail);
} else {
rctx->broken_server = result;
*/
rctx->retryopts |= DNS_FETCHOPT_NOEDNS0;
rctx->resend = true;
- add_bad_edns(fctx, &query->addrinfo->sockaddr);
inc_stats(fctx->res, dns_resstatscounter_edns0fail);
} else {
rctx->broken_server = DNS_R_UNEXPECTEDRCODE;
resquery_t *query = rctx->query;
fetchctx_t *fctx = rctx->fctx;
- /*
- * We have an affirmative response to the query and we have
- * previously got a response from this server which indicated
- * EDNS may not be supported so we can now cache the lack of
- * EDNS support.
- */
- if (rctx->opt == NULL && !EDNSOK(query->addrinfo) &&
- (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(
- 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,
- FCTX_ADDRINFO_NOEDNS0,
- FCTX_ADDRINFO_NOEDNS0);
- } else if (rctx->opt == NULL &&
- (query->rmessage->flags & DNS_MESSAGEFLAG_TC) == 0 &&
- !EDNSOK(query->addrinfo) &&
- (query->rmessage->rcode == dns_rcode_noerror ||
- query->rmessage->rcode == dns_rcode_nxdomain) &&
- (rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
- {
- /*
- * We didn't get a OPT record in response to a EDNS
- * query.
- *
- * Old versions of named incorrectly drop the OPT record
- * when there is a signed, truncated response so we
- * check that TC is not set.
- *
- * Record that the server is not talking EDNS. While
- * this should be safe to do for any rcode we limit it
- * to NOERROR and NXDOMAIN.
- */
- dns_message_logpacket(
- query->rmessage, "received packet (no opt) from",
- &query->addrinfo->sockaddr, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
- fctx->res->mctx);
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- FCTX_ADDRINFO_NOEDNS0,
- FCTX_ADDRINFO_NOEDNS0);
- }
-
/*
* If we get a non error EDNS response record the fact so we
* won't fallback to plain DNS in the future for this server.
/*
* Remember that they may not like EDNS0.
*/
- add_bad_edns(fctx, &query->addrinfo->sockaddr);
inc_stats(fctx->res, dns_resstatscounter_edns0fail);
} else if (rcode == dns_rcode_formerr) {
if (query->rmessage->cc_echoed) {