diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 07:24:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 07:24:22 +0000 |
commit | 45d6379135504814ab723b57f0eb8be23393a51d (patch) | |
tree | d4f2ec4acca824a8446387a758b0ce4238a4dffa /lib/ns/include | |
parent | Initial commit. (diff) | |
download | bind9-45d6379135504814ab723b57f0eb8be23393a51d.tar.xz bind9-45d6379135504814ab723b57f0eb8be23393a51d.zip |
Adding upstream version 1:9.16.44.upstream/1%9.16.44upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
l--------- | lib/ns/include/.clang-format | 1 | ||||
-rw-r--r-- | lib/ns/include/Makefile.in | 19 | ||||
-rw-r--r-- | lib/ns/include/ns/Makefile.in | 37 | ||||
-rw-r--r-- | lib/ns/include/ns/client.h | 585 | ||||
-rw-r--r-- | lib/ns/include/ns/hooks.h | 420 | ||||
-rw-r--r-- | lib/ns/include/ns/interfacemgr.h | 202 | ||||
-rw-r--r-- | lib/ns/include/ns/lib.h | 37 | ||||
-rw-r--r-- | lib/ns/include/ns/listenlist.h | 101 | ||||
-rw-r--r-- | lib/ns/include/ns/log.h | 74 | ||||
-rw-r--r-- | lib/ns/include/ns/notify.h | 47 | ||||
-rw-r--r-- | lib/ns/include/ns/query.h | 235 | ||||
-rw-r--r-- | lib/ns/include/ns/server.h | 189 | ||||
-rw-r--r-- | lib/ns/include/ns/sortlist.h | 83 | ||||
-rw-r--r-- | lib/ns/include/ns/stats.h | 141 | ||||
-rw-r--r-- | lib/ns/include/ns/types.h | 35 | ||||
-rw-r--r-- | lib/ns/include/ns/update.h | 45 | ||||
-rw-r--r-- | lib/ns/include/ns/version.h | 18 | ||||
-rw-r--r-- | lib/ns/include/ns/xfrout.h | 33 |
18 files changed, 2302 insertions, 0 deletions
diff --git a/lib/ns/include/.clang-format b/lib/ns/include/.clang-format new file mode 120000 index 0000000..0e62f72 --- /dev/null +++ b/lib/ns/include/.clang-format @@ -0,0 +1 @@ +../../../.clang-format.headers
\ No newline at end of file diff --git a/lib/ns/include/Makefile.in b/lib/ns/include/Makefile.in new file mode 100644 index 0000000..5863acb --- /dev/null +++ b/lib/ns/include/Makefile.in @@ -0,0 +1,19 @@ +# 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. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +SUBDIRS = ns +TARGETS = + +@BIND9_MAKE_RULES@ diff --git a/lib/ns/include/ns/Makefile.in b/lib/ns/include/ns/Makefile.in new file mode 100644 index 0000000..6976e1e --- /dev/null +++ b/lib/ns/include/ns/Makefile.in @@ -0,0 +1,37 @@ +# 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. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +VERSION=@BIND9_VERSION@ + +HEADERS = client.h hooks.h interfacemgr.h lib.h listenlist.h log.h \ + notify.h query.h server.h sortlist.h stats.h \ + types.h update.h version.h xfrout.h +SUBDIRS = +TARGETS = + +@BIND9_MAKE_RULES@ + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/ns + +install:: installdirs + for i in ${HEADERS}; do \ + ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/ns || exit 1 ; \ + done + +uninstall:: + for i in ${HEADERS}; do \ + rm -f ${DESTDIR}${includedir}/ns/$$i || exit 1 ; \ + done diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h new file mode 100644 index 0000000..d1e2fde --- /dev/null +++ b/lib/ns/include/ns/client.h @@ -0,0 +1,585 @@ +/* + * 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. + */ + +#ifndef NS_CLIENT_H +#define NS_CLIENT_H 1 + +/***** +***** Module Info +*****/ + +/*! \file + * \brief + * This module defines two objects, ns_client_t and ns_clientmgr_t. + * + * An ns_client_t object handles incoming DNS requests from clients + * on a given network interface. + * + * Each ns_client_t object can handle only one TCP connection or UDP + * request at a time. Therefore, several ns_client_t objects are + * typically created to serve each network interface, e.g., one + * for handling TCP requests and a few (one per CPU) for handling + * UDP requests. + * + * Incoming requests are classified as queries, zone transfer + * requests, update requests, notify requests, etc, and handed off + * to the appropriate request handler. When the request has been + * fully handled (which can be much later), the ns_client_t must be + * notified of this by calling one of the following functions + * exactly once in the context of its task: + * \code + * ns_client_send() (sending a non-error response) + * ns_client_sendraw() (sending a raw response) + * ns_client_error() (sending an error response) + * ns_client_drop() (sending no response, logging the reason) + *\endcode + * This will release any resources used by the request and + * and allow the ns_client_t to listen for the next request. + * + * A ns_clientmgr_t manages a number of ns_client_t objects. + * New ns_client_t objects are created by calling + * ns_clientmgr_createclients(). They are destroyed by + * destroying their manager. + */ + +/*** + *** Imports + ***/ + +#include <inttypes.h> +#include <stdbool.h> + +#include <isc/atomic.h> +#include <isc/buffer.h> +#include <isc/magic.h> +#include <isc/netmgr.h> +#include <isc/platform.h> +#include <isc/quota.h> +#include <isc/stdtime.h> + +#include <dns/db.h> +#include <dns/ecs.h> +#include <dns/fixedname.h> +#include <dns/name.h> +#include <dns/rdataclass.h> +#include <dns/rdatatype.h> +#include <dns/tcpmsg.h> +#include <dns/types.h> + +#include <ns/query.h> +#include <ns/types.h> + +/*** + *** Types + ***/ + +#define NS_CLIENT_TCP_BUFFER_SIZE 65535 +#define NS_CLIENT_SEND_BUFFER_SIZE 4096 + +/*! + * Client object states. Ordering is significant: higher-numbered + * states are generally "more active", meaning that the client can + * have more dynamically allocated data, outstanding events, etc. + * In the list below, any such properties listed for state N + * also apply to any state > N. + */ + +typedef enum { + NS_CLIENTSTATE_FREED = 0, + /*%< + * The client object no longer exists. + */ + + NS_CLIENTSTATE_INACTIVE = 1, + /*%< + * The client object exists and has a task and timer. + * Its "query" struct and sendbuf are initialized. + * It has a message and OPT, both in the reset state. + */ + + NS_CLIENTSTATE_READY = 2, + /*%< + * The client object is either a TCP or a UDP one, and + * it is associated with a network interface. It is on the + * client manager's list of active clients. + * + * If it is a TCP client object, it has a TCP listener socket + * and an outstanding TCP listen request. + * + * If it is a UDP client object, it has a UDP listener socket + * and an outstanding UDP receive request. + */ + + NS_CLIENTSTATE_WORKING = 3, + /*%< + * The client object has received a request and is working + * on it. It has a view, and it may have any of a non-reset OPT, + * recursion quota, and an outstanding write request. + */ + + NS_CLIENTSTATE_RECURSING = 4, + /*%< + * The client object is recursing. It will be on the + * 'recursing' list. + */ + + NS_CLIENTSTATE_MAX = 5 + /*%< + * Sentinel value used to indicate "no state". + */ +} ns_clientstate_t; + +typedef ISC_LIST(ns_client_t) client_list_t; + +/*% nameserver client manager structure */ +struct ns_clientmgr { + /* Unlocked. */ + unsigned int magic; + + isc_mem_t *mctx; + ns_server_t *sctx; + isc_taskmgr_t *taskmgr; + isc_timermgr_t *timermgr; + isc_task_t *excl; + isc_refcount_t references; + int ncpus; + + /* Attached by clients, needed for e.g. recursion */ + isc_task_t **taskpool; + + ns_interface_t *interface; + + /* Lock covers manager state. */ + isc_mutex_t lock; + bool exiting; + + /* Lock covers the recursing list */ + isc_mutex_t reclock; + client_list_t recursing; /*%< Recursing clients */ + + /*%< mctx pool for clients. */ + isc_mem_t **mctxpool; +}; + +/*% nameserver client structure */ +struct ns_client { + unsigned int magic; + isc_mem_t *mctx; + bool allocated; /* Do we need to free it? */ + ns_server_t *sctx; + ns_clientmgr_t *manager; + ns_clientstate_t state; + int nupdates; + bool nodetach; + bool shuttingdown; + unsigned int attributes; + isc_task_t *task; + dns_view_t *view; + dns_dispatch_t *dispatch; + isc_nmhandle_t *handle; /* Permanent pointer to handle */ + isc_nmhandle_t *sendhandle; /* Waiting for send callback */ + isc_nmhandle_t *reqhandle; /* Waiting for request callback + (query, update, notify) */ + isc_nmhandle_t *fetchhandle; /* Waiting for recursive fetch */ + isc_nmhandle_t *prefetchhandle; /* Waiting for prefetch / rpzfetch */ + isc_nmhandle_t *updatehandle; /* Waiting for update callback */ + unsigned char *tcpbuf; + dns_message_t *message; + unsigned char *sendbuf; + dns_rdataset_t *opt; + uint16_t udpsize; + uint16_t extflags; + int16_t ednsversion; /* -1 noedns */ + void (*cleanup)(ns_client_t *); + ns_query_t query; + isc_time_t requesttime; + isc_stdtime_t now; + isc_time_t tnow; + dns_name_t signername; /*%< [T]SIG key name */ + dns_name_t *signer; /*%< NULL if not valid sig */ + bool mortal; /*%< Die after handling request */ + isc_quota_t *recursionquota; + + isc_sockaddr_t peeraddr; + bool peeraddr_valid; + isc_netaddr_t destaddr; + isc_sockaddr_t destsockaddr; + + dns_ecs_t ecs; /*%< EDNS client subnet sent by client */ + + struct in6_pktinfo pktinfo; + isc_dscp_t dscp; + /*% + * Information about recent FORMERR response(s), for + * FORMERR loop avoidance. This is separate for each + * client object rather than global only to avoid + * the need for locking. + */ + struct { + isc_sockaddr_t addr; + isc_stdtime_t time; + dns_messageid_t id; + } formerrcache; + + /*% Callback function to send a response when unit testing */ + void (*sendcb)(isc_buffer_t *buf); + + ISC_LINK(ns_client_t) rlink; + unsigned char cookie[8]; + uint32_t expire; + unsigned char *keytag; + uint16_t keytag_len; + + /*% + * Used to override the DNS response code in ns_client_error(). + * If set to -1, the rcode is determined from the result code, + * but if set to any other value, the least significant 12 + * bits will be used as the rcode in the response message. + */ + int32_t rcode_override; +}; + +#define NS_CLIENT_MAGIC ISC_MAGIC('N', 'S', 'C', 'c') +#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) + +#define NS_CLIENTATTR_TCP 0x00001 +#define NS_CLIENTATTR_RA 0x00002 /*%< Client gets recursive service */ +#define NS_CLIENTATTR_PKTINFO 0x00004 /*%< pktinfo is valid */ +#define NS_CLIENTATTR_MULTICAST 0x00008 /*%< recv'd from multicast */ +#define NS_CLIENTATTR_WANTDNSSEC 0x00010 /*%< include dnssec records */ +#define NS_CLIENTATTR_WANTNSID 0x00020 /*%< include nameserver ID */ +/* Obsolete: NS_CLIENTATTR_FILTER_AAAA 0x00040 */ +/* Obsolete: NS_CLIENTATTR_FILTER_AAAA_RC 0x00080 */ +#define NS_CLIENTATTR_WANTAD 0x00100 /*%< want AD in response if possible */ +#define NS_CLIENTATTR_WANTCOOKIE 0x00200 /*%< return a COOKIE */ +#define NS_CLIENTATTR_HAVECOOKIE 0x00400 /*%< has a valid COOKIE */ +#define NS_CLIENTATTR_WANTEXPIRE 0x00800 /*%< return seconds to expire */ +#define NS_CLIENTATTR_HAVEEXPIRE 0x01000 /*%< return seconds to expire */ +#define NS_CLIENTATTR_WANTOPT 0x02000 /*%< add opt to reply */ +#define NS_CLIENTATTR_HAVEECS 0x04000 /*%< received an ECS option */ +#define NS_CLIENTATTR_WANTPAD 0x08000 /*%< pad reply */ +#define NS_CLIENTATTR_USEKEEPALIVE 0x10000 /*%< use TCP keepalive */ + +#define NS_CLIENTATTR_NOSETFC 0x20000 /*%< don't set servfail cache */ + +/* + * Flag to use with the SERVFAIL cache to indicate + * that a query had the CD bit set. + */ +#define NS_FAILCACHE_CD 0x01 + +#if defined(_WIN32) && !defined(_WIN64) +LIBNS_EXTERNAL_DATA extern atomic_uint_fast32_t ns_client_requests; +#else /* if defined(_WIN32) && !defined(_WIN64) */ +LIBNS_EXTERNAL_DATA extern atomic_uint_fast64_t ns_client_requests; +#endif /* if defined(_WIN32) && !defined(_WIN64) */ + +/*** + *** Functions + ***/ + +/* + * Note! These ns_client_ routines MUST be called ONLY from the client's + * task in order to ensure synchronization. + */ + +void +ns_client_send(ns_client_t *client); +/*%< + * Finish processing the current client request and + * send client->message as a response. + * \brief + * Note! These ns_client_ routines MUST be called ONLY from the client's + * task in order to ensure synchronization. + */ + +void +ns_client_sendraw(ns_client_t *client, dns_message_t *msg); +/*%< + * Finish processing the current client request and + * send msg as a response using client->message->id for the id. + */ + +void +ns_client_error(ns_client_t *client, isc_result_t result); +/*%< + * Finish processing the current client request and return + * an error response to the client. The error response + * will have an RCODE determined by 'result'. + */ + +void +ns_client_drop(ns_client_t *client, isc_result_t result); +/*%< + * Log the reason the current client request has failed; no response + * will be sent. + */ + +bool +ns_client_shuttingdown(ns_client_t *client); +/*%< + * Return true iff the client is currently shutting down. + */ + +isc_result_t +ns_client_replace(ns_client_t *client); +/*%< + * Try to replace the current client with a new one, so that the + * current one can go off and do some lengthy work without + * leaving the dispatch/socket without service. + */ + +void +ns_client_settimeout(ns_client_t *client, unsigned int seconds); +/*%< + * Set a timer in the client to go off in the specified amount of time. + */ + +isc_result_t +ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr, + isc_timermgr_t *timermgr, ns_interface_t *ifp, int ncpus, + ns_clientmgr_t **managerp); +/*%< + * Create a client manager. + */ + +void +ns_clientmgr_shutdown(ns_clientmgr_t *manager); +/*%< + * Shutdown a client manager and all ns_client_t objects + * managed by it. + */ + +void +ns_clientmgr_destroy(ns_clientmgr_t **managerp); +/*%< + * Destroy a client manager. + */ + +isc_sockaddr_t * +ns_client_getsockaddr(ns_client_t *client); +/*%< + * Get the socket address of the client whose request is + * currently being processed. + */ + +isc_sockaddr_t * +ns_client_getdestaddr(ns_client_t *client); +/*%< + * Get the destination address (server) for the request that is + * currently being processed. + */ + +isc_result_t +ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, + dns_acl_t *acl, bool default_allow); + +/*%< + * Convenience function for client request ACL checking. + * + * Check the current client request against 'acl'. If 'acl' + * is NULL, allow the request iff 'default_allow' is true. + * If netaddr is NULL, check the ACL against client->peeraddr; + * otherwise check it against netaddr. + * + * Notes: + *\li This is appropriate for checking allow-update, + * allow-query, allow-transfer, etc. It is not appropriate + * for checking the blackhole list because we treat positive + * matches as "allow" and negative matches as "deny"; in + * the case of the blackhole list this would be backwards. + * + * Requires: + *\li 'client' points to a valid client. + *\li 'netaddr' points to a valid address, or is NULL. + *\li 'acl' points to a valid ACL, or is NULL. + * + * Returns: + *\li ISC_R_SUCCESS if the request should be allowed + * \li DNS_R_REFUSED if the request should be denied + *\li No other return values are possible. + */ + +isc_result_t +ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr, + const char *opname, dns_acl_t *acl, bool default_allow, + int log_level); +/*%< + * Like ns_client_checkaclsilent, except the outcome of the check is + * logged at log level 'log_level' if denied, and at debug 3 if approved. + * Log messages will refer to the request as an 'opname' request. + * + * Requires: + *\li 'client' points to a valid client. + *\li 'sockaddr' points to a valid address, or is NULL. + *\li 'acl' points to a valid ACL, or is NULL. + *\li 'opname' points to a null-terminated string. + */ + +void +ns_client_log(ns_client_t *client, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, ...) + ISC_FORMAT_PRINTF(5, 6); + +void +ns_client_logv(ns_client_t *client, isc_logcategory_t *category, + isc_logmodule_t *module, int level, const char *fmt, va_list ap) + ISC_FORMAT_PRINTF(5, 0); + +void +ns_client_aclmsg(const char *msg, const dns_name_t *name, dns_rdatatype_t type, + dns_rdataclass_t rdclass, char *buf, size_t len); + +#define NS_CLIENT_ACLMSGSIZE(x) \ + (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ + DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) + +void +ns_client_recursing(ns_client_t *client); +/*%< + * Add client to end of th recursing list. + */ + +void +ns_client_killoldestquery(ns_client_t *client); +/*%< + * Kill the oldest recursive query (recursing list head). + */ + +void +ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); +/*%< + * Dump the outstanding recursive queries to 'f'. + */ + +void +ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); +/*%< + * Replace the qname. + */ + +isc_result_t +ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp); + +isc_result_t +ns_client_addopt(ns_client_t *client, dns_message_t *message, + dns_rdataset_t **opt); + +/*%< + * Get a client object from the inactive queue, or create one, as needed. + * (Not intended for use outside this module and associated tests.) + */ + +void +ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult, + isc_region_t *region, void *arg); + +/*%< + * Handle client requests. + * (Not intended for use outside this module and associated tests.) + */ + +isc_result_t +ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg); + +/*%< + * Called every time a TCP connection is establish. This is used for + * updating TCP statistics. + */ + +dns_rdataset_t * +ns_client_newrdataset(ns_client_t *client); + +void +ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp); +/*%< + * Get and release temporary rdatasets in the client message; + * used in query.c and in plugins. + */ + +isc_result_t +ns_client_newnamebuf(ns_client_t *client); +/*%< + * Allocate a name buffer for the client message. + */ + +dns_name_t * +ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf); +/*%< + * Get a temporary name for the client message. + */ + +isc_buffer_t * +ns_client_getnamebuf(ns_client_t *client); +/*%< + * Get a name buffer from the pool, or allocate a new one if needed. + */ + +void +ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf); +/*%< + * Adjust buffer 'dbuf' to reflect that 'name' is using space in it, + * and set client attributes appropriately. + */ + +void +ns_client_releasename(ns_client_t *client, dns_name_t **namep); +/*%< + * Release 'name' back to the pool of temporary names for the client + * message. If it is using a name buffer, relinquish its exclusive + * rights on the buffer. + */ + +isc_result_t +ns_client_newdbversion(ns_client_t *client, unsigned int n); +/*%< + * Allocate 'n' new database versions for use by client queries. + */ + +ns_dbversion_t * +ns_client_getdbversion(ns_client_t *client); +/*%< + * Get a free database version for use by a client query, allocating + * a new one if necessary. + */ + +ns_dbversion_t * +ns_client_findversion(ns_client_t *client, dns_db_t *db); +/*%< + * Find the correct database version to use with a client query. + * If we have already done a query related to the database 'db', + * make sure subsequent queries are from the same version; + * otherwise, take a database version from the list of dbversions + * allocated by ns_client_newdbversion(). + */ + +isc_result_t +ns__client_setup(ns_client_t *client, ns_clientmgr_t *manager, bool new); +/*%< + * Perform initial setup of an allocated client. + */ + +void +ns__client_reset_cb(void *client0); +/*%< + * Reset the client object so that it can be reused. + */ + +void +ns__client_put_cb(void *client0); +/*%< + * Free all resources allocated to this client object, so that + * it can be freed. + */ + +#endif /* NS_CLIENT_H */ diff --git a/lib/ns/include/ns/hooks.h b/lib/ns/include/ns/hooks.h new file mode 100644 index 0000000..db3846d --- /dev/null +++ b/lib/ns/include/ns/hooks.h @@ -0,0 +1,420 @@ +/* + * 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. + */ + +#ifndef NS_HOOKS_H +#define NS_HOOKS_H 1 + +/*! \file */ + +#include <stdbool.h> + +#include <isc/list.h> +#include <isc/magic.h> +#include <isc/result.h> + +#include <dns/rdatatype.h> + +#include <ns/client.h> +#include <ns/query.h> +/* + * "Hooks" are a mechanism to call a defined function or set of functions once + * a certain place in code is reached. Hook actions can inspect and alter the + * state of an ongoing process, allowing processing to continue afterward or + * triggering an early return. + * + * Currently hooks are used in two ways: in plugins, which use them to + * add functionality to query processing, and in the unit tests for libns, + * where they are used to inspect state before and after certain functions have + * run. + * + * Both of these uses are limited to libns, so hooks are currently defined in + * the ns/hooks.h header file, and hook-related macro and function names are + * prefixed with `NS_` and `ns_`. However, the design is fairly generic and + * could be repurposed for general use, e.g. as part of libisc, after some + * further customization. + * + * Hooks are created by defining a hook point identifier in the ns_hookpoint_t + * enum below, and placing a special call at a corresponding location in the + * code which invokes the action(s) for that hook; there are two such special + * calls currently implemented, namely the CALL_HOOK() and CALL_HOOK_NORETURN() + * macros in query.c. The former macro contains a "goto cleanup" statement + * which is inlined into the function into which the hook has been inserted; + * this enables the hook action to cause the calling function to return from + * the hook insertion point. For functions returning isc_result_t, if a hook + * action intends to cause a return at hook insertion point, it also has to set + * the value to be returned by the calling function. + * + * A hook table is an array (indexed by the value of the hook point identifier) + * in which each cell contains a linked list of structures, each of which + * contains a function pointer to a hook action and a pointer to data which is + * to be passed to the action function when it is called. + * + * Each view has its own separate hook table, populated by loading plugin + * modules specified in the "plugin" statements in named.conf. There is also a + * special, global hook table (ns__hook_table) that is only used by libns unit + * tests and whose existence can be safely ignored by plugin modules. + * + * Hook actions are functions which: + * + * - return an ns_hookresult_t value: + * - if NS_HOOK_RETURN is returned by the hook action, the function + * into which the hook is inserted will return and no further hook + * actions at the same hook point will be invoked, + * - if NS_HOOK_CONTINUE is returned by the hook action and there are + * further hook actions set up at the same hook point, they will be + * processed; if NS_HOOK_CONTINUE is returned and there are no + * further hook actions set up at the same hook point, execution of + * the function into which the hook has been inserted will be + * resumed. + * + * - accept three pointers as arguments: + * - a pointer specified by the special call at the hook insertion point, + * - a pointer specified upon inserting the action into the hook table, + * - a pointer to an isc_result_t value which will be returned by the + * function into which the hook is inserted if the action returns + * NS_HOOK_RETURN. + * + * In order for a hook action to be called for a given hook, a pointer to that + * action function (along with an optional pointer to action-specific data) has + * to be inserted into the relevant hook table entry for that hook using an + * ns_hook_add() call. If multiple actions are set up at a single hook point + * (e.g. by multiple plugin modules), they are processed in FIFO order, that is + * they are performed in the same order in which their relevant ns_hook_add() + * calls were issued. Since the configuration is loaded from a single thread, + * this means that multiple actions at a single hook point are determined by + * the order in which the relevant plugin modules were declared in the + * configuration file(s). The hook API currently does not support changing + * this order. + * + * As an example, consider the following hypothetical function in query.c: + * + * ---------------------------------------------------------------------------- + * static isc_result_t + * query_foo(query_ctx_t *qctx) { + * isc_result_t result; + * + * CALL_HOOK(NS_QUERY_FOO_BEGIN, qctx); + * + * ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, + * ISC_LOG_DEBUG(99), "Lorem ipsum dolor sit amet..."); + * + * result = ISC_R_COMPLETE; + * + * cleanup: + * return (result); + * } + * ---------------------------------------------------------------------------- + * + * and the following hook action: + * + * ---------------------------------------------------------------------------- + * static ns_hookresult_t + * cause_failure(void *hook_data, void *action_data, isc_result_t *resultp) { + * UNUSED(hook_data); + * UNUSED(action_data); + * + * *resultp = ISC_R_FAILURE; + * + * return (NS_HOOK_RETURN); + * } + * ---------------------------------------------------------------------------- + * + * If this hook action was installed in the hook table using: + * + * ---------------------------------------------------------------------------- + * const ns_hook_t foo_fail = { + * .action = cause_failure, + * }; + * + * ns_hook_add(..., NS_QUERY_FOO_BEGIN, &foo_fail); + * ---------------------------------------------------------------------------- + * + * then query_foo() would return ISC_R_FAILURE every time it is called due + * to the cause_failure() hook action returning NS_HOOK_RETURN and setting + * '*resultp' to ISC_R_FAILURE. query_foo() would also never log the + * "Lorem ipsum dolor sit amet..." message. + * + * Consider a different hook action: + * + * ---------------------------------------------------------------------------- + * static ns_hookresult_t + * log_qtype(void *hook_data, void *action_data, isc_result_t *resultp) { + * query_ctx_t *qctx = (query_ctx_t *)hook_data; + * FILE *stream = (FILE *)action_data; + * + * UNUSED(resultp); + * + * fprintf(stream, "QTYPE=%u\n", qctx->qtype); + * + * return (NS_HOOK_CONTINUE); + * } + * ---------------------------------------------------------------------------- + * + * If this hook action was installed in the hook table instead of + * cause_failure(), using: + * + * ---------------------------------------------------------------------------- + * const ns_hook_t foo_log_qtype = { + * .action = log_qtype, + * .action_data = stderr, + * }; + * + * ns_hook_add(..., NS_QUERY_FOO_BEGIN, &foo_log_qtype); + * ---------------------------------------------------------------------------- + * + * then the QTYPE stored in the query context passed to query_foo() would be + * logged to stderr upon each call to that function; 'qctx' would be passed to + * the hook action in 'hook_data' since it is specified in the CALL_HOOK() call + * inside query_foo() while stderr would be passed to the hook action in + * 'action_data' since it is specified in the ns_hook_t structure passed to + * ns_hook_add(). As the hook action returns NS_HOOK_CONTINUE, + * query_foo() would also be logging the "Lorem ipsum dolor sit amet..." + * message before returning ISC_R_COMPLETE. + */ + +/*! + * Currently-defined hook points. So long as these are unique, + * the order in which they are declared is unimportant, but + * currently matches the order in which they are referenced in + * query.c. + */ +typedef enum { + /* hookpoints from query.c */ + NS_QUERY_QCTX_INITIALIZED, + NS_QUERY_QCTX_DESTROYED, + NS_QUERY_SETUP, + NS_QUERY_START_BEGIN, + NS_QUERY_LOOKUP_BEGIN, + NS_QUERY_RESUME_BEGIN, + NS_QUERY_RESUME_RESTORED, + NS_QUERY_GOT_ANSWER_BEGIN, + NS_QUERY_RESPOND_ANY_BEGIN, + NS_QUERY_RESPOND_ANY_FOUND, + NS_QUERY_ADDANSWER_BEGIN, + NS_QUERY_RESPOND_BEGIN, + NS_QUERY_NOTFOUND_BEGIN, + NS_QUERY_NOTFOUND_RECURSE, + NS_QUERY_PREP_DELEGATION_BEGIN, + NS_QUERY_ZONE_DELEGATION_BEGIN, + NS_QUERY_DELEGATION_BEGIN, + NS_QUERY_DELEGATION_RECURSE_BEGIN, + NS_QUERY_NODATA_BEGIN, + NS_QUERY_NXDOMAIN_BEGIN, + NS_QUERY_NCACHE_BEGIN, + NS_QUERY_ZEROTTL_RECURSE, + NS_QUERY_CNAME_BEGIN, + NS_QUERY_DNAME_BEGIN, + NS_QUERY_PREP_RESPONSE_BEGIN, + NS_QUERY_DONE_BEGIN, + NS_QUERY_DONE_SEND, + + /* XXX other files could be added later */ + + NS_HOOKPOINTS_COUNT /* MUST BE LAST */ +} ns_hookpoint_t; + +/* + * Returned by a hook action to indicate how to proceed after it has + * been called: continue processing, or return immediately. + */ +typedef enum { + NS_HOOK_CONTINUE, + NS_HOOK_RETURN, +} ns_hookresult_t; + +typedef ns_hookresult_t (*ns_hook_action_t)(void *arg, void *data, + isc_result_t *resultp); + +typedef struct ns_hook { + isc_mem_t *mctx; + ns_hook_action_t action; + void *action_data; + ISC_LINK(struct ns_hook) link; +} ns_hook_t; + +typedef ISC_LIST(ns_hook_t) ns_hooklist_t; +typedef ns_hooklist_t ns_hooktable_t[NS_HOOKPOINTS_COUNT]; + +/*% + * ns__hook_table is a global hook table, which is used if view->hooktable + * is NULL. It's intended only for use by unit tests. + */ +LIBNS_EXTERNAL_DATA extern ns_hooktable_t *ns__hook_table; + +/* + * Plugin API version + * + * When the API changes, increment NS_PLUGIN_VERSION. If the + * change is backward-compatible (e.g., adding a new function call + * but not changing or removing an old one), increment NS_PLUGIN_AGE + * as well; if not, set NS_PLUGIN_AGE to 0. + */ +#ifndef NS_PLUGIN_VERSION +#define NS_PLUGIN_VERSION 1 +#define NS_PLUGIN_AGE 0 +#endif /* ifndef NS_PLUGIN_VERSION */ + +typedef isc_result_t +ns_plugin_register_t(const char *parameters, const void *cfg, const char *file, + unsigned long line, isc_mem_t *mctx, isc_log_t *lctx, + void *actx, ns_hooktable_t *hooktable, void **instp); +/*%< + * Called when registering a new plugin. + * + * 'parameters' contains the plugin configuration text. + * + * '*instp' will be set to the module instance handle if the function + * is successful. + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li Other errors are possible + */ + +typedef void +ns_plugin_destroy_t(void **instp); +/*%< + * Destroy a plugin instance. + * + * '*instp' must be set to NULL by the function before it returns. + */ + +typedef isc_result_t +ns_plugin_check_t(const char *parameters, const void *cfg, const char *file, + unsigned long line, isc_mem_t *mctx, isc_log_t *lctx, + void *actx); +/*%< + * Check the validity of 'parameters'. + */ + +typedef int +ns_plugin_version_t(void); +/*%< + * Return the API version number a plugin was compiled with. + * + * If the returned version number is no greater than + * NS_PLUGIN_VERSION, and no less than NS_PLUGIN_VERSION - NS_PLUGIN_AGE, + * then the module is API-compatible with named. + */ + +/*% + * Prototypes for API functions to be defined in each module. + */ +ns_plugin_check_t plugin_check; +ns_plugin_destroy_t plugin_destroy; +ns_plugin_register_t plugin_register; +ns_plugin_version_t plugin_version; + +isc_result_t +ns_plugin_expandpath(const char *src, char *dst, size_t dstsize); +/*%< + * Prepare the plugin location to be passed to dlopen() based on the plugin + * path or filename found in the configuration file ('src'). Store the result + * in 'dst', which is 'dstsize' bytes large. + * + * On Unix systems, two classes of 'src' are recognized: + * + * - If 'src' is an absolute or relative path, it will be copied to 'dst' + * verbatim. + * + * - If 'src' is a filename (i.e. does not contain a path separator), the + * path to the directory into which named plugins are installed will be + * prepended to it and the result will be stored in 'dst'. + * + * On Windows, 'src' is always copied to 'dst' verbatim. + * + * Returns: + *\li #ISC_R_SUCCESS Success + *\li #ISC_R_NOSPACE 'dst' is not large enough to hold the output string + *\li Other result snprintf() returned a negative value + */ + +isc_result_t +ns_plugin_register(const char *modpath, const char *parameters, const void *cfg, + const char *cfg_file, unsigned long cfg_line, + isc_mem_t *mctx, isc_log_t *lctx, void *actx, + dns_view_t *view); +/*%< + * Load the plugin module specified from the file 'modpath', and + * register an instance using 'parameters'. + * + * 'cfg_file' and 'cfg_line' specify the location of the plugin + * declaration in the configuration file. + * + * 'cfg' and 'actx' are the configuration context and ACL configuration + * context, respectively; they are passed as void * here in order to + * prevent this library from having a dependency on libisccfg). + * + * 'instp' will be left pointing to the instance of the plugin + * created by the module's plugin_register function. + */ + +isc_result_t +ns_plugin_check(const char *modpath, const char *parameters, const void *cfg, + const char *cfg_file, unsigned long cfg_line, isc_mem_t *mctx, + isc_log_t *lctx, void *actx); +/*%< + * Open the plugin module at 'modpath' and check the validity of + * 'parameters', logging any errors or warnings found, then + * close it without configuring it. + */ + +void +ns_plugins_create(isc_mem_t *mctx, ns_plugins_t **listp); +/*%< + * Create and initialize a plugin list. + */ + +void +ns_plugins_free(isc_mem_t *mctx, void **listp); +/*%< + * Close each plugin module in a plugin list, then free the list object. + */ + +void +ns_hooktable_free(isc_mem_t *mctx, void **tablep); +/*%< + * Free a hook table. + */ + +void +ns_hook_add(ns_hooktable_t *hooktable, isc_mem_t *mctx, + ns_hookpoint_t hookpoint, const ns_hook_t *hook); +/*%< + * Allocate (using memory context 'mctx') a copy of the 'hook' structure + * describing a hook action and append it to the list of hooks at 'hookpoint' + * in 'hooktable'. + * + * Requires: + *\li 'hooktable' is not NULL + * + *\li 'mctx' is not NULL + * + *\li 'hookpoint' is less than NS_QUERY_HOOKS_COUNT + * + *\li 'hook' is not NULL + */ + +void +ns_hooktable_init(ns_hooktable_t *hooktable); +/*%< + * Initialize a hook table. + */ + +isc_result_t +ns_hooktable_create(isc_mem_t *mctx, ns_hooktable_t **tablep); +/*%< + * Allocate and initialize a hook table. + */ +#endif /* NS_HOOKS_H */ diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h new file mode 100644 index 0000000..9f696e2 --- /dev/null +++ b/lib/ns/include/ns/interfacemgr.h @@ -0,0 +1,202 @@ +/* + * 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. + */ + +#ifndef NS_INTERFACEMGR_H +#define NS_INTERFACEMGR_H 1 + +/***** +***** Module Info +*****/ + +/*! \file + * \brief + * The interface manager monitors the operating system's list + * of network interfaces, creating and destroying listeners + * as needed. + * + * Reliability: + *\li No impact expected. + * + * Resources: + * + * Security: + * \li The server will only be able to bind to the DNS port on + * newly discovered interfaces if it is running as root. + * + * Standards: + *\li The API for scanning varies greatly among operating systems. + * This module attempts to hide the differences. + */ + +/*** + *** Imports + ***/ + +#include <stdbool.h> + +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/netmgr.h> +#include <isc/refcount.h> +#include <isc/socket.h> + +#include <dns/geoip.h> +#include <dns/result.h> + +#include <ns/listenlist.h> +#include <ns/types.h> + +/*** + *** Types + ***/ + +#define IFACE_MAGIC ISC_MAGIC('I', ':', '-', ')') +#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) + +#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */ +#define MAX_UDP_DISPATCH \ + 128 /*%< Maximum number of UDP dispatchers \ + * to start per interface */ +/*% The nameserver interface structure */ +struct ns_interface { + unsigned int magic; /*%< Magic number. */ + ns_interfacemgr_t *mgr; /*%< Interface manager. */ + isc_mutex_t lock; + isc_refcount_t references; + unsigned int generation; /*%< Generation number. */ + isc_sockaddr_t addr; /*%< Address and port. */ + unsigned int flags; /*%< Interface flags */ + char name[32]; /*%< Null terminated. */ + dns_dispatch_t *udpdispatch[MAX_UDP_DISPATCH]; + /*%< UDP dispatchers. */ + isc_socket_t *tcpsocket; /*%< TCP socket. */ + isc_nmsocket_t *udplistensocket; + isc_nmsocket_t *tcplistensocket; + isc_dscp_t dscp; /*%< "listen-on" DSCP value */ + isc_refcount_t ntcpaccepting; /*%< Number of clients + * ready to accept new + * TCP connections on this + * interface */ + isc_refcount_t ntcpactive; /*%< Number of clients + * servicing TCP queries + * (whether accepting or + * connected) */ + int nudpdispatch; /*%< Number of UDP dispatches */ + ns_clientmgr_t *clientmgr; /*%< Client manager. */ + ISC_LINK(ns_interface_t) link; +}; + +/*** + *** Functions + ***/ + +isc_result_t +ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx, + isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, + isc_socketmgr_t *socketmgr, isc_nm_t *nm, + dns_dispatchmgr_t *dispatchmgr, isc_task_t *task, + unsigned int udpdisp, dns_geoip_databases_t *geoip, + int ncpus, ns_interfacemgr_t **mgrp); +/*%< + * Create a new interface manager. + * + * Initially, the new manager will not listen on any interfaces. + * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() + * to set nonempty listen-on lists. + */ + +void +ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target); + +void +ns_interfacemgr_detach(ns_interfacemgr_t **targetp); + +void +ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); + +void +ns_interfacemgr_setbacklog(ns_interfacemgr_t *mgr, int backlog); +/*%< + * Set the size of the listen() backlog queue. + */ + +bool +ns_interfacemgr_islistening(ns_interfacemgr_t *mgr); +/*%< + * Return if the manager is listening on any interface. It can be called + * after a scan or adjust. + */ + +isc_result_t +ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose); +/*%< + * Scan the operatings system's list of network interfaces + * and create listeners when new interfaces are discovered. + * Shut down the sockets for interfaces that go away. + * + * This should be called once on server startup and then + * periodically according to the 'interface-interval' option + * in named.conf. + */ + +void +ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); +/*%< + * Set the IPv4 "listen-on" list of 'mgr' to 'value'. + * The previous IPv4 listen-on list is freed. + */ + +void +ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); +/*%< + * Set the IPv6 "listen-on" list of 'mgr' to 'value'. + * The previous IPv6 listen-on list is freed. + */ + +dns_aclenv_t * +ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); + +void +ns_interface_attach(ns_interface_t *source, ns_interface_t **target); + +void +ns_interface_detach(ns_interface_t **targetp); + +void +ns_interface_shutdown(ns_interface_t *ifp); +/*%< + * Stop listening for queries on interface 'ifp'. + * May safely be called multiple times. + */ + +void +ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); + +bool +ns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, const isc_sockaddr_t *addr); + +ns_server_t * +ns_interfacemgr_getserver(ns_interfacemgr_t *mgr); +/*%< + * Returns the ns_server object associated with the interface manager. + */ + +ns_interface_t * +ns__interfacemgr_getif(ns_interfacemgr_t *mgr); +ns_interface_t * +ns__interfacemgr_nextif(ns_interface_t *ifp); +/* + * Functions to allow external callers to walk the interfaces list. + * (Not intended for use outside this module and associated tests.) + */ +#endif /* NS_INTERFACEMGR_H */ diff --git a/lib/ns/include/ns/lib.h b/lib/ns/include/ns/lib.h new file mode 100644 index 0000000..8c1d113 --- /dev/null +++ b/lib/ns/include/ns/lib.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#pragma once + +/*! \file include/ns/lib.h */ + +#include <isc/lang.h> +#include <isc/types.h> + +ISC_LANG_BEGINDECLS + +LIBNS_EXTERNAL_DATA extern unsigned int ns_pps; + +isc_result_t +ns_lib_init(void); +/*%< + * A set of initialization procedures used in the NS library. + */ + +void +ns_lib_shutdown(void); +/*%< + * Free temporary resources allocated in ns_lib_init(). + */ + +ISC_LANG_ENDDECLS diff --git a/lib/ns/include/ns/listenlist.h b/lib/ns/include/ns/listenlist.h new file mode 100644 index 0000000..74ff87b --- /dev/null +++ b/lib/ns/include/ns/listenlist.h @@ -0,0 +1,101 @@ +/* + * 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. + */ + +#ifndef NS_LISTENLIST_H +#define NS_LISTENLIST_H 1 + +/***** +***** Module Info +*****/ + +/*! \file + * \brief + * "Listen lists", as in the "listen-on" configuration statement. + */ + +/*** + *** Imports + ***/ + +#include <stdbool.h> + +#include <isc/net.h> + +#include <dns/types.h> + +/*** + *** Types + ***/ + +typedef struct ns_listenelt ns_listenelt_t; +typedef struct ns_listenlist ns_listenlist_t; + +struct ns_listenelt { + isc_mem_t *mctx; + in_port_t port; + isc_dscp_t dscp; /* -1 = not set, 0..63 */ + dns_acl_t *acl; + ISC_LINK(ns_listenelt_t) link; +}; + +struct ns_listenlist { + isc_mem_t *mctx; + int refcount; + ISC_LIST(ns_listenelt_t) elts; +}; + +/*** + *** Functions + ***/ + +isc_result_t +ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, + dns_acl_t *acl, ns_listenelt_t **target); +/*%< + * Create a listen-on list element. + */ + +void +ns_listenelt_destroy(ns_listenelt_t *elt); +/*%< + * Destroy a listen-on list element. + */ + +isc_result_t +ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target); +/*%< + * Create a new, empty listen-on list. + */ + +void +ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target); +/*%< + * Attach '*target' to '*source'. + */ + +void +ns_listenlist_detach(ns_listenlist_t **listp); +/*%< + * Detach 'listp'. + */ + +isc_result_t +ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp, + bool enabled, ns_listenlist_t **target); +/*%< + * Create a listen-on list with default contents, matching + * all addresses with port 'port' (if 'enabled' is true), + * or no addresses (if 'enabled' is false). + */ + +#endif /* NS_LISTENLIST_H */ diff --git a/lib/ns/include/ns/log.h b/lib/ns/include/ns/log.h new file mode 100644 index 0000000..eb12ff6 --- /dev/null +++ b/lib/ns/include/ns/log.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#ifndef NS_LOG_H +#define NS_LOG_H 1 + +/*! \file */ + +#include <isc/log.h> +#include <isc/types.h> + +LIBNS_EXTERNAL_DATA extern isc_log_t *ns_lctx; +LIBNS_EXTERNAL_DATA extern isc_logcategory_t ns_categories[]; +LIBNS_EXTERNAL_DATA extern isc_logmodule_t ns_modules[]; + +#define NS_LOGCATEGORY_CLIENT (&ns_categories[0]) +#define NS_LOGCATEGORY_NETWORK (&ns_categories[1]) +#define NS_LOGCATEGORY_UPDATE (&ns_categories[2]) +#define NS_LOGCATEGORY_QUERIES (&ns_categories[3]) +#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_categories[4]) +#define NS_LOGCATEGORY_QUERY_ERRORS (&ns_categories[5]) +#define NS_LOGCATEGORY_TAT (&ns_categories[6]) +#define NS_LOGCATEGORY_SERVE_STALE (&ns_categories[7]) + +/* + * Backwards compatibility. + */ +#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL + +#define NS_LOGMODULE_CLIENT (&ns_modules[0]) +#define NS_LOGMODULE_QUERY (&ns_modules[1]) +#define NS_LOGMODULE_INTERFACEMGR (&ns_modules[2]) +#define NS_LOGMODULE_UPDATE (&ns_modules[3]) +#define NS_LOGMODULE_XFER_IN (&ns_modules[4]) +#define NS_LOGMODULE_XFER_OUT (&ns_modules[5]) +#define NS_LOGMODULE_NOTIFY (&ns_modules[6]) +#define NS_LOGMODULE_HOOKS (&ns_modules[7]) + +void +ns_log_init(isc_log_t *lctx); +/*%< + * Make the libns categories and modules available for use with the + * ISC logging library. + * + * Requires: + *\li lctx is a valid logging context. + * + *\li ns_log_init() is called only once. + * + * Ensures: + *\li The categories and modules defined above are available for + * use by isc_log_usechannnel() and isc_log_write(). + */ + +void +ns_log_setcontext(isc_log_t *lctx); +/*%< + * Make the libns library use the provided context for logging internal + * messages. + * + * Requires: + *\li lctx is a valid logging context. + */ +#endif /* NS_LOG_H */ diff --git a/lib/ns/include/ns/notify.h b/lib/ns/include/ns/notify.h new file mode 100644 index 0000000..2c5fcf3 --- /dev/null +++ b/lib/ns/include/ns/notify.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#ifndef NS_NOTIFY_H +#define NS_NOTIFY_H 1 + +#include <ns/client.h> + +/*** + *** Module Info + ***/ + +/*! \file + * \brief + * RFC1996 + * A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) + */ + +/*** + *** Functions. + ***/ + +void +ns_notify_start(ns_client_t *client, isc_nmhandle_t *handle); + +/*%< + * Examines the incoming message to determine appropriate zone. + * Returns FORMERR if there is not exactly one question. + * Returns REFUSED if we do not serve the listed zone. + * Pass the message to the zone module for processing + * and returns the return status. + * + * Requires + *\li client to be valid. + */ + +#endif /* NS_NOTIFY_H */ diff --git a/lib/ns/include/ns/query.h b/lib/ns/include/ns/query.h new file mode 100644 index 0000000..be0dadd --- /dev/null +++ b/lib/ns/include/ns/query.h @@ -0,0 +1,235 @@ +/* + * 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. + */ + +#ifndef NS_QUERY_H +#define NS_QUERY_H 1 + +/*! \file */ + +#include <stdbool.h> + +#include <isc/buffer.h> +#include <isc/netaddr.h> +#include <isc/types.h> + +#include <dns/rdataset.h> +#include <dns/resolver.h> +#include <dns/rpz.h> +#include <dns/types.h> + +#include <ns/types.h> + +/*% nameserver database version structure */ +typedef struct ns_dbversion { + dns_db_t *db; + dns_dbversion_t *version; + bool acl_checked; + bool queryok; + ISC_LINK(struct ns_dbversion) link; +} ns_dbversion_t; + +/*% + * nameserver recursion parameters, to uniquely identify a recursion + * query; this is used to detect a recursion loop + */ +typedef struct ns_query_recparam { + dns_rdatatype_t qtype; + dns_name_t *qname; + dns_fixedname_t fqname; + dns_name_t *qdomain; + dns_fixedname_t fqdomain; +} ns_query_recparam_t; + +/*% nameserver query structure */ +struct ns_query { + unsigned int attributes; + unsigned int restarts; + bool timerset; + dns_name_t *qname; + dns_name_t *origqname; + dns_rdatatype_t qtype; + unsigned int dboptions; + unsigned int fetchoptions; + dns_db_t *gluedb; + dns_db_t *authdb; + dns_zone_t *authzone; + bool authdbset; + bool isreferral; + isc_mutex_t fetchlock; + dns_fetch_t *fetch; + dns_fetch_t *prefetch; + dns_rpz_st_t *rpz_st; + isc_bufferlist_t namebufs; + ISC_LIST(ns_dbversion_t) activeversions; + ISC_LIST(ns_dbversion_t) freeversions; + dns_rdataset_t *dns64_aaaa; + dns_rdataset_t *dns64_sigaaaa; + bool *dns64_aaaaok; + unsigned int dns64_aaaaoklen; + unsigned int dns64_options; + unsigned int dns64_ttl; + + struct { + dns_db_t *db; + dns_zone_t *zone; + dns_dbnode_t *node; + dns_rdatatype_t qtype; + dns_name_t *fname; + dns_fixedname_t fixed; + isc_result_t result; + dns_rdataset_t *rdataset; + dns_rdataset_t *sigrdataset; + bool authoritative; + bool is_zone; + } redirect; + + ns_query_recparam_t recparam; + + dns_keytag_t root_key_sentinel_keyid; + bool root_key_sentinel_is_ta; + bool root_key_sentinel_not_ta; +}; + +#define NS_QUERYATTR_RECURSIONOK 0x000001 +#define NS_QUERYATTR_CACHEOK 0x000002 +#define NS_QUERYATTR_PARTIALANSWER 0x000004 +#define NS_QUERYATTR_NAMEBUFUSED 0x000008 +#define NS_QUERYATTR_RECURSING 0x000010 +#define NS_QUERYATTR_QUERYOKVALID 0x000040 +#define NS_QUERYATTR_QUERYOK 0x000080 +#define NS_QUERYATTR_WANTRECURSION 0x000100 +#define NS_QUERYATTR_SECURE 0x000200 +#define NS_QUERYATTR_NOAUTHORITY 0x000400 +#define NS_QUERYATTR_NOADDITIONAL 0x000800 +#define NS_QUERYATTR_CACHEACLOKVALID 0x001000 +#define NS_QUERYATTR_CACHEACLOK 0x002000 +#define NS_QUERYATTR_DNS64 0x004000 +#define NS_QUERYATTR_DNS64EXCLUDE 0x008000 +#define NS_QUERYATTR_RRL_CHECKED 0x010000 +#define NS_QUERYATTR_REDIRECT 0x020000 +#define NS_QUERYATTR_ANSWERED 0x040000 +#define NS_QUERYATTR_STALEOK 0x080000 +#define NS_QUERYATTR_STALEPENDING 0x100000 + +typedef struct query_ctx query_ctx_t; + +/* query context structure */ +struct query_ctx { + isc_buffer_t *dbuf; /* name buffer */ + dns_name_t *fname; /* found name from DB lookup */ + dns_name_t *tname; /* temporary name, used + * when processing ANY + * queries */ + dns_rdataset_t *rdataset; /* found rdataset */ + dns_rdataset_t *sigrdataset; /* found sigrdataset */ + dns_rdataset_t *noqname; /* rdataset needing + * NOQNAME proof */ + dns_rdatatype_t qtype; + dns_rdatatype_t type; + + unsigned int options; /* DB lookup options */ + + bool redirected; /* nxdomain redirected? */ + bool is_zone; /* is DB a zone DB? */ + bool is_staticstub_zone; + bool resuming; /* resumed from recursion? */ + bool dns64, dns64_exclude, rpz; + bool authoritative; /* authoritative query? */ + bool want_restart; /* CNAME chain or other + * restart needed */ + bool refresh_rrset; /* stale RRset refresh needed */ + bool need_wildcardproof; /* wildcard proof needed */ + bool nxrewrite; /* negative answer from RPZ */ + bool findcoveringnsec; /* lookup covering NSEC */ + bool answer_has_ns; /* NS is in answer */ + dns_fixedname_t wildcardname; /* name needing wcard proof */ + dns_fixedname_t dsname; /* name needing DS */ + + ns_client_t *client; /* client object */ + bool detach_client; /* client needs detaching */ + + dns_fetchevent_t *event; /* recursion event */ + + dns_db_t *db; /* zone or cache database */ + dns_dbversion_t *version; /* DB version */ + dns_dbnode_t *node; /* DB node */ + + dns_db_t *zdb; /* zone DB values, saved */ + dns_dbnode_t *znode; /* while searching cache */ + dns_name_t *zfname; /* for a better answer */ + dns_dbversion_t *zversion; + dns_rdataset_t *zrdataset; + dns_rdataset_t *zsigrdataset; + + dns_rpz_st_t *rpz_st; /* RPZ state */ + dns_zone_t *zone; /* zone to search */ + + dns_view_t *view; /* client view */ + + isc_result_t result; /* query result */ + int line; /* line to report error */ +}; + +isc_result_t +ns_query_done(query_ctx_t *qctx); +/*%< + * Finalize this phase of the query process: + * + * - Clean up. + * - If we have an answer ready (positive or negative), send it. + * - If we need to restart for a chaining query, call ns__query_start() again. + * - If we've started recursion, then just clean up; things will be + * restarted via fetch_callback()/query_resume(). + */ + +isc_result_t +ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, + dns_name_t *qdomain, dns_rdataset_t *nameservers, + bool resuming); +/*%< + * Prepare client for recursion, then create a resolver fetch, with + * the event callback set to fetch_callback(). Afterward we terminate + * this phase of the query, and resume with a new query context when + * recursion completes. + */ + +isc_result_t +ns_query_init(ns_client_t *client); + +void +ns_query_free(ns_client_t *client); + +void +ns_query_start(ns_client_t *client, isc_nmhandle_t *handle); + +void +ns_query_cancel(ns_client_t *client); + +/* + * The following functions are expected to be used only within query.c + * and query modules. + */ + +isc_result_t +ns__query_sfcache(query_ctx_t *qctx); +/*%< + * (Must not be used outside this module and its associated unit tests.) + */ + +isc_result_t +ns__query_start(query_ctx_t *qctx); +/*%< + * (Must not be used outside this module and its associated unit tests.) + */ + +#endif /* NS_QUERY_H */ diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h new file mode 100644 index 0000000..6ace9f3 --- /dev/null +++ b/lib/ns/include/ns/server.h @@ -0,0 +1,189 @@ +/* + * 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. + */ + +#ifndef NS_SERVER_H +#define NS_SERVER_H 1 + +/*! \file */ + +#include <inttypes.h> +#include <stdbool.h> + +#include <isc/fuzz.h> +#include <isc/log.h> +#include <isc/magic.h> +#include <isc/quota.h> +#include <isc/random.h> +#include <isc/sockaddr.h> +#include <isc/types.h> + +#include <dns/acl.h> +#include <dns/types.h> + +#include <ns/types.h> + +#define NS_EVENT_CLIENTCONTROL (ISC_EVENTCLASS_NS + 0) + +#define NS_SERVER_LOGQUERIES 0x00000001U /*%< log queries */ +#define NS_SERVER_NOAA 0x00000002U /*%< -T noaa */ +#define NS_SERVER_NOSOA 0x00000004U /*%< -T nosoa */ +#define NS_SERVER_NONEAREST 0x00000008U /*%< -T nonearest */ +#define NS_SERVER_NOEDNS 0x00000020U /*%< -T noedns */ +#define NS_SERVER_DROPEDNS 0x00000040U /*%< -T dropedns */ +#define NS_SERVER_NOTCP 0x00000080U /*%< -T notcp */ +#define NS_SERVER_DISABLE4 0x00000100U /*%< -6 */ +#define NS_SERVER_DISABLE6 0x00000200U /*%< -4 */ +#define NS_SERVER_FIXEDLOCAL 0x00000400U /*%< -T fixedlocal */ +#define NS_SERVER_SIGVALINSECS 0x00000800U /*%< -T sigvalinsecs */ +#define NS_SERVER_EDNSFORMERR 0x00001000U /*%< -T ednsformerr (STD13) */ +#define NS_SERVER_EDNSNOTIMP 0x00002000U /*%< -T ednsnotimp */ +#define NS_SERVER_EDNSREFUSED 0x00004000U /*%< -T ednsrefused */ + +/*% + * Type for callback function to get hostname. + */ +typedef isc_result_t (*ns_hostnamecb_t)(char *buf, size_t len); + +/*% + * Type for callback function to signal the fuzzer thread + * when built with AFL. + */ +typedef void (*ns_fuzzcb_t)(void); + +/*% + * Type for callback function to get the view that can answer a query. + */ +typedef isc_result_t (*ns_matchview_t)( + isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr, dns_message_t *message, + dns_aclenv_t *env, isc_result_t *sigresultp, dns_view_t **viewp); + +/*% + * Server context. + */ +struct ns_server { + unsigned int magic; + isc_mem_t *mctx; + + isc_refcount_t references; + + /*% Server cookie secret and algorithm */ + unsigned char secret[32]; + ns_cookiealg_t cookiealg; + ns_altsecretlist_t altsecrets; + bool answercookie; + + /*% Quotas */ + isc_quota_t recursionquota; + isc_quota_t tcpquota; + isc_quota_t xfroutquota; + isc_quota_t updquota; + + /*% Test options and other configurables */ + uint32_t options; + + dns_acl_t *blackholeacl; + dns_acl_t *keepresporder; + uint16_t udpsize; + uint16_t transfer_tcp_message_size; + bool interface_auto; + dns_tkeyctx_t *tkeyctx; + + /*% Server id for NSID */ + char *server_id; + ns_hostnamecb_t gethostname; + + /*% Fuzzer callback */ + isc_fuzztype_t fuzztype; + ns_fuzzcb_t fuzznotify; + + /*% Callback to find a matching view for a query */ + ns_matchview_t matchingview; + + /*% Stats counters */ + ns_stats_t *nsstats; + dns_stats_t *rcvquerystats; + dns_stats_t *opcodestats; + dns_stats_t *rcodestats; + + isc_stats_t *udpinstats4; + isc_stats_t *udpoutstats4; + isc_stats_t *udpinstats6; + isc_stats_t *udpoutstats6; + + isc_stats_t *tcpinstats4; + isc_stats_t *tcpoutstats4; + isc_stats_t *tcpinstats6; + isc_stats_t *tcpoutstats6; +}; + +struct ns_altsecret { + ISC_LINK(ns_altsecret_t) link; + unsigned char secret[32]; +}; + +isc_result_t +ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview, + ns_server_t **sctxp); +/*%< + * Create a server context object with default settings. + */ + +void +ns_server_attach(ns_server_t *src, ns_server_t **dest); +/*%< + * Attach a server context. + * + * Requires: + *\li 'src' is valid. + */ + +void +ns_server_detach(ns_server_t **sctxp); +/*%< + * Detach from a server context. If its reference count drops to zero, destroy + * it, freeing its memory. + * + * Requires: + *\li '*sctxp' is valid. + * Ensures: + *\li '*sctxp' is NULL on return. + */ + +isc_result_t +ns_server_setserverid(ns_server_t *sctx, const char *serverid); +/*%< + * Set sctx->server_id to 'serverid'. If it was set previously, free the memory. + * + * Requires: + *\li 'sctx' is valid. + */ + +void +ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value); +/*%< + * Set the given options on (if 'value' == #true) + * or off (if 'value' == #false). + * + * Requires: + *\li 'sctx' is valid + */ + +bool +ns_server_getoption(ns_server_t *sctx, unsigned int option); +/*%< + * Returns the current value of the specified server option. + * + * Requires: + *\li 'sctx' is valid. + */ +#endif /* NS_SERVER_H */ diff --git a/lib/ns/include/ns/sortlist.h b/lib/ns/include/ns/sortlist.h new file mode 100644 index 0000000..a2eedd9 --- /dev/null +++ b/lib/ns/include/ns/sortlist.h @@ -0,0 +1,83 @@ +/* + * 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. + */ + +#ifndef NS_SORTLIST_H +#define NS_SORTLIST_H 1 + +/*! \file */ + +#include <isc/types.h> + +#include <dns/acl.h> +#include <dns/types.h> + +/*% + * Type for callback functions that rank addresses. + */ +typedef int (*dns_addressorderfunc_t)(const isc_netaddr_t *address, + const void *arg); + +/*% + * Return value type for setup_sortlist. + */ +typedef enum { + NS_SORTLISTTYPE_NONE, + NS_SORTLISTTYPE_1ELEMENT, + NS_SORTLISTTYPE_2ELEMENT +} ns_sortlisttype_t; + +ns_sortlisttype_t +ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr, + const void **argp); +/*%< + * Find the sortlist statement in 'acl' (for ACL environment 'env') + * that applies to 'clientaddr', if any. + * + * If a 1-element sortlist item applies, return NS_SORTLISTTYPE_1ELEMENT and + * make '*argp' point to the matching subelement. + * + * If a 2-element sortlist item applies, return NS_SORTLISTTYPE_2ELEMENT and + * make '*argp' point to ACL that forms the second element. + * + * If no sortlist item applies, return NS_SORTLISTTYPE_NONE and set '*argp' + * to NULL. + */ + +int +ns_sortlist_addrorder1(const isc_netaddr_t *addr, const void *arg); +/*%< + * Find the sort order of 'addr' in 'arg', the matching element + * of a 1-element top-level sortlist statement. + */ + +int +ns_sortlist_addrorder2(const isc_netaddr_t *addr, const void *arg); +/*%< + * Find the sort order of 'addr' in 'arg', a topology-like + * ACL forming the second element in a 2-element top-level + * sortlist statement. + */ + +void +ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, dns_aclenv_t *env, + isc_netaddr_t *client_addr, + dns_addressorderfunc_t *orderp, const void **argp); +/*%< + * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. + * If a sortlist statement applies, return in '*orderp' a pointer to a function + * for ranking network addresses based on that sortlist statement, and in + * '*argp' an argument to pass to said function. If no sortlist statement + * applies, set '*orderp' and '*argp' to NULL. + */ + +#endif /* NS_SORTLIST_H */ diff --git a/lib/ns/include/ns/stats.h b/lib/ns/include/ns/stats.h new file mode 100644 index 0000000..b9564aa --- /dev/null +++ b/lib/ns/include/ns/stats.h @@ -0,0 +1,141 @@ +/* + * 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. + */ + +#ifndef NS_STATS_H +#define NS_STATS_H 1 + +/*! \file include/ns/stats.h */ + +#include <ns/types.h> + +/*% + * Server statistics counters. Used as isc_statscounter_t values. + */ +enum { + ns_statscounter_requestv4 = 0, + ns_statscounter_requestv6 = 1, + ns_statscounter_edns0in = 2, + ns_statscounter_badednsver = 3, + ns_statscounter_tsigin = 4, + ns_statscounter_sig0in = 5, + ns_statscounter_invalidsig = 6, + ns_statscounter_requesttcp = 7, + + ns_statscounter_authrej = 8, + ns_statscounter_recurserej = 9, + ns_statscounter_xfrrej = 10, + ns_statscounter_updaterej = 11, + + ns_statscounter_response = 12, + ns_statscounter_truncatedresp = 13, + ns_statscounter_edns0out = 14, + ns_statscounter_tsigout = 15, + ns_statscounter_sig0out = 16, + + ns_statscounter_success = 17, + ns_statscounter_authans = 18, + ns_statscounter_nonauthans = 19, + ns_statscounter_referral = 20, + ns_statscounter_nxrrset = 21, + ns_statscounter_servfail = 22, + ns_statscounter_formerr = 23, + ns_statscounter_nxdomain = 24, + ns_statscounter_recursion = 25, + ns_statscounter_duplicate = 26, + ns_statscounter_dropped = 27, + ns_statscounter_failure = 28, + + ns_statscounter_xfrdone = 29, + + ns_statscounter_updatereqfwd = 30, + ns_statscounter_updaterespfwd = 31, + ns_statscounter_updatefwdfail = 32, + ns_statscounter_updatedone = 33, + ns_statscounter_updatefail = 34, + ns_statscounter_updatebadprereq = 35, + + ns_statscounter_recursclients = 36, + + ns_statscounter_dns64 = 37, + + ns_statscounter_ratedropped = 38, + ns_statscounter_rateslipped = 39, + + ns_statscounter_rpz_rewrites = 40, + + ns_statscounter_udp = 41, + ns_statscounter_tcp = 42, + + ns_statscounter_nsidopt = 43, + ns_statscounter_expireopt = 44, + ns_statscounter_otheropt = 45, + ns_statscounter_ecsopt = 46, + ns_statscounter_padopt = 47, + ns_statscounter_keepaliveopt = 48, + + ns_statscounter_nxdomainredirect = 49, + ns_statscounter_nxdomainredirect_rlookup = 50, + + ns_statscounter_cookiein = 51, + ns_statscounter_cookiebadsize = 52, + ns_statscounter_cookiebadtime = 53, + ns_statscounter_cookienomatch = 54, + ns_statscounter_cookiematch = 55, + ns_statscounter_cookienew = 56, + ns_statscounter_badcookie = 57, + + ns_statscounter_nxdomainsynth = 58, + ns_statscounter_nodatasynth = 59, + ns_statscounter_wildcardsynth = 60, + + ns_statscounter_trystale = 61, + ns_statscounter_usedstale = 62, + + ns_statscounter_prefetch = 63, + ns_statscounter_keytagopt = 64, + + ns_statscounter_tcphighwater = 65, + + ns_statscounter_reclimitdropped = 66, + + ns_statscounter_updatequota = 67, + + ns_statscounter_max = 68, +}; + +void +ns_stats_attach(ns_stats_t *stats, ns_stats_t **statsp); + +void +ns_stats_detach(ns_stats_t **statsp); + +isc_result_t +ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp); + +void +ns_stats_increment(ns_stats_t *stats, isc_statscounter_t counter); + +void +ns_stats_decrement(ns_stats_t *stats, isc_statscounter_t counter); + +isc_stats_t * +ns_stats_get(ns_stats_t *stats); + +void +ns_stats_update_if_greater(ns_stats_t *stats, isc_statscounter_t counter, + isc_statscounter_t value); + +isc_statscounter_t +ns_stats_get_counter(ns_stats_t *stats, isc_statscounter_t counter); + +#endif /* NS_STATS_H */ diff --git a/lib/ns/include/ns/types.h b/lib/ns/include/ns/types.h new file mode 100644 index 0000000..f16f9a0 --- /dev/null +++ b/lib/ns/include/ns/types.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#ifndef NS_TYPES_H +#define NS_TYPES_H 1 + +/*! \file */ + +typedef struct ns_altsecret ns_altsecret_t; +typedef ISC_LIST(ns_altsecret_t) ns_altsecretlist_t; +typedef struct ns_client ns_client_t; +typedef struct ns_clientmgr ns_clientmgr_t; +typedef struct ns_plugin ns_plugin_t; +typedef ISC_LIST(ns_plugin_t) ns_plugins_t; +typedef struct ns_interface ns_interface_t; +typedef struct ns_interfacemgr ns_interfacemgr_t; +typedef struct ns_query ns_query_t; +typedef struct ns_server ns_server_t; +typedef struct ns_stats ns_stats_t; + +typedef enum { ns_cookiealg_aes, ns_cookiealg_siphash24 } ns_cookiealg_t; + +#define NS_COOKIE_VERSION_1 1 + +#endif /* NS_TYPES_H */ diff --git a/lib/ns/include/ns/update.h b/lib/ns/include/ns/update.h new file mode 100644 index 0000000..72ac604 --- /dev/null +++ b/lib/ns/include/ns/update.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#ifndef NS_UPDATE_H +#define NS_UPDATE_H 1 + +/***** +***** Module Info +*****/ + +/*! \file + * \brief + * RFC2136 Dynamic Update + */ + +/*** + *** Imports + ***/ + +#include <dns/result.h> +#include <dns/types.h> + +/*** + *** Types. + ***/ + +/*** + *** Functions + ***/ + +void +ns_update_start(ns_client_t *client, isc_nmhandle_t *handle, + isc_result_t sigresult); + +#endif /* NS_UPDATE_H */ diff --git a/lib/ns/include/ns/version.h b/lib/ns/include/ns/version.h new file mode 100644 index 0000000..e342717 --- /dev/null +++ b/lib/ns/include/ns/version.h @@ -0,0 +1,18 @@ +/* + * 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/ns/version.h */ + +#include <isc/platform.h> + +LIBNS_EXTERNAL_DATA extern const char ns_version[]; diff --git a/lib/ns/include/ns/xfrout.h b/lib/ns/include/ns/xfrout.h new file mode 100644 index 0000000..8f0809e --- /dev/null +++ b/lib/ns/include/ns/xfrout.h @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#ifndef NS_XFROUT_H +#define NS_XFROUT_H 1 + +/***** +***** Module Info +*****/ + +/*! \file + * \brief + * Outgoing zone transfers (AXFR + IXFR). + */ + +/*** + *** Functions + ***/ + +void +ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype); + +#endif /* NS_XFROUT_H */ |