0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews/*
a134177ed9f82189504191d90f3ed9e97c2b47cbTinderbox User * Copyright (C) 2009, 2011, 2012, 2015, 2016 Internet Systems Consortium, Inc. ("ISC")
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
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/.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id$ */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews/*! \file */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews/***
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *** Imports
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ***/
12ff7274fe2ea531ecca6a71fb9f7e1ae92da389Mark Andrews
12ff7274fe2ea531ecca6a71fb9f7e1ae92da389Mark Andrews#include <config.h>
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews#include <isc/string.h>
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews#include <isc/util.h>
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews#include <dns/db.h>
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews#include <dns/dbiterator.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dns/rdata.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <dns/rdataset.h>
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#include <dns/rdatasetiter.h>
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews#include <dns/result.h>
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#include <dns/rriterator.h>
0da29be670f6fa5b2a6320d9d843bc8b802c153aMark Andrews
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews/***
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *** RRiterator methods
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ***/
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsisc_result_t
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsdns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_stdtime_t now)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->magic = RRITERATOR_MAGIC;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->db = db;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->dbit = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->ver = ver;
1676408640d8283c9f17eec0b183e1302ea7fd70Mark Andrews it->now = now;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->node = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_db_createiterator(it->db, 0, &it->dbit);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->rdatasetit = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdata_init(&it->rdata);
0da29be670f6fa5b2a6320d9d843bc8b802c153aMark Andrews dns_rdataset_init(&it->rdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fixedname_init(&it->fixedname);
0da29be670f6fa5b2a6320d9d843bc8b802c153aMark Andrews INSIST(! dns_rdataset_isassociated(&it->rdataset));
0da29be670f6fa5b2a6320d9d843bc8b802c153aMark Andrews it->result = ISC_R_SUCCESS;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsisc_result_t
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrewsdns_rriterator_first(dns_rriterator_t *it) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_RRITERATOR(it));
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews /* Reset state */
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (dns_rdataset_isassociated(&it->rdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&it->rdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (it->rdatasetit != NULL)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdatasetiter_destroy(&it->rdatasetit);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (it->node != NULL)
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews dns_db_detachnode(it->db, &it->node);
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews it->result = dns_dbiterator_first(it->dbit);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews /*
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * The top node may be empty when out of zone glue exists.
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews * Walk the tree to find the first node with data.
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt while (it->result == ISC_R_SUCCESS) {
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews it->result = dns_dbiterator_current(it->dbit, &it->node,
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews dns_fixedname_name(&it->fixedname));
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews if (it->result != ISC_R_SUCCESS)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (it->result);
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews it->now, &it->rdatasetit);
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews if (it->result != ISC_R_SUCCESS)
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews return (it->result);
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews it->result = dns_rdatasetiter_first(it->rdatasetit);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews if (it->result != ISC_R_SUCCESS) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * This node is empty. Try next node.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews dns_rdatasetiter_destroy(&it->rdatasetit);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews dns_db_detachnode(it->db, &it->node);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews it->result = dns_dbiterator_next(it->dbit);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews continue;
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews }
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews dns_rdataset_getownercase(&it->rdataset,
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews dns_fixedname_name(&it->fixedname));
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews it->result = dns_rdataset_first(&it->rdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsisc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_rriterator_nextrrset(dns_rriterator_t *it) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_RRITERATOR(it));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdataset_isassociated(&it->rdataset))
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_disassociate(&it->rdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->result = dns_rdatasetiter_next(it->rdatasetit);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * The while loop body is executed more than once
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * only when an empty dbnode needs to be skipped.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
ad1317338af79edad878c9c3e4361798503310baMark Andrews while (it->result == ISC_R_NOMORE) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdatasetiter_destroy(&it->rdatasetit);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_db_detachnode(it->db, &it->node);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->result = dns_dbiterator_next(it->dbit);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (it->result == ISC_R_NOMORE) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* We are at the end of the entire database. */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
ad1317338af79edad878c9c3e4361798503310baMark Andrews if (it->result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->result = dns_dbiterator_current(it->dbit, &it->node,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fixedname_name(&it->fixedname));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (it->result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->now, &it->rdatasetit);
ad1317338af79edad878c9c3e4361798503310baMark Andrews if (it->result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->result = dns_rdatasetiter_first(it->rdatasetit);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (it->result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_rdataset_getownercase(&it->rdataset,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fixedname_name(&it->fixedname));
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrews it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrews it->result = dns_rdataset_first(&it->rdataset);
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrews return (it->result);
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrews}
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrews
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrewsisc_result_t
21c8938824a2445bc750ba9c395a0d857f50ad72Tinderbox Userdns_rriterator_next(dns_rriterator_t *it) {
75ae74f8fd0847817bce2db7c868b179db67f019Mark Andrews REQUIRE(VALID_RRITERATOR(it));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (it->result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (it->result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(it->dbit != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(it->node != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(it->rdatasetit != NULL);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews it->result = dns_rdataset_next(&it->rdataset);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews if (it->result == ISC_R_NOMORE)
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews return (dns_rriterator_nextrrset(it));
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews return (it->result);
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews}
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrewsvoid
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrewsdns_rriterator_pause(dns_rriterator_t *it) {
3dd63ba00f91f4d54ba45ba1831375950758c0a7Mark Andrews REQUIRE(VALID_RRITERATOR(it));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvoid
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsdns_rriterator_destroy(dns_rriterator_t *it) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_RRITERATOR(it));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (dns_rdataset_isassociated(&it->rdataset))
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews dns_rdataset_disassociate(&it->rdataset);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews if (it->rdatasetit != NULL)
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews dns_rdatasetiter_destroy(&it->rdatasetit);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews if (it->node != NULL)
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews dns_db_detachnode(it->db, &it->node);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews dns_dbiterator_destroy(&it->dbit);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews}
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrewsvoid
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntdns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews isc_uint32_t *ttl, dns_rdataset_t **rdataset,
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews dns_rdata_t **rdata)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt{
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews REQUIRE(name != NULL && *name == NULL);
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews REQUIRE(VALID_RRITERATOR(it));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(it->result == ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(rdataset == NULL || *rdataset == NULL);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews REQUIRE(rdata == NULL || *rdata == NULL);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews *name = dns_fixedname_name(&it->fixedname);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews *ttl = it->rdataset.ttl;
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews dns_rdata_reset(&it->rdata);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews dns_rdataset_current(&it->rdataset, &it->rdata);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews if (rdataset != NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *rdataset = &it->rdataset;
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews if (rdata != NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *rdata = &it->rdata;
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews}
aaaf8d4f4873d21e55c3ffb4f656203d08339865Mark Andrews