bind9/lib/dns/log.c
Tony Finch 6b9ddbd1ce Add a qp-trie data structure
A qp-trie is a kind of radix tree that is particularly well-suited to
DNS servers. I invented the qp-trie in 2015, based on Dan Bernstein's
crit-bit trees and Phil Bagwell's HAMT. https://dotat.at/prog/qp/

This code incorporates some new ideas that I prototyped using
NLnet Labs NSD in 2020 (optimizations for DNS names as keys)
and 2021 (custom allocator and garbage collector).
https://dotat.at/cgi/git/nsd.git

The BIND version of my qp-trie code has a number of improvements
compared to the prototype developed for NSD.

  * The main omission in the prototype was the very sketchy outline of
    how locking might work. Now the locking has been implemented,
    using a reader/writer lock and a mutex. However, it is designed to
    benefit from liburcu if that is available.

  * The prototype was designed for two-version concurrency, one
    version for readers and one for the writer. The new code supports
    multiversion concurrency, to provide a basis for BIND's dbversion
    machinery, so that updates are not blocked by long-running zone
    transfers.

  * There are now two kinds of transaction that modify the trie: an
    `update` aims to support many very small zones without wasting
    memory; a `write` avoids unnecessary allocation to help the
    performance of many small changes to the cache.

  * There is also a single-threaded interface for situations where
    concurrent access is not necessary.

  * The API makes better use of types to make it more clear which
    operations are permitted when.

  * The lookup table used to convert a DNS name to a qp-trie key is
    now initialized by a run-time constructor instead of a programmer
    using copy-and-paste. Key conversion is more flexible, so the
    qp-trie can be used with keys other than DNS names.

  * There has been much refactoring and re-arranging things to improve
    the terminology and order of presentation in the code, and the
    internal documentation has been moved from a comment into a file
    of its own.

Some of the required functionality has been stripped out, to be
brought back later after the basics are known to work.

  * Garbage collector performance statistics are missing.

  * Fancy searches are missing, such as longest match and
    nearest match.

  * Iteration is missing.

  * Search for update is missing, for cases where the caller needs to
    know if the value object is mutable or not.
2023-02-27 13:47:25 +00:00

66 lines
2.1 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <isc/util.h>
#include <dns/log.h>
/*%
* When adding a new category, be sure to add the appropriate
* \#define to <dns/log.h>.
*/
isc_logcategory_t dns_categories[] = {
{ "notify", 0 }, { "database", 0 }, { "security", 0 },
{ "_placeholder", 0 }, { "dnssec", 0 }, { "resolver", 0 },
{ "xfer-in", 0 }, { "xfer-out", 0 }, { "dispatch", 0 },
{ "lame-servers", 0 }, { "delegation-only", 0 }, { "edns-disabled", 0 },
{ "rpz", 0 }, { "rate-limit", 0 }, { "cname", 0 },
{ "spill", 0 }, { "dnstap", 0 }, { "zoneload", 0 },
{ "nsid", 0 }, { "rpz-passthru", 0 }, { NULL, 0 }
};
/*%
* When adding a new module, be sure to add the appropriate
* \#define to <dns/log.h>.
*/
isc_logmodule_t dns_modules[] = {
{ "dns/db", 0 }, { "dns/rbtdb", 0 }, { "dns/rbt", 0 },
{ "dns/rdata", 0 }, { "dns/master", 0 }, { "dns/message", 0 },
{ "dns/cache", 0 }, { "dns/config", 0 }, { "dns/resolver", 0 },
{ "dns/zone", 0 }, { "dns/journal", 0 }, { "dns/adb", 0 },
{ "dns/xfrin", 0 }, { "dns/xfrout", 0 }, { "dns/acl", 0 },
{ "dns/validator", 0 }, { "dns/dispatch", 0 }, { "dns/request", 0 },
{ "dns/masterdump", 0 }, { "dns/tsig", 0 }, { "dns/tkey", 0 },
{ "dns/sdb", 0 }, { "dns/diff", 0 }, { "dns/hints", 0 },
{ "dns/unused1", 0 }, { "dns/dlz", 0 }, { "dns/dnssec", 0 },
{ "dns/crypto", 0 }, { "dns/packets", 0 }, { "dns/nta", 0 },
{ "dns/dyndb", 0 }, { "dns/dnstap", 0 }, { "dns/ssu", 0 },
{ "dns/qp", 0 }, { NULL, 0 },
};
isc_log_t *dns_lctx = NULL;
void
dns_log_init(isc_log_t *lctx) {
REQUIRE(lctx != NULL);
isc_log_registercategories(lctx, dns_categories);
isc_log_registermodules(lctx, dns_modules);
}
void
dns_log_setcontext(isc_log_t *lctx) {
dns_lctx = lctx;
}