Browse Source

[3484] Updated Developer's Guide for the DHCPv4 server.

Marcin Siodelski 9 years ago
parent
commit
b7720538a4
1 changed files with 113 additions and 26 deletions
  1. 113 26
      src/bin/dhcp4/dhcp4.dox

+ 113 - 26
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<uint32_t>
+ 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<uint32_t>(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