update.c revision 8803b0510877fd08044542edbb55e2be72fae36f
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Copyright (C) 1999 Internet Software Consortium.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Permission to use, copy, modify, and distribute this software for any
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * purpose with or without fee is hereby granted, provided that the above
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * copyright notice and this permission notice appear in all copies.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * SOFTWARE.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <config.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <stdio.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <stdlib.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <unistd.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <string.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <isc/assertions.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <isc/error.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <isc/mem.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <isc/result.h>
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson#include <isc/taskpool.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/db.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/dbiterator.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/dbtable.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/dnssec.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/events.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/fixedname.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/journal.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/message.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/name.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/nxt.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/rdata.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/rdatalist.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/rdataset.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/rdatasetiter.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/rdatastruct.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/result.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/types.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <dns/view.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/zone.h>
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley#include <dns/zt.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <named/globals.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <named/client.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson#include <named/update.h>
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#include <named/log.h>
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * This module implements dynamic update as in RFC2136.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson XXX TODO:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson - forwarding
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson - document strict minimality
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson*/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson/**************************************************************************/
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson/*
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * Convenience macro of common isc_log_write() arguments
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * to use in reportings server errors.
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define UPDATE_ERROR_LOGARGS \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ISC_LOG_ERROR
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson/*
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * Convenience macro of common isc_log_write() arguments
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * to use in tracing dynamic update protocol requests.
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define UPDATE_PROTOCOL_LOGARGS \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ISC_LOG_INFO
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson/*
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * Convenience macro of common isc_log_write() arguments
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * to use in low-level debug tracing.
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define UPDATE_DEBUG_LOGARGS \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ISC_LOG_DEBUG(8)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson/*
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * Check an operation for failure. These macros all assume that
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * the function using them has a 'result' variable and a 'failure'
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * label.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define CHECK(op) \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson do { result = (op); \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson if (result != DNS_R_SUCCESS) goto failure; \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson } while (0)
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson/*
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * Fail unconditionally with result 'code', which must not
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * be DNS_R_SUCCESS. The reason for failure presumably has
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * been logged already.
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define FAIL(code) \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson do { \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson result = (code); \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson goto failure; \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson } while (0)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson/*
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * Fail unconditionally and log as a client error.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define FAILC(code, msg) \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson do { \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS, \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "dynamic update failed: %s (%s)", \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson msg, isc_result_totext(code)); \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson goto failure; \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson } while (0)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson/*
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson * Fail unconditionally and log as a server error.
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson#define FAILS(code, msg) \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson do { \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS, \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "dynamic update error: %s: %s", \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson msg, isc_result_totext(code)); \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson goto failure; \
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson } while (0)
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson/**************************************************************************/
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef struct rr rr_t;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstruct rr {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* dns_name_t name; */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_uint32_t ttl;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_rdata_t rdata;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson};
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssontypedef struct update_event update_event_t;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonstruct update_event {
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson ISC_EVENT_COMMON(update_event_t);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_zone_t *zone;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_result_t result;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson};
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson/**************************************************************************/
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson/*
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson * Forward declarations.
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonstatic void update_action(isc_task_t *task, isc_event_t *event);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonstatic void updatedone_action(isc_task_t *task, isc_event_t *event);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Update a single RR in version 'ver' of 'db' and log the
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * update in 'diff'.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Ensures:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * '*tuple' == NULL. Either the tuple is freed, or its
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * ownership has been transferred to the diff.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssondo_one_tuple(dns_difftuple_t **tuple,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_t *db, dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t *diff)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t temp_diff;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Create a singleton diff */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_init(diff->mctx, &temp_diff);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Apply it to the database. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_diff_apply(&temp_diff, db, ver);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_free(tuple);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Merge it into the current pending journal entry. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_appendminimal(diff, tuple);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Do not clear temp_diff. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonupdate_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diffop_t op, dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_ttl_t ttl, dns_rdata_t *rdata)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *tuple = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_difftuple_create(diff->mctx, op,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson name, ttl, rdata, &tuple);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (do_one_tuple(&tuple, db, ver, diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Callback-style iteration over rdatasets and rdatas.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * foreach_rrset() can be used to iterate over the RRsets
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * of a name and call a callback function with each
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * one. Similarly, foreach_rr() can be used to iterate
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * over the individual RRs at name, optionally restricted
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * to RRs of a given type.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * The callback functions are called "actions" and take
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * two arguments: a void pointer for passing arbitrary
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * context information, and a pointer to the current RRset
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * or RR. By convention, their names end in "_action".
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * XXXRTH We might want to make this public somewhere in libdns.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Function type for foreach_rrset() iterator actions. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef dns_result_t rrset_func(void *data, dns_rdataset_t *rrset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Function type for foreach_rr() iterator actions. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef dns_result_t rr_func(void *data, rr_t *rr);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Internal context struct for foreach_node_rr(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef struct {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_func * rr_action;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson void * rr_action_data;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson} foreach_node_rr_ctx_t;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Internal helper function for foreach_node_rr(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonforeach_node_rr_action(void *data, dns_rdataset_t *rdataset)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson foreach_node_rr_ctx_t *ctx = data;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_rdataset_first(rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_rdataset_next(rdataset))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_t rr;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_current(rdataset, &rr.rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr.ttl = rdataset->ttl;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = (*ctx->rr_action)(ctx->rr_action_data, &rr);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * For each rdataset of 'name' in 'ver' of 'db', call 'action'
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * with the rdataset and 'action_data' as arguments. If the name
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * does not exist, do nothing.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * If 'action' returns an error, abort iteration and return the error.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonforeach_rrset(dns_db_t *db,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rrset_func *action,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson void *action_data)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbnode_t *node;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatasetiter_t *iter;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson node = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_db_findnode(db, name, ISC_FALSE, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result == DNS_R_NOTFOUND)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson iter = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_db_allrdatasets(db, node, ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson (isc_stdtime_t) 0, &iter);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto cleanup_node;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_rdatasetiter_first(iter);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_rdatasetiter_next(iter))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_t rdataset;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_init(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatasetiter_current(iter, &rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = (*action)(action_data, &rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_disassociate(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto cleanup_iterator;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result == DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson cleanup_iterator:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatasetiter_destroy(&iter);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson cleanup_node:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_detachnode(db, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * For each RR of 'name' in 'ver' of 'db', call 'action'
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * with the RR and 'action_data' as arguments. If the name
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * does not exist, do nothing.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * If 'action' returns an error, abort iteration
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * and return the error.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonforeach_node_rr(dns_db_t *db,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_func *rr_action,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson void *rr_action_data)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson foreach_node_rr_ctx_t ctx;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.rr_action = rr_action;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.rr_action_data = rr_action_data;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (foreach_rrset(db, ver, name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson foreach_node_rr_action, &ctx));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley * For each of the RRs specified by 'db', 'ver', 'name', 'type',
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley * (which can be dns_rdatatype_any to match any type), and 'covers', call
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley * 'action' with the RR and 'action_data' as arguments. If the name
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * does not exist, or if no RRset of the given type exists at the name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * do nothing.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * If 'action' returns an error, abort iteration and return the error.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonforeach_rr(dns_db_t *db,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatatype_t type,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_func *rr_action,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson void *rr_action_data)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbnode_t *node;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_t rdataset;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (type == dns_rdatatype_any)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (foreach_node_rr(db, ver, name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_action, rr_action_data));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson node = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_db_findnode(db, name, ISC_FALSE, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result == DNS_R_NOTFOUND)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_init(&rdataset);
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley result = dns_db_findrdataset(db, node, ver, type, covers,
9637357a7765cc63ae401e02c727b1202f20bc08Bob Halley (isc_stdtime_t) 0, &rdataset, NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result == DNS_R_NOTFOUND) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto cleanup_node;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto cleanup_node;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_rdataset_first(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_rdataset_next(&rdataset))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_t rr;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_current(&rdataset, &rr.rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr.ttl = rdataset.ttl;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = (*rr_action)(rr_action_data, &rr);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto cleanup_rdataset;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto cleanup_rdataset;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson cleanup_rdataset:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_disassociate(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson cleanup_node:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_detachnode(db, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Various tests on the database contents (for prerequisites, etc).
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Function type for predicate functions that compare a database RR 'db_rr'
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * against an update RR 'update_rr'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef isc_boolean_t rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Helper function for rrset_exists(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonrrset_exists_action(void *data, rr_t *rr) /*ARGSUSED*/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson data = data; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr = rr; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_EXISTS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson/*
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * Utility macro for RR existence checking functions.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson *
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * If the variable 'result' has the value DNS_R_EXISTS or
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * DNS_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE,
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * respectively, and return success.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson *
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * If 'result' has any other value, there was a failure.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * Return the failure result code and do not set *exists.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson *
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * This would be more readable as "do { if ... } while(0)",
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson * but that form generates tons of warnings on Solaris 2.6.
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson */
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson#define RETURN_EXISTENCE_FLAG \
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson return ((result == DNS_R_EXISTS) ? \
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson (*exists = ISC_TRUE, DNS_R_SUCCESS) : \
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson ((result == DNS_R_SUCCESS) ? \
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson (*exists = ISC_FALSE, DNS_R_SUCCESS) : \
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson result));
f4c0131a46ea183238027ef9c3400cc6079b8b85Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Set '*exists' to true iff an rrset of the given type exists,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * to false otherwise.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonrrset_exists(dns_db_t *db, dns_dbversion_t *ver,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley isc_boolean_t *exists)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley result = foreach_rr(db, ver, name, type, covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rrset_exists_action, NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson RETURN_EXISTENCE_FLAG;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Helper function for cname_incompatible_rrset_exists */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssoncname_compatibility_action(void *data, dns_rdataset_t *rrset)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*ARGSUSED*/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson data = data; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rrset->type != dns_rdatatype_cname &&
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ! dns_rdatatype_isdnssec(rrset->type))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_EXISTS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Check whether there is an rrset incompatible with adding a CNAME RR,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * i.e., anything but another CNAME (which can be replaced) or a
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * DNSSEC RR (which can coexist).
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * If such an incompatible rrset exists, set '*exists' to ISC_TRUE.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Otherwise, set it to ISC_FALSE.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssoncname_incompatible_rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name, isc_boolean_t *exists) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = foreach_rrset(db, ver, name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson cname_compatibility_action, NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson RETURN_EXISTENCE_FLAG;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Helper function for rr_count(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssoncount_rr_action(void *data, rr_t *rr) /*ARGSUSED*/ {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson int *countp = data;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr = rr; /* Unused. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson (*countp)++;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Count the number of RRs of 'type' belonging to 'name' in 'ver' of 'db'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonrr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t type, dns_rdatatype_t covers, int *countp)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *countp = 0;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley return (foreach_rr(db, ver, name, type, covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson count_rr_action, countp));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Context struct for matching_rr_exists(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef struct {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_predicate *predicate;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_t *db;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t *update_rr;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson} matching_rr_exists_ctx_t;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Helper function for matching_rr_exists(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonmatching_rr_exists_action(void *data, rr_t *rr) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson matching_rr_exists_ctx_t *ctx = data;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if ((*ctx->predicate)(ctx->update_rr, &rr->rdata))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_EXISTS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Compare the 'update_rr' with all RRs in the RRset specified by 'db',
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * 'ver', 'name', and 'type' using 'predicate'. If the predicate returns
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * true for at least one of them, set '*exists' to ISC_TRUE. Otherwise,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * set it to ISC_FALSE.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonmatching_rr_exists(rr_predicate *predicate,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_t *db,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatatype_t type,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t *update_rr,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_boolean_t *exists)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson matching_rr_exists_ctx_t ctx;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.predicate = predicate;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.db = db;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.ver = ver;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.name = name;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.update_rr = update_rr;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley result = foreach_rr(db, ver, name, type, covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson matching_rr_exists_action, &ctx);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson RETURN_EXISTENCE_FLAG;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Context struct and helper function for name_exists() */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonname_exists_action(void *data, dns_rdataset_t *rrset) /*ARGSUSED*/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson data = data; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rrset = rrset; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_EXISTS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Set '*exists' to true iff the given name exists, to false otherwise.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonname_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_boolean_t *exists)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = foreach_rrset(db, ver, name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson name_exists_action, NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson RETURN_EXISTENCE_FLAG;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Checking of "RRset exists (value dependent)" prerequisites.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * In the RFC2136 section 3.2.5, this is the pseudocode involving
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * a variable called "temp", a mapping of <name, type> tuples to rrsets.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Here, we represent the "temp" data structure as (non-minimial) "dns_diff_t"
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * where each typle has op==DNS_DIFFOP_EXISTS.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Append a tuple asserting the existence of the RR with
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * 'name' and 'rdata' to 'diff'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontemp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *tuple = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
297377a5029e71566d4158bae67f127a3e4f3fc3Bob Halley REQUIRE(DNS_DIFF_VALID(diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson name, 0, rdata, &tuple));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_APPEND(diff->tuples, tuple, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Compare two rdatasets represented as sorted lists of tuples.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * All list elements must have the same owner name and type.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Return DNS_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * if not.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontemp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (;;) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (a == NULL || b == NULL)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson break;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(a->op == DNS_DIFFOP_EXISTS && b->op == DNS_DIFFOP_EXISTS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(a->rdata.type == b->rdata.type);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(dns_name_equal(&a->name, &b->name));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (dns_rdata_compare(&a->rdata, &b->rdata) != 0)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_NXRRSET);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson a = ISC_LIST_NEXT(a, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson b = ISC_LIST_NEXT(b, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (a != NULL || b != NULL)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_NXRRSET);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * A comparison function defining the sorting order for the entries
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * in the "temp" data structure. The major sort key is the owner name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * followed by the type and rdata.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic int
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontemp_order(const void *av, const void *bv)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t * const *ap = av;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t * const *bp = bv;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *a = *ap;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *b = *bp;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson int r;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson r = dns_name_compare(&a->name, &b->name);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (r != 0)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (r);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson r = (b->rdata.type - a->rdata.type);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (r != 0)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (r);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson r = dns_rdata_compare(&a->rdata, &b->rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (r);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Check the "RRset exists (value dependent)" prerequisite information
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * in 'temp' against the contents of the database 'db'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Return DNS_R_SUCCESS if the prerequisites are satisfied,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * rcode(dns_rcode_nxrrset) if not.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontemp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbnode_t *node;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *t;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t trash;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Exit early if the list is empty (for efficiency only). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (ISC_LIST_HEAD(temp->tuples) == NULL)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Sort the prerequisite records by owner name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * type, and rdata.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_diff_sort(temp, temp_order);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_init(mctx, &trash);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * For each name and type in the prerequisites,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * construct a sorted rdata list of the corresponding
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * database contents, and compare the lists.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson t = ISC_LIST_HEAD(temp->tuples);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson while (t != NULL) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson name = &t->name;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* A new unique name begins here. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson node = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_db_findnode(db, name, ISC_FALSE, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result == DNS_R_NOTFOUND)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_NXRRSET);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* A new unique type begins here. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson while (t != NULL && dns_name_equal(&t->name, name)) {
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t type, covers;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_t rdataset;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t d_rrs; /* Database RRs with
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson this name and type */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t u_rrs; /* Update RRs with
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson this name and type */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson type = t->rdata.type;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley if (type == dns_rdatatype_sig)
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley covers = dns_rdata_covers(&t->rdata);
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley else
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley covers = 0;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Collect all database RRs for this name and type
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * onto d_rrs and sort them.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_init(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_db_findrdataset(db, node, ver, type,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley covers, (isc_stdtime_t) 0,
9637357a7765cc63ae401e02c727b1202f20bc08Bob Halley &rdataset, NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_detachnode(db, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_NXRRSET);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_init(mctx, &d_rrs);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_init(mctx, &u_rrs);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_rdataset_first(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_rdataset_next(&rdataset))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t rdata;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_current(&rdataset, &rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = temp_append(&d_rrs, name, &rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto failure;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto failure;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_diff_sort(&d_rrs, temp_order);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto failure;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Collect all update RRs for this name and type
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * onto u_rrs. No need to sort them here -
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * they are already sorted.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson while (t != NULL &&
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_equal(&t->name, name) &&
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson t->rdata.type == type)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *next =
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_NEXT(t, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_UNLINK(temp->tuples, t, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_APPEND(u_rrs.tuples, t, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson t = next;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Compare the two sorted lists. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples),
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_HEAD(d_rrs.tuples));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto failure;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * We are done with the tuples, but we can't free
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * them yet because "name" still points into one
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * of them. Move them on a temporary list.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_disassociate(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson failure:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_clear(&d_rrs);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_clear(&u_rrs);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_clear(&trash);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_disassociate(&rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_detachnode(db, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_detachnode(db, &node);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_clear(&trash);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Conditional deletion of RRs.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Context structure for delete_if(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontypedef struct {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr_predicate *predicate;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_t *db;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t *diff;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t *update_rr;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson} conditional_delete_ctx_t;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Predicate functions for delete_if(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Return true iff 'update_rr' is neither a SOA nor an NS RR. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic isc_boolean_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontype_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) /*ARGSUSED*/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson update_rr = update_rr; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return ((db_rr->type != dns_rdatatype_soa &&
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson db_rr->type != dns_rdatatype_ns) ?
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_TRUE : ISC_FALSE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Return true always. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic isc_boolean_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssontrue_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) /*ARGSUSED*/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson update_rr = update_rr; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson db_rr = db_rr; /* Unused */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (ISC_TRUE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Return true iff the two RRs have identical rdata. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic isc_boolean_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonrr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * XXXRTH This is not a problem, but we should consider creating
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * dns_rdata_equal() (that used dns_name_equal()), since it
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * would be faster. Not a priority.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (dns_rdata_compare(update_rr, db_rr) == 0 ?
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_TRUE : ISC_FALSE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Return true iff 'update_rr' should replace 'db_rr' according
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * to the special RFC2136 rules for CNAME, SOA, and WKS records.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic isc_boolean_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonreplaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (db_rr->type != update_rr->type)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (ISC_FALSE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (db_rr->type == dns_rdatatype_cname)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (ISC_TRUE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (db_rr->type == dns_rdatatype_soa)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (ISC_TRUE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * RFC2136 does not mention NXT, but multiple NXTs make little
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * sense, so we replace those, too.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (db_rr->type == dns_rdatatype_nxt)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (ISC_TRUE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (db_rr->type == dns_rdatatype_wks) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Compare the address and protocol fields only. These
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * form the first five bytes of the RR data. Do a
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * raw binary comparison; unpacking the WKS RRs using
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * dns_rdata_tostruct() might be cleaner in some ways,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * but it would require us to pass around an mctx.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(db_rr->length >= 5 && update_rr->length >= 5);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (memcmp(db_rr->data, update_rr->data, 5) == 0 ?
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ISC_TRUE : ISC_FALSE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (ISC_FALSE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/* Internal helper function for delete_if(). */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssondelete_if_action(void *data, rr_t *rr) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson conditional_delete_ctx_t *ctx = data;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = update_one_rr(ctx->db, ctx->ver, ctx->diff,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson DNS_DIFFOP_DEL, ctx->name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rr->ttl, &rr->rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Conditionally delete RRs. Apply 'predicate' to the RRs
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * specified by 'db', 'ver', 'name', and 'type' (which can
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * be dns_rdatatype_any to match any type). Delete those
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * RRs for which the predicate returns true, and log the
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * deletions in 'diff'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssondelete_if(rr_predicate *predicate,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_t *db,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatatype_t type,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t *update_rr,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t *diff)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson conditional_delete_ctx_t ctx;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.predicate = predicate;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.db = db;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.ver = ver;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.diff = diff;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.name = name;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson ctx.update_rr = update_rr;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley return (foreach_rr(db, ver, name, type, covers,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson delete_if_action, &ctx));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Miscellaneous subroutines.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Extract a single update RR from 'section' of dynamic update message
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * 'msg', with consistency checking.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Stores the owner name, rdata, and TTL of the update RR at 'name',
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * 'rdata', and 'ttl', respectively.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic void
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonget_current_rr(dns_message_t *msg, dns_section_t section,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataclass_t zoneclass,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_ttl_t *ttl,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataclass_t *update_class)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_t *rdataset;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_message_currentname(msg, section, name);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rdataset = ISC_LIST_HEAD((*name)->list);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(rdataset != NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley *covers = rdataset->covers;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *ttl = rdataset->ttl;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_rdataset_first(rdataset);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(result == DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_current(rdataset, rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson INSIST(dns_rdataset_next(rdataset) == DNS_R_NOMORE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *update_class = rdata->rdclass;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rdata->rdclass = zoneclass;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Increment the SOA serial number of database 'db', version 'ver'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Replace the SOA record in the database, and log the
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * change in 'diff'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * XXXRTH Failures in this routine will be worth logging, when
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * we have a logging system. Failure to find the zonename
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * or the SOA rdataset warrant at least an UNEXPECTED_ERROR().
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonincrement_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_t *diff, isc_mem_t *mctx)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *deltuple = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_t *addtuple = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_uint32_t serial;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(dns_difftuple_copy(deltuple, &addtuple));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson addtuple->op = DNS_DIFFOP_ADD;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson serial = dns_soa_getserial(&addtuple->rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* RFC1982 */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson serial = (serial + 1) & 0xFFFFFFFF;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (serial == 0)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson serial = 1;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_soa_setserial(serial, &addtuple->rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(do_one_tuple(&addtuple, db, ver, diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(do_one_tuple(&deltuple, db, ver, diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson failure:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (addtuple != NULL)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_free(&addtuple);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (deltuple != NULL)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_difftuple_free(&deltuple);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Check that the new SOA record at 'update_rdata' does not
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * illegally cause the SOA serial number to decrease or stay
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * unchanged relative to the existing SOA in 'db'.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Sets '*ok' to ISC_TRUE if the update is legal, ISC_FALSE if not.
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson *
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * William King points out that RFC2136 is inconsistent about
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * the case where the serial number stays unchanged:
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson *
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * section 3.4.2.2 requires a server to ignore a SOA update request
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * if the serial number on the update SOA is less_than_or_equal to
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * the zone SOA serial.
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson *
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * section 3.6 requires a server to ignore a SOA update request if
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * the serial is less_than the zone SOA serial.
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson *
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson * Paul says 3.4.2.2 is correct.
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson *
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssoncheck_soa_increment(dns_db_t *db, dns_dbversion_t *ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t *update_rdata,
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson isc_boolean_t *ok)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_uint32_t db_serial;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_uint32_t update_serial;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson update_serial = dns_soa_getserial(update_rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_db_getsoaserial(db, ver, &db_serial);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson if (DNS_SERIAL_GE(db_serial, update_serial)) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *ok = ISC_FALSE;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson *ok = ISC_TRUE;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson return (DNS_R_SUCCESS);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/**************************************************************************/
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Incremental updating of NXTs and SIGs.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson#define MAXZONEKEYS 32 /* Maximum number of zone keys supported. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * We abuse the dns_diff_t type to represent a set of domain names
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * affected by the update.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonnamelist_append_name(dns_diff_t *list, dns_name_t *name) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *tuple = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson static dns_rdata_t dummy_rdata = { NULL, 0, 0, 0, { NULL, NULL } };
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &dummy_rdata, &tuple));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_append(list, &tuple);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonnamelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_t fixedname;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_t *child;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbiterator_t *dbit = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_init(&fixedname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson child = dns_fixedname_name(&fixedname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (result = dns_dbiterator_seek(dbit, name);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result == DNS_R_SUCCESS;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = dns_dbiterator_next(dbit))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbnode_t *node = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = dns_dbiterator_current(dbit, &node, child);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (! dns_name_issubdomain(child, name))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson break;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(namelist_append_name(affected, child));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (dbit != NULL)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbiterator_destroy(&dbit);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/* Helper function for non_nxt_rrset_exists(). */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonis_non_nxt_action(void *data, dns_rdataset_t *rrset)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*ARGSUSED*/
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson data = data; /* Unused */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (!(rrset->type == dns_rdatatype_nxt ||
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson (rrset->type == dns_rdatatype_sig &&
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson rrset->covers == dns_rdatatype_nxt)))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (DNS_R_EXISTS);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (DNS_R_SUCCESS);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Check whether there is an rrset other than a NXT or SIG NXT,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * i.e., anything that justifies the continued existence of a name
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * after a secure update.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * If such an rrset exists, set '*exists' to ISC_TRUE.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Otherwise, set it to ISC_FALSE.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonnon_nxt_rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_t *name, isc_boolean_t *exists) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = foreach_rrset(db, ver, name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson is_non_nxt_action, NULL);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson RETURN_EXISTENCE_FLAG;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * A comparison function for sorting dns_diff_t:s by name.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic int
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonname_order(const void *av, const void *bv)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t * const *ap = av;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t * const *bp = bv;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *a = *ap;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *b = *bp;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (dns_name_compare(&a->name, &b->name));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonuniqify_name_list(dns_diff_t *list) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *p, *q;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_diff_sort(list, name_order));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson p = ISC_LIST_HEAD(list->tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while (p != NULL) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while (1) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson q = ISC_LIST_NEXT(p, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (q == NULL || ! dns_name_equal(&p->name, &q->name))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson break;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ISC_LIST_UNLINK(list->tuples, q, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_free(&q);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson p = ISC_LIST_NEXT(p, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonis_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_boolean_t *flag)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_t foundname;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_init(&foundname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = dns_db_find(db, name, ver, dns_rdatatype_any,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson (isc_stdtime_t) 0, NULL,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_name(&foundname),
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson NULL, NULL);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (result == DNS_R_SUCCESS) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *flag = ISC_FALSE;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (DNS_R_SUCCESS);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } else if (result == DNS_R_ZONECUT) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* XXX should omit non-delegation types from NXT */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *flag = ISC_FALSE;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (DNS_R_SUCCESS);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } else if (result == DNS_R_GLUE) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *flag = ISC_TRUE;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (DNS_R_SUCCESS);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } else {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Find the next/previous name that has a NXT record.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * In other words, skip empty database nodes and names that
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * have had their NXTs removed because they are obscured by
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * a zone cut.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonnext_active(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *oldname,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_t *newname, isc_boolean_t forward)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbiterator_t *dbit = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_boolean_t has_nxt;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_dbiterator_seek(dbit, oldname));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson do {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbnode_t *node = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (forward)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = dns_dbiterator_next(dbit);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson else
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = dns_dbiterator_prev(dbit);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (result == DNS_R_NOMORE) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Wrap around. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (forward)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_dbiterator_first(dbit));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson else
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_dbiterator_last(dbit));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbiterator_current(dbit, &node, newname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * The iterator may hold the tree lock, and
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson * rrset_exists() calls dns_db_findnode() which
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * may try to reacquire it. To avoid deadlock
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * we must pause the iterator first.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_dbiterator_pause(dbit));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(rrset_exists(db, ver, newname,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_nxt, 0, &has_nxt));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } while (! has_nxt);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (dbit != NULL)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbiterator_destroy(&dbit);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Add a NXT record for "name", recording the change in "diff".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonadd_nxt(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_diff_t *diff) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbnode_t *node = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned char buffer[DNS_NXT_BUFFERSIZE];
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdata_t rdata;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *tuple = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_t fixedname;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_t *target;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_init(&fixedname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson target = dns_fixedname_name(&fixedname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Find the successor name, aka NXT target. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(next_active(db, ver, name, target, ISC_TRUE));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Create the NXT RDATA. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdata_init(&rdata);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_buildnxtrdata(db, ver, node, target, buffer, &rdata));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Create a diff tuple, update the database, and record the change. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson 3600, /* XXXRTH */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &rdata, &tuple));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(do_one_tuple(&tuple, db, ver, diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson INSIST(tuple == NULL);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (node != NULL)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Add a placeholder NXT record for "name", recording the change in "diff".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonadd_placeholder_nxt(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_diff_t *diff) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *tuple = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_region_t r;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned char data[1] = { 0 }; /* The root domain, no bits. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdata_t rdata;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson r.base = data;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson r.length = sizeof data;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nxt, &r);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &rdata, &tuple));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(do_one_tuple(&tuple, db, ver, diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonfind_zone_keys(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbnode_t *node = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson mctx, maxkeys, keys, nkeys));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (node != NULL)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Add SIG records for an RRset, recording the change in "diff".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonadd_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t now,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_stdtime_t expire)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbnode_t *node = NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdataset_t rdataset;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdata_t sig_rdata;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_buffer_t buffer;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned char data[1024]; /* XXX */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned int i;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdataset_init(&rdataset);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_buffer_init(&buffer, data, sizeof data, ISC_BUFFERTYPE_BINARY);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Get the rdataset to sign. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_db_findrdataset(db, node, ver, type, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson (isc_stdtime_t) 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &rdataset, NULL));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (i = 0; i < nkeys; i++) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Calculate the signature, creating a SIG RDATA. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &now, &expire,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson mctx, &buffer, &sig_rdata));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Update the database and journal with the SIG. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* XXX inefficient - will cause dataset merging */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson rdataset.ttl, &sig_rdata));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (dns_rdataset_isassociated(&rdataset))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdataset_disassociate(&rdataset);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (node != NULL)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_detachnode(db, &node);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson/*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Update SIG and NXT records affected by an update. The original
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * update, including the SOA serial update but exluding the SIG & NXT
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * changes, is in "diff" and has already been applied to "newver" of "db".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * The database version prior to the update is "oldver".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * The necessary SIG and NXT changes will be applied to "newver"
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * and added (as a minimal diff) to "diff".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonstatic dns_result_t
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafssonupdate_signatures(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *oldver,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_dbversion_t *newver, dns_diff_t *diff)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson{
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_result_t result;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_difftuple_t *t;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_t diffnames;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_t affected;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_t sig_diff;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_t nxt_diff;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_t nxt_mindiff;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_boolean_t flag;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dst_key_t *zone_keys[MAXZONEKEYS];
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned int nkeys = 0;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson unsigned int i;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_stdtime_t now, expire;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_init(mctx, &diffnames);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_init(mctx, &affected);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_init(mctx, &sig_diff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_init(mctx, &nxt_diff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_init(mctx, &nxt_mindiff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = find_zone_keys(db, newver, mctx,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson MAXZONEKEYS, zone_keys, &nkeys);
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson if (result != DNS_R_SUCCESS) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson NS_LOGMODULE_UPDATE, ISC_LOG_ERROR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "could not get zone keys for secure "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "dynamic update");
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson goto failure;
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson }
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(isc_stdtime_get(&now));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson expire = 100000 + now; /* XXX */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Find all RRsets directly affected by the update, and
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * update their SIGs. Also build a list of names affected
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * by the update in "diffnames".
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(dns_diff_sort(diff, temp_order));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_HEAD(diff->tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while (t != NULL) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_t *name = &t->name;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Now "name" is a new, unique name affected by the update. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(namelist_append_name(&diffnames, name));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while (t != NULL && dns_name_equal(&t->name, name)) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_t type;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson type = t->rdata.type;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Now "name" and "type" denote a new unique RRset
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * affected by the update.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Don't sign SIGs. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (type == dns_rdatatype_sig)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson goto skip;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Delete all old SIGs covering this type, since they
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * are all invalid when the signed RRset has changed.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * We may not be able to recreate all of them - tough.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(delete_if(true_p, db, newver, name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_sig, type,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson NULL, &sig_diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * If this RRset still exists after the update,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * add a new signature for it.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(rrset_exists(db, newver, name, type, 0, &flag));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (flag) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(add_sigs(db, newver, name, type,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &sig_diff, zone_keys, nkeys,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson mctx, now, expire));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson skip:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Skip any other updates to the same RRset. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while (t != NULL &&
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_equal(&t->name, name) &&
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t->rdata.type == type)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Remove orphaned NXTs and SIG NXTs. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (t = ISC_LIST_HEAD(diffnames.tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t != NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(non_nxt_rrset_exists(db, newver, &t->name, &flag));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (! flag) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(delete_if(true_p, db, newver, &t->name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_any, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson NULL, &sig_diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * When a name is created or deleted, its predecessor needs to
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * have its NXT updated.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (t = ISC_LIST_HEAD(diffnames.tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t != NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_boolean_t existed, exists;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_t fixedname;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_name_t *prevname;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_fixedname_init(&fixedname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson prevname = dns_fixedname_name(&fixedname);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(name_exists(db, oldver, &t->name, &existed));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(name_exists(db, newver, &t->name, &exists));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (exists == existed)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson continue;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Find the predecessor.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * When names become obscured or unobscured in this update
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * transaction, we may find the wrong predecessor because
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * the NXTs have not yet been updated to reflect the delegation
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * change. This should not matter because in this case,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * the correct predecessor is either the delegation node or
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * a newly unobscured node, and those nodes are on the
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * "affected" list in any case.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(next_active(db, newver, &t->name, prevname, ISC_FALSE));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(namelist_append_name(&affected, prevname));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Find names affected by delegation changes. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (t = ISC_LIST_HEAD(diffnames.tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t != NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_boolean_t existed, exists;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &existed));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &exists));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (exists == existed)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson continue;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * There was a delegation change. Mark all subdomains
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * of t->name as potentially needing a NXT update.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(namelist_append_subdomain(db, &t->name, &affected));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson INSIST(ISC_LIST_EMPTY(diffnames.tuples));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(uniqify_name_list(&affected));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Determine which names should have NXTs, and delete/create
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * NXTs to make it so. We don't know the final NXT targets yet,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * so we just create placeholder NXTs with arbitrary contents
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * to indicate that their respective owner names should be part of
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * the NXT chain.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (t = ISC_LIST_HEAD(affected.tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t != NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson isc_boolean_t exists;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(name_exists(db, newver, &t->name, &exists));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (! exists)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson continue;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(is_glue(db, newver, &t->name, &flag));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (flag) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * This name is obscured. Delete any
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * existing NXT record.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(delete_if(true_p, db, newver, &t->name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_nxt, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson NULL, &nxt_diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } else {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* This name is not obscured. It should have a NXT. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(rrset_exists(db, newver, &t->name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_nxt, 0, &flag));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (! flag) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson add_placeholder_nxt(db, newver, &t->name, diff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Now we know which names are part of the NXT chain.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Make them all point at their correct targets.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (t = ISC_LIST_HEAD(affected.tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t != NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(rrset_exists(db, newver, &t->name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_nxt, 0, &flag));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (flag) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * There is a NXT, but we don't know if it is correct.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Delete it and create a correct one to be sure.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * If the update was unnecessary, the diff minimization
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * will take care of eliminating it from the journal,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * IXFRs, etc.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson *
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * The SIG bit should always be set in the NXTs
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * we generate, because they will all get SIG NXTs.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * (XXX what if the zone keys are missing?).
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Because the SIG NXTs have not necessarily been
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * created yet, the correctness of the bit mask relies
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * on the assumption that NXTs are only created if
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * there is other data, and if there is other data,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * there are other SIGs.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(delete_if(true_p, db, newver, &t->name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_nxt, 0,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson NULL, &nxt_diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(add_nxt(db, newver, &t->name, &nxt_diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Minimize the set of NXT updates so that we don't
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * have to regenerate the SIG NXTs for NXTs that were
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * replaced with identical ones.
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while ((t = ISC_LIST_HEAD(nxt_diff.tuples)) != NULL) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ISC_LIST_UNLINK(nxt_diff.tuples, t, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_appendminimal(&nxt_mindiff, &t);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Update SIG NXTs. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (t = ISC_LIST_HEAD(nxt_mindiff.tuples);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t != NULL;
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson t = ISC_LIST_NEXT(t, link))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (t->op == DNS_DIFFOP_DEL) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(delete_if(true_p, db, newver, &t->name,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_rdatatype_sig, dns_rdatatype_nxt,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson NULL, &sig_diff));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } else if (t->op == DNS_DIFFOP_ADD) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson CHECK(add_sigs(db, newver, &t->name, dns_rdatatype_nxt,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson &sig_diff, zone_keys, nkeys, mctx, now,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson expire));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson } else {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson INSIST(0);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /* Record our changes for the journal. */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ISC_LIST_UNLINK(sig_diff.tuples, t, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_appendminimal(diff, &t);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson while ((t = ISC_LIST_HEAD(nxt_mindiff.tuples)) != NULL) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ISC_LIST_UNLINK(nxt_mindiff.tuples, t, link);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_appendminimal(diff, &t);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson INSIST(ISC_LIST_EMPTY(sig_diff.tuples));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson INSIST(ISC_LIST_EMPTY(nxt_diff.tuples));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson INSIST(ISC_LIST_EMPTY(nxt_mindiff.tuples));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson failure:
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_clear(&sig_diff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_clear(&nxt_diff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_clear(&nxt_mindiff);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_clear(&affected);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_diff_clear(&diffnames);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson for (i = 0; i < nkeys; i++)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dst_key_free(zone_keys[i]);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson return (result);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson}
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/**************************************************************************/
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson/*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * The actual update code in all its glory. We try to follow
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * the RFC2136 pseudocode as closely as possible.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafssonstatic dns_result_t
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonsend_update_event(ns_client_t *client, dns_zone_t *zone) {
e112f5a7abd362e52b8d23ea53e3e6de6af99dbeAndreas Gustafsson dns_result_t result = DNS_R_SUCCESS;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson update_event_t *event = NULL;
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson isc_task_t *zonetask = NULL;
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson event = (update_event_t *)
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE,
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson update_action, client, sizeof(*event));
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson if (event == NULL)
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson FAIL(DNS_R_NOMEMORY);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson event->zone = zone;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson event->result = DNS_R_SUCCESS;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson isc_taskpool_gettask(ns_g_zonetasks,
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson dns_name_hash(dns_zone_getorigin(zone),
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson ISC_FALSE),
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson &zonetask);
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson isc_task_send(zonetask, (isc_event_t **) &event);
92450223cadcf1fe2efb0c88f09e5bba84f572b2Mark Andrews
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson failure:
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson if (event != NULL)
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_event_free((isc_event_t **) &event);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson return (result);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson}
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonstatic void
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonrespond(ns_client_t *client, dns_result_t result) {
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson int msg_result;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_message_t *response = NULL;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson msg_result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTRENDER,
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson &response);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson if (msg_result != DNS_R_SUCCESS)
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson goto msg_failure;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson response->id = client->message->id;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson response->rcode = (result == DNS_R_SUCCESS ?
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_rcode_noerror : dns_result_torcode(result));
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson response->flags = client->message->flags;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson response->flags |= DNS_MESSAGEFLAG_QR;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_message_destroy(&client->message);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson client->message = response;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson ns_client_send(client);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson return;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson msg_failure:
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ISC_LOG_ERROR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "could not create update response message: %s",
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_result_totext(msg_result));
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson ns_client_next(client, msg_result);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson}
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonvoid
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonns_update_start(ns_client_t *client)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson{
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_message_t *request = client->message;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_result_t result;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *zonename;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataset_t *zone_rdataset;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_zone_t *zone = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataclass_t zoneclass;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Interpret the zone section.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_message_firstname(request, DNS_SECTION_ZONE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update zone section empty");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * The zone section must contain exactly one "question", and
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * it must be of type SOA.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson zonename = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_message_currentname(request, DNS_SECTION_ZONE, &zonename);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson zone_rdataset = ISC_LIST_HEAD(zonename->list);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson zoneclass = zone_rdataset->rdclass;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (zone_rdataset->type != dns_rdatatype_soa)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update zone section contains non-SOA");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (ISC_LIST_NEXT(zone_rdataset, link) != NULL)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update zone section contains multiple RRs");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* The zone section must have exactly one name. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_message_nextname(request, DNS_SECTION_ZONE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update zone section contains multiple RRs");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson result = dns_zt_find(client->view->zonetable, zonename, NULL, &zone);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_NOTAUTH,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "not authoritative for update zone");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson switch(dns_zone_gettype(zone)) {
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson case dns_zone_master:
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson CHECK(send_update_event(client, zone));
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson break; /* OK. */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson case dns_zone_slave:
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILS(DNS_R_NOTIMP,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update forwarding"); /* XXX implement */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson default:
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_NOTAUTH,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "not authoritative for update zone");
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson }
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson return;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson failure:
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson /*
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson * We failed without having sent an update event to the zone.
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson * We are still in the client task context, so we can
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson * simply give an error response without switching tasks.
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson respond(client, result);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonstatic void
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonupdate_action(isc_task_t *task, isc_event_t *event)
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson{
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson update_event_t *uev = (update_event_t *) event;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_zone_t *zone = uev->zone;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson ns_client_t *client = (ns_client_t *) event->arg;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_result_t result;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_db_t *db = NULL;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_dbversion_t *oldver = NULL;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_dbversion_t *ver = NULL;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_diff_t diff; /* Pending updates. */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_diff_t temp; /* Pending RR existence assertions. */
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_boolean_t soa_serial_changed = ISC_FALSE;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_mem_t *mctx = client->mctx;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_rdatatype_t covers;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_message_t *request = client->message;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_rdataclass_t zoneclass;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_name_t *zonename;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson INSIST(event->type == DNS_EVENT_UPDATE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_diff_init(mctx, &diff);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson dns_diff_init(mctx, &temp);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson CHECK(dns_zone_getdb(zone, &db));
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson zonename = dns_db_origin(db);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson zoneclass = dns_db_class(db);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_currentversion(db, &oldver);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(dns_db_newversion(db, &ver));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Check prerequisites. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t rdata;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_ttl_t ttl;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataclass_t update_class;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_boolean_t flag;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &name, &rdata, &covers, &ttl, &update_class);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (ttl != 0)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! dns_name_issubdomain(name, zonename))
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_NOTZONE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "prerequisite name is out of zone");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (update_class == dns_rdataclass_any) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.length != 0)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "class ANY prerequisite "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "RDATA is not empty");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_any) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(name_exists(db, ver, name, &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! flag) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_NXDOMAIN,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "'name in use' prerequisite "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "not satisfied");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(rrset_exists(db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdata.type, covers, &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! flag) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* RRset does not exist. */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_NXRRSET,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson "'rrset exists (value independent)' "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "prerequisite not satisfied");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (update_class == dns_rdataclass_none) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.length != 0)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "class NONE prerequisite"
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "RDATA is not empty");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_any) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(name_exists(db, ver, name, &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (flag) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_YXDOMAIN,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "'name not in use' prerequisite "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "not satisfied");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(rrset_exists(db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdata.type, covers, &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (flag) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* RRset exists. */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_YXRRSET,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "'rrset does not exist' "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "prerequisite not satisfied");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (update_class == zoneclass) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* "temp<rr.name, rr.type> += rr;" */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = temp_append(&temp, name, &rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson UNEXPECTED_ERROR(__FILE__, __LINE__,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson "temp entry creation failed: %s",
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_result_totext(result));
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAIL(DNS_R_UNEXPECTED);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR, "malformed prerequisite");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson FAIL(result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Perform the final check of the "rrset exists (value dependent)"
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * prerequisites.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = temp_check(mctx, &temp, db, ver);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(result, "'RRset exists (value dependent)' "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "prerequisite not satisfied");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_DEBUG_LOGARGS, "prerequisites are OK");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* XXX Check Requestor's Permissions Here */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Perform the Update Section Prescan. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_message_nextname(request, DNS_SECTION_UPDATE))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t rdata;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_ttl_t ttl;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataclass_t update_class;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &name, &rdata, &covers, &ttl, &update_class);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! dns_name_issubdomain(name, zonename))
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_NOTZONE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update RR is outside zone");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (update_class == zoneclass) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Check for meta-RRs. The RFC2136 pseudocode says
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * check for ANY|AXFR|MAILA|MAILB, but the text adds
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * "or any other QUERY metatype"
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (dns_rdatatype_ismeta(rdata.type)) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "meta-RR in update");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (update_class == dns_rdataclass_any) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (ttl != 0 || rdata.length != 0 ||
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson (dns_rdatatype_ismeta(rdata.type) &&
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rdata.type != dns_rdatatype_any))
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "meta-RR in update");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (update_class == dns_rdataclass_none) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (ttl != 0 ||
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdatatype_ismeta(rdata.type))
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_FORMERR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "meta-RR in update");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson NS_LOGMODULE_UPDATE, ISC_LOG_WARNING,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "update RR has incorrect class %d",
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson update_class);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson FAIL(DNS_R_FORMERR);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * draft-ietf-dnsind-simple-secure-update-01 says
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * "Unlike traditional dynamic update, the client
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * is forbidden from updating NXT records."
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson */
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (dns_db_issecure(db) && rdata.type == dns_rdatatype_nxt) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILC(DNS_R_REFUSED,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "explicit NXT updates are not allowed "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "in secure zones");
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson FAIL(result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_DEBUG_LOGARGS, "update section prescan OK");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /* Process the Update Section. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result == DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_message_nextname(request, DNS_SECTION_UPDATE))
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_name_t *name = NULL;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdata_t rdata;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_ttl_t ttl;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_rdataclass_t update_class;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson isc_boolean_t flag;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &name, &rdata, &covers, &ttl, &update_class);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (update_class == zoneclass) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_cname) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(cname_incompatible_rrset_exists(db, ver,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson name,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (flag) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to add CNAME "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "alongside non-CNAME "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(rrset_exists(db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_cname, 0,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson &flag));
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (flag &&
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson ! dns_rdatatype_isdnssec(rdata.type))
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to add non-CNAME "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "alongside CNAME ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_soa) {
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson isc_boolean_t ok;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(rrset_exists(db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_soa, 0,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! flag) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to create 2nd "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "SOA ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(check_soa_increment(db, ver, &rdata,
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson &ok));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! ok) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "SOA update failed to "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "increment serial, "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "ignoring it");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
c6e66777242752532a094561fc728233cab9bc2fAndreas Gustafsson soa_serial_changed = ISC_TRUE;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * Add an RR. If an identical RR already exists,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * do nothing. If a similar but not identical
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * CNAME, SOA, or WKS exists, remove it first.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(matching_rr_exists(rr_equal_p, db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdata.type, covers, &rdata,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &flag));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! flag) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "adding an RR");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(delete_if(replaces_p, db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdata.type, covers, &rdata,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = update_one_rr(db, ver, &diff,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson DNS_DIFFOP_ADD,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson name, ttl, &rdata);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson FAIL(result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to add existing RR "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (update_class == dns_rdataclass_any) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_any) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "delete all rrsets from a name");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (dns_name_equal(name, zonename)) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(delete_if(type_not_soa_nor_ns_p,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_any, 0,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson &rdata, &diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(delete_if(true_p, db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_any, 0,
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson &rdata, &diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (dns_name_equal(name, zonename) &&
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson (rdata.type == dns_rdatatype_soa ||
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson rdata.type == dns_rdatatype_ns)) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to delete all SOA "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "or NS records ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "deleting an rrset");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(delete_if(true_p, db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdata.type, covers, &rdata,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley &diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson } else if (update_class == dns_rdataclass_none) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_soa) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to delete SOA ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (rdata.type == dns_rdatatype_ns) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson int count;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(rr_count(db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_ns, 0, &count));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (count == 1) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "attempt to delete last "
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "NS ignored");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson continue;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_PROTOCOL_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "deleting an RR");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(delete_if(rr_equal_p, db, ver, name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdata.type, covers, &rdata, &diff));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_NOMORE)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson FAIL(result);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * If any changes were made, increment the SOA serial number,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * update SIGs and NXTs (if zone is secure), and write the update
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * to the journal.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! ISC_LIST_EMPTY(diff.tuples)) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_journal_t *journal;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * Increment the SOA serial, but only if it was not
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson * changed as a result of an update operation.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (! soa_serial_changed) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson CHECK(increment_soa_serial(db, ver, &diff, mctx));
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (dns_db_issecure(db)) {
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson result = update_signatures(mctx, db,
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson oldver, ver, &diff);
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson if (result != DNS_R_SUCCESS) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson NS_LOGMODULE_UPDATE,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson ISC_LOG_ERROR,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "SIG/NXT update failed: %s",
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_result_totext(result));
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson goto failure;
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson }
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_DEBUG_LOGARGS, "writing journal");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson journal = NULL;
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson result = dns_journal_open(mctx, dns_zone_getixfrlog(zone),
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson ISC_TRUE, &journal);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS)
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILS(result, "journal open failed");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = dns_journal_write_transaction(journal, &diff);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (result != DNS_R_SUCCESS) {
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_journal_destroy(&journal);
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson FAILS(result, "journal write failed");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_journal_destroy(&journal);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson /*
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * XXXRTH Just a note that this committing code will have to change
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * to handle databases that need two-phase commit, but this
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson * isn't a priority.
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson */
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_DEBUG_LOGARGS, "committing update transaction");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_closeversion(db, &ver, ISC_TRUE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson result = DNS_R_SUCCESS;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson goto common;
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson failure:
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson /* The reason for failure should have been logged at this point. */
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (ver != NULL) {
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson isc_log_write(UPDATE_DEBUG_LOGARGS,
8803b0510877fd08044542edbb55e2be72fae36fAndreas Gustafsson "rolling back");
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_closeversion(db, &ver, ISC_FALSE);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson }
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson common:
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_clear(&temp);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_diff_clear(&diff);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson if (oldver != NULL)
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson dns_db_closeversion(db, &oldver, ISC_FALSE);
b2c71d98dfc4dab5c6b8c8f39cf8fed3d899e94cAndreas Gustafsson
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson if (db != NULL)
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson dns_db_detach(&db);
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley if (zone != NULL)
d60f5b9bc8c1e1f7ddebc6c7834f7550a8e8be6fBob Halley dns_zone_detach(&zone);
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson
999ae80184e3df1016ac74514124b0459ace4d01Andreas Gustafsson isc_task_detach(&task);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson uev->result = result;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson uev->type = DNS_EVENT_UPDATEDONE;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson uev->action = updatedone_action;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_task_send(client->task, &event);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson INSIST(event == NULL);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonstatic void
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafssonupdatedone_action(isc_task_t *task, isc_event_t *event)
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson{
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson update_event_t *uev = (update_event_t *) event;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson ns_client_t *client = (ns_client_t *) event->arg;
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson INSIST(event->type == DNS_EVENT_UPDATEDONE);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson INSIST(task == client->task);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson respond(client, uev->result);
581db30788a4920ba8558287a0dccf3c1a210c5aAndreas Gustafsson isc_event_free(&event);
4cd3d6df39927315e3fadc07a8da3788175f4195Andreas Gustafsson}