From: Marcin Siodelski Date: Wed, 8 Jul 2015 11:33:47 +0000 (+0200) Subject: [3484] Updated Developer's Guide for the DHCPv4 server. X-Git-Tag: trac4006_base~25^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7720538a4be30b63d423c73a7823a374e46dbc0;p=thirdparty%2Fkea.git [3484] Updated Developer's Guide for the DHCPv4 server. --- diff --git a/src/bin/dhcp4/dhcp4.dox b/src/bin/dhcp4/dhcp4.dox index 6288f52c1f..50b47bc82b 100644 --- a/src/bin/dhcp4/dhcp4.dox +++ b/src/bin/dhcp4/dhcp4.dox @@ -15,34 +15,125 @@ /** @page dhcp4 DHCPv4 Server Component -Kea offers DHCPv4 server implementation. It is implemented as -kea-dhcp4 component. Its primary code is located in -isc::dhcp::Dhcpv4Srv class. It uses \ref libdhcp extensively, -especially isc::dhcp::Pkt4, isc::dhcp::Option and -isc::dhcp::IfaceMgr classes. Currently this code offers skeleton -functionality, i.e. it is able to receive and process incoming -requests and transmit responses. However, it does not have database -management, so it returns only one, hardcoded lease to whoever asks -for it. - -DHCPv4 server component does not support direct traffic (relayed -only), as support for transmission to hosts without IPv4 address -assigned is not implemented in IfaceMgr yet. +Kea includes the "kea-dhcp4" component, which is the DHCPv4 server +implementation. This component is built around the +@ref isc::dhcp::Dhcpv4Srv class which controls all major operations +performed by the server such as: DHCP messages processing, callouts +execution for many hook points, FQDN processing and interactions with the +"kea-dhcp-ddns" component, lease allocation, system signals handling etc. + +The "kea-dhcp4" component requires linking with many different libraries +to obtain access to common functions like: interfaces and sockets +management, configuration parsing, leases management and allocation, +hooks infrastructure, statistics management etc. + +The following sections walk through some of the details of the "kea-dhcp4" +component implementation. @section dhcpv4ConfigParser Configuration Parser in DHCPv4 -This parser follows exactly the same logic as its DHCPv6 counterpart. -See \ref dhcpv6ConfigParser. +The common configuration parsers for the DHCP servers are located in the +src/lib/dhcpsrv/parsers/ directory. Parsers specific to the DHCPv4 component +are located in the src/bin/dhcp4/json_config_parser.cc. These parsers derive +from the common configuration parsers and customize their behavior. For +example: the @c Subnet4ConfigParser is used to parse parameters +describing a single subnet. It derives from the @ref +isc::dhcp::SubnetConfigParser, which implements the common base for both +DHCPv4 and DHCPv6 subnets. The @ref isc::dhcp::Subnet4ConfigParser +implements the @c initSubnet abstract method, which creates an instance of +the DHCPv4 subnet. This method is invoked by the parent class. + +Some parsers for the DHCPv4 server derive from the isc::dhcp::DhcpConfigParser +class directly. This is an abstract class, defining a basic interface for +all configuration parsers. All DHCPv4 parsers deriving from this class +directly have their entire implementation in the +src/bin/dhcp4/json_config_parser.cc. @section dhcpv4ConfigInherit DHCPv4 configuration inheritance -Configuration inheritance in DHCPv4 follows exactly the same logic as its DHCPv6 -counterpart. See \ref dhcpv6ConfigInherit. +One notable useful feature of DHCP configuration is its parameter inheritance. +For example, "renew-timer" value may be specified at a global scope and it then +applies to all subnets. However, some subnets may have it overwritten with subnet +specific values that takes precedence over global values that are considered +defaults. The parameters inheritance is implemented by means of the "global +context". The global context is represented by the @ref isc::dhcp::ParserContext +class and it holds pointers to storages of different kind, e.g. text parameters, +numeric parameters etc. When the server is parsing the top level configuration +parameters it passes pointers to the storages of the appropriate kind, to the +parsers being invoked to parse the global values. Parsers will store the +parsed values into these storages. Once the global parameters are stored in the +global context, the parsers for the nested configuration parameters are invoked. +These parsers check the presence of the parameters overriding the values of +the global parameters. If a value is not present, the values from the global +context is used. + +A good example of inheritance is the implementation of the @ref +isc::dhcp::SubnetConfigParser. The @c getParam method is used throughout the +class to obtain values of the parameters defining a subnet. It first checks +if the specific value is present in the local values storage. If it is not +present, it uses the value from the global context. + + @code + isc::dhcp::Triplet + SubnetConfigParser::getParam(const std::string& name) { + uint32_t value = 0; + try { + // look for local value + value = uint32_values_->getParam(name); + } catch (const DhcpConfigError &) { + try { + // no local, use global value + value = global_context_->uint32_values_->getParam(name); + } catch (const DhcpConfigError &) { + isc_throw(DhcpConfigError, "Mandatory parameter " << name + << " missing (no global default and no subnet-" + << "specific value)"); + } + } + + return (Triplet(value)); +} +@endcode + +Note that if the value is neither present in the local storage nor in the global +context an error is signalled. + +Parameter inheritance is done once, during the reconfiguration phase. +Reconfigurations are rare, so extra logic here is not a problem. On the other +hand, values of those parameters may be used thousands times per second, so +access to these parameters must be as efficient as possible. In fact, +currently the code has to only call @c Subnet4::getT1(), regardless if the +"renew-timer" has been specified as a global or subnet specific value. + +Debugging configuration parser may be confusing. Therefore there is a special +class called DebugParser. It does not configure anything, but just +accepts any parameter of any type. If requested to commit configuration, it will +print out received parameter name and its value. This class is not currently used, +but it is convenient to have it every time a new parameter is added to DHCP +configuration. For that purpose it should be left in the code. @section dhcpv4OptionsParse Custom functions to parse message options -The DHCPv4 server uses the same logic to supply custom callback function to -parse message option as DHCPv6 server implementation. See \ref dhcpv6OptionsParse. +The DHCPv4 server implementation provides a generic support to define option +formats and set option values. A number of options formats have been defined +for standard options in libdhcp++. However, the formats for vendor specific +options are dynamically configured by the server's administrator and thus can't +be stored in libdhcp++. Such option formats are stored in the +@ref isc::dhcp::CfgMgr. The libdhcp++ provides functions for recursive parsing +of options which may be encapsulated by other options up to the any level of +encapsulation but these functions are unaware of the option formats defined +in the @ref isc::dhcp::CfgMgr because they belong to a different library. +Therefore, the generic functions @ref isc::dhcp::LibDHCP::unpackOptions4 and +@ref isc::dhcp::LibDHCP::unpackOptions4 are only useful to parse standard +options which definitions are provided in the libdhcp++. In order to overcome +this problem a callback mechanism has been implemented in @c Option and @c Pkt4 +classes. By installing a callback function on the instance of the @c Pkt4 the +server may provide a custom implementation of the options parsing algorithm. +This callback function will take precedence over the @c LibDHCP::unpackOptions4 +and @c LibDHCP::unpackOptions4 functions. With this approach, the callback is +implemented within the context of the server and it has access to all objects +which define its configuration (including dynamically created option +definitions). @section dhcpv4DDNSIntegration DHCPv4 Server Support for the Dynamic DNS Updates T @@ -201,13 +292,9 @@ through the main loop. This method fetches the last received signal and calls a handler function defined in the kea_controller.cc. The handler function calls a static function @c configure defined in the kea_controller.cc. -In order for the signal handler to know the location of the configuration file -(specified at process startup), the location of this file needs to be stored -in a static variable so as it may be directly accessed by the signal handler. -This static variable is stored in the @c dhcp::Daemon class and all Kea processes -can use it (all processes derive from this class). The configuration file -location is initialized when the @c Daemon::init method is called. Therefore, -derived classes should call it in their implementations of the @c init method. +The signal handler reconfigures the server using the configuration file +specified at the server startup. The location of this file is held in the +@c Daemon class. @section dhcpv4Other Other DHCPv4 topics