resolver-nonbackoff-tries <integer>;
resolver-query-timeout <integer>;
resolver-retry-interval <integer>;
+ resolver-use-dns64 <boolean>;
response-padding { <address_match_element>; ... } block-size <integer>;
response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
reuseport <boolean>;
resolver-nonbackoff-tries <integer>;
resolver-query-timeout <integer>;
resolver-retry-interval <integer>;
+ resolver-use-dns64 <boolean>;
response-padding { <address_match_element>; ... } block-size <integer>;
response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
root-key-sentinel <boolean>;
#include <dns/cache.h>
#include <dns/db.h>
#include <dns/dispatch.h>
+#include <dns/dns64.h>
#include <dns/dnstap.h>
#include <dns/ds.h>
#include <dns/edns.h>
unsigned int options) {
isc_result_t result;
dns_resolver_t *res = NULL;
+ dns_dns64_t *dns64 = NULL;
resquery_t *query = NULL;
- isc_sockaddr_t addr;
+ isc_sockaddr_t addr, sockaddr;
bool have_addr = false;
unsigned int srtt;
isc_tlsctx_cache_t *tlsctx_cache = NULL;
query->start = isc_time_now();
/*
- * If this is a TCP query, then we need to make a socket and
- * a dispatch for it here. Otherwise we use the resolver's
- * shared dispatch.
+ * Maybe apply DNS64 mappings to IPv4 addresses.
*/
+ sockaddr = addrinfo->sockaddr;
+ dns64 = ISC_LIST_HEAD(fctx->res->view->dns64);
+ if (isc_sockaddr_pf(&sockaddr) == AF_INET &&
+ fctx->res->view->usedns64 && dns64 != NULL)
+ {
+ struct in6_addr aaaa;
+
+ result = dns_dns64_aaaafroma(
+ dns64, NULL, NULL, fctx->res->view->aclenv, 0,
+ (unsigned char *)&sockaddr.type.sin.sin_addr.s_addr,
+ aaaa.s6_addr);
+ if (result == ISC_R_SUCCESS) {
+ char sockaddrbuf1[ISC_SOCKADDR_FORMATSIZE];
+ char sockaddrbuf2[ISC_SOCKADDR_FORMATSIZE];
+
+ /* format old address */
+ isc_sockaddr_format(&sockaddr, sockaddrbuf1,
+ sizeof(sockaddrbuf1));
+
+ /* replace address */
+ isc_sockaddr_fromin6(&sockaddr, &aaaa,
+ ntohs(sockaddr.type.sin.sin_port));
+ addrinfo->sockaddr = sockaddr;
+
+ /* format new address */
+ isc_sockaddr_format(&sockaddr, sockaddrbuf2,
+ sizeof(sockaddrbuf2));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+ "Using DNS64 address %s to talk to %s\n",
+ sockaddrbuf2, sockaddrbuf1);
+ }
+ }
if (res->view->peers != NULL) {
dns_peer_t *peer = NULL;
isc_netaddr_t dstip;
bool usetcp = false;
- isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr);
+ isc_netaddr_fromsockaddr(&dstip, &sockaddr);
result = dns_peerlist_peerbyaddr(res->view->peers, &dstip,
&peer);
if (result == ISC_R_SUCCESS) {
}
}
+ /*
+ * If this is a TCP query, then we need to make a socket and
+ * a dispatch for it here. Otherwise we use the resolver's
+ * shared dispatch.
+ */
if ((query->options & DNS_FETCHOPT_TCP) != 0) {
int pf;
- pf = isc_sockaddr_pf(&addrinfo->sockaddr);
+ pf = isc_sockaddr_pf(&sockaddr);
if (!have_addr) {
switch (pf) {
case PF_INET:
isc_sockaddr_setport(&addr, 0);
result = dns_dispatch_createtcp(res->view->dispatchmgr, &addr,
- &addrinfo->sockaddr,
- &query->dispatch);
+ &sockaddr, &query->dispatch);
if (result != ISC_R_SUCCESS) {
goto cleanup_query;
}
goto cleanup_query;
}
} else {
- switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
+ switch (isc_sockaddr_pf(&sockaddr)) {
case PF_INET:
dns_dispatch_attach(
dns_resolver_dispatchv4(res),
UNLOCK(&fctx->lock);
/* Set up the dispatch and set the query ID */
- result = dns_dispatch_add(
- query->dispatch, fctx->loop, 0,
- isc_interval_ms(&fctx->interval), &query->addrinfo->sockaddr,
- addrinfo->transport, tlsctx_cache, resquery_connected,
- resquery_senddone, resquery_response, query, &query->id,
- &query->dispentry);
+ result = dns_dispatch_add(query->dispatch, fctx->loop, 0,
+ isc_interval_ms(&fctx->interval), &sockaddr,
+ addrinfo->transport, tlsctx_cache,
+ resquery_connected, resquery_senddone,
+ resquery_response, query, &query->id,
+ &query->dispentry);
if (result != ISC_R_SUCCESS) {
goto cleanup_udpfetch;
}