e334405421979688f2d838805ac67ee47bd62976Mark Andrews/*
6fb9b25791778f69002eb72be6235e20d98ec452Tinderbox User * Copyright (C) 2010, 2011, 2014, 2016, 2017 Internet Systems Consortium, Inc. ("ISC")
b8a9a7bef2c3060204c68aef4f3fce04afc1aaeeAutomatic Updater *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
c1aef54e14bb92518b1c062ba8c0292a7cb949cbAutomatic Updater/* $Id: dns64.c,v 1.8 2011/03/12 04:59:47 tbox Exp $ */
b8a9a7bef2c3060204c68aef4f3fce04afc1aaeeAutomatic Updater
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <config.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <isc/list.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <isc/mem.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <isc/netaddr.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <isc/string.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <isc/util.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <dns/acl.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <dns/dns64.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <dns/rdata.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <dns/rdataset.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews#include <dns/result.h>
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsstruct dns_dns64 {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned char bits[16]; /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * Prefix + suffix bits.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_t * clients; /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * Which clients get mapped
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * addresses.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_t * mapped; /*
b8a9a7bef2c3060204c68aef4f3fce04afc1aaeeAutomatic Updater * IPv4 addresses to be mapped.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_t * excluded; /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * IPv6 addresses that are
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * treated as not existing.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int prefixlen; /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * Start of mapped address.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int flags;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_mem_t * mctx;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews ISC_LINK(dns_dns64_t) link;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews};
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsisc_result_t
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int prefixlen, isc_netaddr_t *suffix,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_t *clients, dns_acl_t *mapped, dns_acl_t *excluded,
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews unsigned int flags, dns_dns64_t **dns64p)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews{
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns_dns64_t *dns64;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int nbytes = 16;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(prefix != NULL && prefix->family == AF_INET6);
f2ea8c2f965be7ff4c59f805712c12d469226b7bEvan Hunt /* Legal prefix lengths from rfc6052.txt. */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
e334405421979688f2d838805ac67ee47bd62976Mark Andrews prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(isc_netaddr_prefixok(prefix, prefixlen) == ISC_R_SUCCESS);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews REQUIRE(dns64p != NULL && *dns64p == NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (suffix != NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews static const unsigned char zeros[16];
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(prefix->family == AF_INET6);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews nbytes = prefixlen / 8 + 4;
f2ea8c2f965be7ff4c59f805712c12d469226b7bEvan Hunt /* Bits 64-71 are zeros. rfc6052.txt */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (prefixlen >= 32 && prefixlen <= 64)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews nbytes++;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(memcmp(suffix->type.in6.s6_addr, zeros, nbytes) == 0);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64 = isc_mem_get(mctx, sizeof(dns_dns64_t));
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews if (dns64 == NULL)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (ISC_R_NOMEMORY);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews memset(dns64->bits, 0, sizeof(dns64->bits));
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews memmove(dns64->bits, prefix->type.in6.s6_addr, prefixlen / 8);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (suffix != NULL)
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews memmove(dns64->bits + nbytes, suffix->type.in6.s6_addr + nbytes,
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt 16 - nbytes);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64->clients = NULL;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (clients != NULL)
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns_acl_attach(clients, &dns64->clients);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64->mapped = NULL;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (mapped != NULL)
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns_acl_attach(mapped, &dns64->mapped);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64->excluded = NULL;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (excluded != NULL)
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns_acl_attach(excluded, &dns64->excluded);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64->prefixlen = prefixlen;
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64->flags = flags;
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews ISC_LINK_INIT(dns64, link);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews dns64->mctx = NULL;
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews isc_mem_attach(mctx, &dns64->mctx);
bfde61d5194a534d800f3b90008d1f52261922c5Mark Andrews *dns64p = dns64;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (ISC_R_SUCCESS);
44c0cfd2be65cebdfce66e0911c4da11186ee651Mark Andrews}
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsvoid
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_destroy(dns_dns64_t **dns64p) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_dns64_t *dns64;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(dns64p != NULL && *dns64p != NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns64 = *dns64p;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews *dns64p = NULL;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(!ISC_LINK_LINKED(dns64, link));
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->clients != NULL)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_detach(&dns64->clients);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->mapped != NULL)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_detach(&dns64->mapped);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->excluded != NULL)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_acl_detach(&dns64->excluded);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_mem_putanddetach(&dns64->mctx, dns64, sizeof(*dns64));
e334405421979688f2d838805ac67ee47bd62976Mark Andrews}
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsisc_result_t
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews const dns_name_t *reqsigner, const dns_aclenv_t *env,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int flags, unsigned char *a, unsigned char *aaaa)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews{
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int nbytes, i;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_result_t result;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews int match;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
e334405421979688f2d838805ac67ee47bd62976Mark Andrews (flags & DNS_DNS64_RECURSIVE) == 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (DNS_R_DISALLOWED);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
e334405421979688f2d838805ac67ee47bd62976Mark Andrews (flags & DNS_DNS64_DNSSEC) != 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (DNS_R_DISALLOWED);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->clients != NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews &match, NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (result != ISC_R_SUCCESS)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (result);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (match <= 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (DNS_R_DISALLOWED);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
b8a9a7bef2c3060204c68aef4f3fce04afc1aaeeAutomatic Updater
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->mapped != NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews struct in_addr ina;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_netaddr_t netaddr;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(&ina.s_addr, a, 4);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_netaddr_fromin(&netaddr, &ina);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews result = dns_acl_match(&netaddr, NULL, dns64->mapped, env,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews &match, NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (result != ISC_R_SUCCESS)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (result);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (match <= 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (DNS_R_DISALLOWED);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews nbytes = dns64->prefixlen / 8;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews INSIST(nbytes <= 12);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews /* Copy prefix. */
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(aaaa, dns64->bits, nbytes);
f2ea8c2f965be7ff4c59f805712c12d469226b7bEvan Hunt /* Bits 64-71 are zeros. rfc6052.txt */
1e442d19949b84d448742672e2ed8cab1177abb6Mark Andrews if (nbytes == 8)
1e442d19949b84d448742672e2ed8cab1177abb6Mark Andrews aaaa[nbytes++] = 0;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews /* Copy mapped address. */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews for (i = 0; i < 4U; i++) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews aaaa[nbytes++] = a[i];
f2ea8c2f965be7ff4c59f805712c12d469226b7bEvan Hunt /* Bits 64-71 are zeros. rfc6052.txt */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (nbytes == 8)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews aaaa[nbytes++] = 0;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews /* Copy suffix. */
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(aaaa + nbytes, dns64->bits + nbytes, 16 - nbytes);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (ISC_R_SUCCESS);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews}
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_t *
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_next(dns_dns64_t *dns64) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns64 = ISC_LIST_NEXT(dns64, link);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (dns64);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews}
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsvoid
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews ISC_LIST_APPEND(*list, dns64, link);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews}
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsvoid
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews ISC_LIST_UNLINK(*list, dns64, link);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews}
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsisc_boolean_t
e334405421979688f2d838805ac67ee47bd62976Mark Andrewsdns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
b8a9a7bef2c3060204c68aef4f3fce04afc1aaeeAutomatic Updater const dns_name_t *reqsigner, const dns_aclenv_t *env,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int flags, dns_rdataset_t *rdataset,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_boolean_t *aaaaok, size_t aaaaoklen)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews{
e334405421979688f2d838805ac67ee47bd62976Mark Andrews struct in6_addr in6;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_netaddr_t netaddr;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_result_t result;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews int match;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_boolean_t answer = ISC_FALSE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_boolean_t found = ISC_FALSE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews unsigned int i, ok;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(rdataset != NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(rdataset->type == dns_rdatatype_aaaa);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(rdataset->rdclass == dns_rdataclass_in);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (aaaaok != NULL)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews REQUIRE(aaaaoklen == dns_rdataset_count(rdataset));
b8a9a7bef2c3060204c68aef4f3fce04afc1aaeeAutomatic Updater
e334405421979688f2d838805ac67ee47bd62976Mark Andrews for (;dns64 != NULL; dns64 = ISC_LIST_NEXT(dns64, link)) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
e334405421979688f2d838805ac67ee47bd62976Mark Andrews (flags & DNS_DNS64_RECURSIVE) == 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews continue;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
e334405421979688f2d838805ac67ee47bd62976Mark Andrews (flags & DNS_DNS64_DNSSEC) != 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews continue;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * Work out if this dns64 structure applies to this client.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->clients != NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews result = dns_acl_match(reqaddr, reqsigner,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns64->clients, env,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews &match, NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (result != ISC_R_SUCCESS)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews continue;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (match <= 0)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews continue;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (!found && aaaaok != NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews for (i = 0; i < aaaaoklen; i++)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews aaaaok[i] = ISC_FALSE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews found = ISC_TRUE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * If we are not excluding any addresses then any AAAA
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * will do.
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (dns64->excluded == NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews answer = ISC_TRUE;
cf4ceeee5fee2ebdca74f82514c14fd50939f85bMark Andrews if (aaaaok == NULL)
cf4ceeee5fee2ebdca74f82514c14fd50939f85bMark Andrews goto done;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews for (i = 0; i < aaaaoklen; i++)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews aaaaok[i] = ISC_TRUE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews goto done;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews i = 0; ok = 0;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews for (result = dns_rdataset_first(rdataset);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews result == ISC_R_SUCCESS;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews result = dns_rdataset_next(rdataset)) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (aaaaok == NULL || !aaaaok[i]) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns_rdataset_current(rdataset, &rdata);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(&in6.s6_addr, rdata.data, 16);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews isc_netaddr_fromin6(&netaddr, &in6);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews result = dns_acl_match(&netaddr, NULL,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews dns64->excluded,
e334405421979688f2d838805ac67ee47bd62976Mark Andrews env, &match, NULL);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (result == ISC_R_SUCCESS && match <= 0) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews answer = ISC_TRUE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (aaaaok == NULL)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews goto done;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews aaaaok[i] = ISC_TRUE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews ok++;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews } else
e334405421979688f2d838805ac67ee47bd62976Mark Andrews ok++;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews i++;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews /*
e334405421979688f2d838805ac67ee47bd62976Mark Andrews * Are all addresses ok?
e334405421979688f2d838805ac67ee47bd62976Mark Andrews */
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (aaaaok != NULL && ok == aaaaoklen)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews goto done;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews
e334405421979688f2d838805ac67ee47bd62976Mark Andrews done:
e334405421979688f2d838805ac67ee47bd62976Mark Andrews if (!found && aaaaok != NULL) {
e334405421979688f2d838805ac67ee47bd62976Mark Andrews for (i = 0; i < aaaaoklen; i++)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews aaaaok[i] = ISC_TRUE;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews }
e334405421979688f2d838805ac67ee47bd62976Mark Andrews return (found ? answer : ISC_TRUE);
e334405421979688f2d838805ac67ee47bd62976Mark Andrews}