diff options
Diffstat (limited to 'src/bin/d2/d2.dox')
-rw-r--r-- | src/bin/d2/d2.dox | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/src/bin/d2/d2.dox b/src/bin/d2/d2.dox new file mode 100644 index 0000000..8a41e52 --- /dev/null +++ b/src/bin/d2/d2.dox @@ -0,0 +1,316 @@ +// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC") +// +// 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 http://mozilla.org/MPL/2.0/. + +/** + @page d2 DHCP-DDNS Component + +Kea is capable of sending dynamic DNS updates to DNS Servers, based on lease +changes made by Kea's DHCP servers. When DDNS updating is enabled, +the DHCP servers generate requests to update DNS as they make lease changes. +These requests, implemented by isc::dhcp_ddns::NameChangeRequest (NCR), are sent +to a separate process, informally known as D2. D2 processes these requests by +carrying out DDNS conversations with the appropriate DNS servers such that they +update the DNS data. + +The design documentation for D2 can be found here: +<a href="https://gitlab.isc.org/isc-projects/kea/wikis/designs/ddns-design">D2 Design</a>. + +The implementation is split in several libraries which can be used separately +(linked only when required): +- src/lib/dns (libkea-dns++) - contains classes and enumerations which define +DNS update message, message content, EDNS, RData, RR Types, RCODEs, OPCODEs, +DNS Name, TSIG key and TSIG record, exception types, etc. +- src/lib/dhcp_ddns (libkea-dhcp_ddns) - contains classes to send and receive, +encapsulate and decapsulate DNS messages, etc. +- src/lib/d2srv (libkea-d2srv) - contains classes to handle NCR transactions, +the DNS client implementation, statistics, configuration parser and manager, +logger, DNS Zone, etc. +- src/bin/d2 (kea-dhcp-ddns) - contains classes which handle message queues, +D2 process and D2 controller internals, etc. + +This document contains several UML diagrams, and a few conventions used within +these diagrams are worth noting: + +- If a class is appearing on class diagram for the first time (within this +document) its background color will be yellow. If it has been presented +already, its background color will be blue and/or its details may not be shown. + +- Associations between classes in D2 are implemented in most cases via typedefs, +sometimes through a small chain of typedefs. These typedefs are shown for +accuracy but are unimportant to a general discussion. + +@section d2ProcessDerivation D2's CPL Derivations + +D2's core application classes are DDNS-specific derivations of the CPL as show +in the diagram below: + +@image html d2_app_classes.svg "D2's CPL Derivations" + +- isc::d2::D2Controller - entry point for running D2, it processes command line +options, starts and controls the application process, @c D2Process +(see @ref src/bin/d2/d2_controller.h). + +- isc::d2::D2Process - creates and manages D2's primary resources and +implements the main event loop described in @ref d2EventLoop section +(see @ref src/bin/d2/d2_process.h). + +- isc::d2::D2CfgMgr - creates, updates, and provides access to D2's application +configuration which is embodied by @c D2CfgContext +(see @ref src/lib/d2srv/d2_cfg_mgr.h). + +- isc::d2::D2CfgContext - warehouses D2's application configuration +(see @ref src/lib/d2srv/d2_cfg_mgr.h). + +@section d2ConfigMgt Configuration Management + +D2's configuration management uses the same underlying mechanisms as Kea's DHCP +servers. It's configuration information is organized into a hierarchical data +model which is mirrored in the implementation by a hierarchy of parser classes +and the runtime classes they instantiate. + +D2's data model is organized as follows: + +- A set of application level values such as the D2's IP address, port + +- Two lists of "domains": one for Forward DNS and one for Reverse DNS. @n + Each domain is described by a zone name and a list of DNS servers that can + update that zone. + +- A list of TSIG keys for conducting signed DDNS exchanges with DNS servers + +The runtime classes that embody this model are shown in the following diagram: + +@image html config_data_classes.svg "D2's Configuration Data Classes" + +- isc::d2::D2CfgContext - D2-specific derivation of @c DCfgContextBase. It +houses the "global" configuration for an instance of D2 +(see @ref src/lib/d2srv/d2_cfg_mgr.h). + +- isc::d2::DdnsDomainListMgr - manages a list of domains. Currently there is +one manager instance for the list of forward domains, and one for the list of +reverse domains. In addition the domain list, it will may house other values +specific to that list of domains (e.g. enable flag) +(see @ref src/lib/d2srv/d2_config.h). + +- isc::d2::DdnsDomain - represents a DNS domain (really a zone). When requests +are received they are matched to a domain by comparing their FQDN to the +domain's name (see @ref src/lib/d2srv/d2_config.h). + +- isc::d2::DnsServerInfo - describes a DNS server which supports DDNS for a +given domain (see @ref src/lib/d2srv/d2_config.h). + +- isc::d2::TSIGKeyInfo - describes a TSIG key used for authenticated DDNS for a +given domain (see @ref src/lib/d2srv/d2_config.h). + +The parsing classes, as one would expect, parallel the runtime classes quite +closely. The parsers are named for the runtime class they instantiate and are +either designed to parse a single occurrence of that class or list of that +class. The parser classes are shown in the diagram below: + +@image html config_parser_classes.svg "D2's Configuration Parsers" + +- isc::d2::DdnsDomainListMgrParser - parser for a domain list manager, it +creates a domain list parser. + +- isc::d2::DdnsDomainListParser - parser for a list of domains, it creates a +domain parser for domain described in a list domains. + +- isc::d2::DdnsDomainParser - Parser for a domain, it creates a DNS server list +parser. + +- isc::d2::DnsServerInfoListParser - parser for a list of DNS servers, it +creates a DNS server parser for server described in a list of servers. + +- isc::d2::DnsServerInfoParser - parser for DNS server. + +- isc::d2::TSIGKeyInfoListParser - parser for a list of TSIG keys, it creates a +parser for key described in a list of keys. + +- isc::d2::TSIGKeyInfoParser - parser for TSIG key. + +For more details on the parsers see @ref src/lib/d2srv/d2_config.h. + +The underlying common libraries for configuration parsing support configuration +input in JSON format, that complies with a fixed set of generic constructs that +may be described by a spec file (also JSON). + +@section d2NCRReceipt Request Reception and Queuing + +D2 is designed to receive requests from Kea's DHCP servers, asynchronously and +store them in queue to be processed. The classes responsible for this are +shown in the diagram below: + +@image html request_mgt_classes.svg "Request Management Classes" + +- isc::d2::D2QueueMgr - owned by @c D2Process, it listens for +@c NameChangeRequests and queues them for processing. It also provides services +for adding, finding, and removing queue entries. It owns the interface used to +receive requests and thus shields the remainder of D2 from any specific +knowledge or interaction with this interface +(see @ref src/bin/d2/d2_queue_mgr.h). + +- isc::d2::RequestQueue - storage container for the received requests +(see @ref src/bin/d2/d2_queue_mgr.h). + +- isc::dhcp_ddns::NameChangeListener - Abstract asynchronous interface for +receiving requests which uses ASIO to process IO and invoke a callback upon +request receipt (see @ref src/lib/dhcp_ddns/ncr_io.h). + +- isc::dhcp_ddns::NameChangeUDPListener - Derivation of NameChangeListener +which supports receiving request via UDP socket +(see @ref src/lib/dhcp_ddns/ncr_udp.h). + +- isc::dhcp_ddns::NameChangeRequest - embodies a request to update DNS entries +based upon a DHCP lease change (see @ref src/lib/dhcp_ddns/ncr_msg.h). + +D2QueueMgr is state-driven, albeit with a very simple state model. The states +are defined by isc::d2::D2QueueMgr::State (see @ref src/bin/d2/d2_queue_mgr.h). + +@section d2DDNSUpdateExecution Update Execution + +The DDNS protocol can lead to a multiple step conversation between the updater +and the DNS server to update entries for a single client. In addition, +@c NameChangeRequests can request changes be made for both forward and reverse +DNS. In order to carry out the appropriate conversation, D2 wraps each request +in a stateful transaction. + +Working such transactions serially can be inefficient, especially if those +requests involve different DNS servers. Therefore, D2 has been designed to +work on more than one transaction at a time by creating and managing a list of +transactions. + +The classes which are responsible for carrying out this work are shown in the +following diagram: + +@image html update_exec_classes.svg "Update Execution Classes" + +- isc::d2::D2UpdateMgr owned by @c D2Process, orchestrates the fulfillment of +each request by managing the execution of its transaction. Its high level +method @ref isc::d2::D2UpdateMgr::sweep() is meant to be called whenever IO +events occur (see @ref src/bin/d2/d2_update_mgr.h). The following steps are +performed each time the method is called: + - Any transaction which has been completed, is logged and culled from the + transaction list. + - Start a new transaction for the next queued request (if any). + +- isc::d2::NameChangeTransaction - abstract state-driven class which carries +out the steps necessary to fulfill a single request. Fulfilling a request is +achieved as IO events in response it DDNS requests drive the transaction through +its state model (see @ref src/lib/d2srv/nc_trans.h). The type of transaction is +based on the nature of the request, this is discussed further on +@ref d2TransDetail section. + +- isc::d2::DNSClient - an asynchronous worker which atomically performs a +single DDNS packet exchange with a given server, providing the response via a +callback mechanism. Each time a transaction's state model calls for a packet +exchange with a DNS server, it uses an instance of this class to do it +(see @ref src/lib/d2srv/dns_client.h). + +- isc::d2::D2UpdateMessage - container for sending and receiving DDNS packets +(see @ref src/lib/d2srv/d2_update_message.h). + +@section d2EventLoop Main Event Loop + +Now that all of the primary components have been introduced it is worth while +discussing D2's main event loop. As mentioned earlier D2 is constructed around +the CPL which is designed to be driven by asynchronous IO processed by a common +IO service thread (isc::asiolink::io_service). Any IO that needs to be +performed by the application thread uses this service to do so. This organizes +the IO event processing into a single event loop centered around the service. +(This does not preclude spinning off worker threads to conduct other tasks, with +their own io_service instances). D2's main event loop, implemented in +@ref isc::d2::D2Process::run() may be paraphrased as follows: + +@code + As long as we should not shutdown repeat the following steps: + 1. Check on the state of the request queue. Take any actions necessary + regarding it. For example, it may be in the process of shutting down + its listener prior to applying a configuration change. + + 2. Give update manager a "time slice" to cull finished transactions and + start new ones. + + 3. Block until one or more of the following IO events occur: + a. NCR message has been received + b. Transaction IO has completed + c. Interval timer expired + d. A process command has been received + e. Something has stopped the IO service (most likely a fatal error) +@endcode + +@section d2TransDetail Transactions + +There are two types of @c NameChangeRequests: an "Add" that is issued when DNS +entries need to be added for new or updated lease, and a "Remove" that is +issued when DNS entries need to be removed for obsolete or expired lease. The +DDNS protocol dictates the steps that should be followed in both cases. + +D2's design addresses this by calling for two types of transactions: one for +adding entries and one for removing them, each with their own state model. +The transaction classes are shown in the following diagram: + +@image html trans_classes.svg "NameChangeTransaction Derivations" + +- isc::d2::NameAddTransaction - carries out a @c NameChangeRequest to add +entries (see @ref src/bin/d2/nc_add.h). + +- isc::d2::NameRemoveTransaction - carries out a @c NameChangeRequest to remove +entries (see @ref src/bin/d2/nc_remove.h). + +- isc::util::StateModel - abstract state model described in @ref d2StateModel +section (see @ref src/lib/util/state_model.h). + +The state models for these two transactions implement DDNS with conflict +resolution as described in <a href="https://tools.ietf.org/html/rfc4703">RFC 4703</a>. + +The state model for isc::d2::NameAddTransaction is diagrammed below: + +@image html add_state_model.svg "State Model for NameAddTransaction" + +The state model for isc::d2::NameRemoveTransaction is depicted next: + +@image html remove_state_model.svg "State Model for NameRemoveTransaction" + +@subsection d2StateModel State Model Implementation + +D2 implements a abstract state-machine through a light weight set of classes. +At construction, the model's dictionary of events and states is initialized. +This allows, the deriving class the ability to bind a method of its choosing +to each state as that state's handler. Each handler contains the knowledge +of how to respond to the "posted" event and including posting other events and +transitioning to other states. + +Executing the model consists of beginning at the current state with the posted +event and continuing until the model needs to wait for an IO-based event or +it has reached the end of the state model. These classes will likely move to +a common library. + +@image html state_model_classes.svg "State Model Classes" + +- isc::util::StateModel - provides the mechanics for executing a state model +described by a dictionary events and states. It provides methods to: + - initialize the model - constructs the dictionary of events and states. + - start the model - sets the model to its initial state, posts a "start" + event and starts the model "running". + - run the model - process the posted event (if one) until the model reaches + a wait state or reaches the end state. + - transition from one state to another. +- isc::d2::Event - Defines an event used to stimulate the model. +- isc::d2::State - Defines a state with the model, each state has a handler +method that is executed upon transition "into" that state from another state. +- isc::d2::LabeledValue - An abstract that associates a integer value with a +text label. +- isc::d2::LabeledValueSet - A collection of LabeledValues for which the integer +values must be unique. + +@subsection d2TransExecExample Transaction Execution Example + +The following sequence chart depicts the typically sequence of events that occur +when D2UpdateMgr creates and starts executing a transaction: + +@image html nc_trans_sequence.svg "Transaction Execution Sequence" + +*/ |