summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/libdhcpsrv.dox
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcpsrv/libdhcpsrv.dox')
-rw-r--r--src/lib/dhcpsrv/libdhcpsrv.dox516
1 files changed, 516 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/libdhcpsrv.dox b/src/lib/dhcpsrv/libdhcpsrv.dox
new file mode 100644
index 0000000..e2ec0a8
--- /dev/null
+++ b/src/lib/dhcpsrv/libdhcpsrv.dox
@@ -0,0 +1,516 @@
+// Copyright (C) 2012-2022 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 libdhcpsrv libkea-dhcpsrv - Server DHCP Library
+
+This library contains code used for the DHCPv4 and DHCPv6 servers' operations,
+including the "Lease Manager" that manages information about leases and the
+"Configuration Manager" that stores the servers' configuration etc.
+The code here is server specific. For generic (useful to the server,
+client, relay and other tools like perfdhcp) code, please see
+\ref libdhcp.
+
+This library contains several crucial elements for the operation of the DHCP server:
+
+- isc::dhcp::CfgGlobals - global scalar (i.e. not list or map) parameters.
+- isc::dhcp::LeaseMgr - lease manager is the name for the database backend that stores
+ leases.
+- isc::dhcp::CfgMgr - configuration manager that holds DHCP specific
+ configuration information (subnets, pools, options, timer values etc.) in
+ easy to use format.
+- isc::dhcp::AllocEngine - allocation engine that handles new requests and allocates new
+ leases.
+- isc::dhcp::HostMgr - manager for static reservations (a.k.a. host reservations).
+- isc::dhcp::D2ClientMgr - DHCP-DDNS (D2) client manager which is responsible for
+ the communication between the DHCP server and the D2 component.
+- isc::dhcp::Dhcp4o6IpcBase - common part (base class) of DHCPv4-over-DHCPv6
+ inter server communication (aka IPC).
+
+@section cfgglobals Global Parameters
+
+The global parameters handle direct (vs using a search in a name to
+value table) access to global scalar (i.e. not list or map) parameter values.
+
+This is related to the procedure to add a new global scalar parameter to
+the DHCPv4 or DHCPv6 (DHCPvX below) server implementation:
+
+- update the src/bin/dhcpX/dhcpX_lexer.ll to add the new token
+- update the src/bin/dhcpX/dhcpX_parser.yy to add the new syntax
+- update the src/bin/dhcpX/json_config_parser.cc to add the new parameter
+ in the global parameter big if statement
+- update the src/lib/dhcpsrv/parsers/simple_parserX.cc file to add the new
+ parameter in the GLOBALX_PARAMETERS keyword list and eventually in the
+ GLOBALX_DEFAULTS list
+- update the cfg_globals.h and cfg_globals.cc files, note that specific to
+ v4 or v6 parameters are after no specific
+- if the parameter exists for shared networks, subnets, etc,
+ the corresponding tables must be updated in simple parser files
+
+Note there is nothing to update for a global parameter in the configuration
+backend: no new column in database schemas, no code in hooks. Of course
+this does not apply to parameters which exist at not global level too.
+
+@section leasemgr Lease Manager
+
+LeaseMgr provides a common, unified abstract API for all database backends. All
+backends are derived from the base class isc::dhcp::LeaseMgr. Currently Kea
+supports three backends, implemented in the following classes:
+
+- isc::dhcp::Memfile_LeaseMgr - stores leases in a CSV file,
+- isc::dhcp::MySqlLeaseMgr - stores leases in a MySQL database
+- isc::dhcp::PgSqlLeaseMgr - stores leases in a PostgreSQL database
+
+@section cfgmgr Configuration Manager
+
+Configuration Manager (\ref isc::dhcp::CfgMgr) is a singleton object which
+holds configuration information necessary for the operation of Kea daemons.
+A complete collection of information for the daemon is stored in the
+\ref isc::dhcp::SrvConfig object. Internally, the Configuration Manager
+holds a list of \ref isc::dhcp::SrvConfig objects, from which one
+is marked as "current configuration".
+
+When the server starts up or is being reconfigured a new
+\ref isc::dhcp::SrvConfig object, referred to as "staging configuration",
+is created. The staging configuration is held at the tip of the list of
+configurations. The object can be accessed by calling the
+\ref isc::dhcp::CfgMgr::getStagingCfg. This object can be accessed
+from different stages of the configuration parsing and modified as needed.
+Modifications of the staging configuration do not affect the current
+configuration. The staging configuration is unused until the
+\ref isc::dhcp::CfgMgr::commit function is called. This exception safe method
+marks the staging object as "current configuration". The const pointer to the
+current configuration can be accessed by calling a
+\ref isc::dhcp::CfgMgr::getCurrentCfg.
+
+The staging configuration can be discarded at any time before it is committed
+by calling the \ref isc::dhcp::CfgMgr::rollback. This removes the
+\ref isc::dhcp::SrvConfig object from the Configuration Manager. When
+the \ref isc::dhcp::CfgMgr::getStagingCfg is called again a fresh/default
+\ref isc::dhcp::SrvConfig object is returned.
+
+The Configuration Manager stores previous configurations, i.e. configurations
+which occurred prior to the most current configuration. This is currently
+unused (except for unit tests) by the daemons, but in the future this
+mechanism can be used to trigger a rollover of the server configuration
+to a last good configuration that the administrator prefers.
+
+The previous configurations are identified by the value which specifies a
+distance between the current configuration and the previous
+configuration. For example: the value of 1 identifies an immediate
+predecessor of the current configuration, the value of 2 identifies the
+one that occurred before it etc.
+
+All configuration classes are derived from the abstract base class
+\ref isc::data::CfgToElement and define the toElement virtual method
+which returns a \ref isc::data::ConstElementPtr which must be
+parsed into the same object, i.e. fulfill this property:
+@code
+for all valid C: parse(parse(C)->toElement()) == parse(C)
+@endcode
+
+
+@section hostmgr Host Manager
+
+Host Manager implemented by the \ref isc::dhcp::HostMgr is a singleton object
+which provides means to retrieve resources statically assigned to the DHCP
+clients, such as IP addresses, prefixes or hostnames. The statically assigned
+resources are called reservations (or host reservations) and they are
+represented in the code by the \ref isc::dhcp::Host class.
+
+The reservations can be specified in the configuration file or in some
+other storage (typically in a database). A dedicated object, called
+host data source, is needed to retrieve the host reservations from the
+database. This object must implement the \ref isc::dhcp::BaseHostDataSource
+interface and its implementation is specific to the type of storage
+holding the reservations. For example, the host data source managing
+host reservations in the MySQL database is required to establish
+connection to the MySQL database and issue specific queries. A factory
+method creating an instance of a base host data source object must be
+registered (at global object initialization for built-in backends,
+dynamically for backends loaded at run-time). See host_data_source_factory.cc
+for example code that registers MySQL and PostgreSQL. Note, that this instance
+is created as "alternate host data source" as opposed to the primary data
+source which returns host reservations specified in the configuration file.
+The primary data source is implemented internally in the
+\ref isc::dhcp::HostMgr and uses the configuration data structures held by
+the \ref isc::dhcp::CfgMgr to retrieve the reservations. In general, the
+\ref isc::dhcp::HostMgr first searches for the reservations using the
+primary data source and falls back to the use of alternate data source
+when nothing has been found. For those methods which are meant to return
+multiple reservations (e.g. find all reservations for the particular
+client), the \ref isc::dhcp::HostMgr will use both primary and alternate
+data source (if present) and concatenate results.
+
+For more information about the \ref isc::dhcp::HostMgr please refer to its
+documentation.
+
+@subsection postgreSQLHostMgr PostgreSQL Host Reservation Management
+
+Storing and retrieving host reservations within a PostgreSQL schema is
+provided by the class, \ref isc::dhcp::PgSqlHostDataSource, a derivation of
+\ref isc::dhcp::BaseHostDataSource and is depicted in the following
+class diagram:
+
+@image html pgsql_host_data_source.svg "PgSqlHostDataSource Class Diagram"
+
+@section optionsConfig Options Configuration Information
+
+The \ref isc::dhcp::CfgOption object holds a collection of options being
+sent to the client. Since each subnet comes with a distinct set of
+options, every \ref isc::dhcp::Subnet object holds its own copy of the
+\ref isc::dhcp::CfgOption object with specific options.
+
+The DHCP server also allows for configuration of "global" options
+which are shared by all subnets. The rule here is that if a particular
+option appears in the global options set and the subnet specific options
+set, the subnet specific option takes precedence. The global options
+configuration is held in the dedicated instance of the
+\ref isc::dhcp::CfgOption class. This instance is owned by the
+\ref isc::dhcp::SrvConfig class.
+
+When the new configuration is parsed, the global options are merged into
+the \ref isc::dhcp::CfgOption instances for all subnets. This is
+causing some overhead during the reconfiguration of the server but on
+the other hand it avoids the lookup of options in two places (among
+subnet specific options and global options) during each packet
+processing.
+
+One of the benefits of keeping a separate set of global options is
+that there may be cases when the server administrator doesn't specify
+any subnet configuration and only wants global options to be used.
+This is the case, when the DHCP server is used for stateless
+configuration, i.e. client's are not allocated an address or prefix,
+and only stateless configuration is handed out.
+
+@section allocengine Allocation Engine
+
+Allocation Engine (\ref isc::dhcp::AllocEngine) is what its name say - an engine
+that handles allocation of new leases. It takes parameters that the client
+provided (client-id, DUID, subnet, a hint if the user provided one, etc.) and
+then attempts to allocate a lease.
+
+There is no single best solution to the address assignment problem. Server
+is expected to pick an address from its available pools is currently not used.
+There are many possible algorithms that can do that, each with its own advantages
+and drawbacks. This allocation engine must provide robust operation is radically
+different scenarios, so there address selection problem was abstracted into
+separate module, called allocator. Its sole purpose is to pick an address from
+a pool. Allocation engine will then check if the picked address is free and if
+it is not, then will ask allocator to pick again.
+
+At least 3 allocators will be implemented:
+
+- Iterative - it iterates over all resources (addresses or prefixes) in
+available pools, one by one. The advantages of this approach are: speed
+(typically it only needs to increase address just one), the guarantee to cover
+all addresses and predictability. This allocator behaves reasonably good in
+case of nearing depletion. Even when pools are almost completely allocated, it
+still will be able to allocate outstanding leases efficiently. Predictability
+can also be considered a serious flaw in some environments, as prediction of the
+next address is trivial and can be leveraged by an attacker. Another drawback of
+this allocator is that it does not attempt to give the same address to returning
+clients (clients that released or expired their leases and are requesting a new
+lease will likely to get a different lease). This allocator is not suitable for
+temporary addresses, which must be randomized. This allocator is implemented
+in \ref isc::dhcp::AllocEngine::IterativeAllocator.
+
+- Hashed - ISC-DHCP uses hash of the client-id or DUID to determine, which
+address is tried first. If that address is not available, the result is hashed
+again. That procedure is repeated until available address is found or there
+are no more addresses left. The benefit of that approach is that it provides
+a relative lease stability, so returning old clients are likely to get the same
+address again. The drawbacks are increased computation cost, as each iteration
+requires use of a hashing function. That is especially difficult when the
+pools are almost depleted. It also may be difficult to guarantee that the
+repeated hashing will iterate over all available addresses in all pools. Flawed
+hash algorithm can go into cycles that iterate over only part of the addresses.
+It is difficult to detect such issues as only some initial seed (client-id
+or DUID) values may trigger short cycles. This allocator is currently not
+implemented. This will be the only allocator allowed for temporary addresses.
+
+- Random - Another possible approach to address selection is randomization. This
+allocator can pick an address randomly from the configured pool. The benefit
+of this approach is that it is easy to implement and makes attacks based on
+address prediction more difficult. The drawback of this approach is that
+returning clients are almost guaranteed to get a different address. Another
+drawback is that with almost depleted pools it is increasingly difficult to
+"guess" an address that is free. This allocator is currently not implemented.
+
+@subsection allocEngineTypes Different lease types support
+
+Allocation Engine has been extended to support different types of leases. Four
+types are supported: TYPE_V4 (IPv4 addresses), TYPE_NA (normal IPv6 addresses),
+TYPE_TA (temporary IPv6 addresses) and TYPE_PD (delegated prefixes). Support for
+TYPE_TA is partial. Some routines are able to handle it, while other are
+not. The major missing piece is the RandomAllocator, so there is no way to randomly
+generate an address. This defeats the purpose of using temporary addresses for now.
+
+@subsection allocEnginePD Prefix Delegation support in AllocEngine
+
+The Allocation Engine supports allocation of the IPv6 addresses and prefixes.
+For a prefix pool, the iterative allocator "walks over"
+every available pool. It is similar to how it iterates over address pool,
+but instead of increasing address by just one, it walks over the whole delegated
+prefix length in one step. This is implemented in
+isc::dhcp::AllocEngine::IterativeAllocator::increasePrefix(). Functionally the
+increaseAddress(addr) call is equivalent to increasePrefix(addr, 128)
+(increasing by a /128 prefix, i.e. a single address). However, both methods are
+kept, because increaseAddress() is faster and this is a routine that may be
+called many hundred thousands times per second.
+
+@subsection allocEngineDHCPv4HostReservation Host Reservation support
+
+The Allocation Engine supports allocation of statically assigned addresses
+to the DHCPv4 clients, a.k.a. Host Reservation.
+
+When the server receives a DHCPDISCOVER or DHCPREQUEST from the client it
+calls \ref isc::dhcp::AllocEngine::allocateLease4 to obtain the suitable lease
+for the client. If the Allocation Engine determines that the particular client
+has a reservation it will try to allocate a reserved address for it. If the
+client requested allocation or renewal of a different address, the Allocation
+Engine will respond with a NULL lease to indicate that the address
+desired by the client could not be assigned. The DHCP server should send
+a DHCPNAK to the client and the client should fall back to the DHCP
+server discovery. When the client sends DHCPDISCOVER, the Allocation
+Engine offers the reserved address and the client should request the
+offered address in subsequent DHCPREQUEST messages.
+
+There are cases when the Allocation Engine is unable to assign the
+reserved address for the client. This includes the situations when
+the address had been previously reserved for another client or the
+address had been assigned out of the dynamic address pool. Such address
+may still remain in use of the client which obtained it first and the
+Allocation Engine must not assign it to the client for which it is
+reserved until the client using this address releases or the server
+assigns a different address for it.
+
+In order to resolve this conflict the Allocation Engine will refuse to
+renew the lease for the client using the address not reserved for it.
+This client should fall back to the 4-way exchange and the Allocation
+Engine will assign a different address. As a result, the reserved
+address will be freed for the use of the client for which the reservation
+was made. The client will be offered/allocated a reserved address
+the next time it retries sending a DHCPDISCOVER/DHCPREQUEST message to
+the server.
+
+@subsection allocEngineReuse Allocation Engine Cache
+
+The allocation engine provides a cache-like feature: when a suitable
+lease already exists for a client if its age is small enough compared
+to the valid lifetime (threshold parameter) and below a configured maximum
+(max age parameter) the lease can be reused. A reusable lease is marked
+by a not zero reuseable_valid_lft_ value.
+
+@section timerManager Timer Manager
+
+The @c isc::dhcp::TimerMgr is a singleton class used throughout the
+server process to register and unregister timers triggering periodic
+tasks such as lease file cleanup, reclamation of expired leases etc.
+
+The Timer Manger is using ASIO deadline timers (wrapped in
+@c isc::asiolink::IntervalTimer class) to execute tasks according to
+the configured periods. Therefore, the server process must provide the
+Timer Manager with the pointer to the @c isc::asiolink::IOService which
+the server is using to run asynchronous tasks.
+
+Current implementation of the DHCP servers uses synchronous calls to
+@c select() function to check if any transmission has been received
+on any socket. This poses a problem with running asynchronous calls
+via @c IOService in the main server loop because the @c select()
+blocks for a specified amount of time while asynchronous calls
+are not triggered. In the future we should migrate from the synchronous
+@c select() calls into asynchronous calls using ASIO. Currently,
+we mitigate the problem by lowering the @c select() timeout to 1s,
+and polling @c IOService for "ready" timers (handlers) after
+@c select() returns. This may cause delays of "ready" handlers
+execution by around 1s. However, this is acceptable for the current
+applications of the periodic timers.
+
+@section leaseReclamationRoutine Leases Reclamation Routine
+
+Lease reclamation is the process in which the expired lease becomes
+available for re-assignment to the same or another client. When the
+server reclaims the lease it executes the callouts registered for the
+"lease4_expire" and "lease6_expire" hook points, performs the DNS update
+to remove any DNS records associated with the expired lease, and finally
+marks a lease as reclaimed in the lease database. The lease may be
+marked as reclaimed by setting its state to @c Lease::STATE_EXPIRED_RECLAIMED
+or by being removed from the database.
+
+Reclamation is performed periodically for a bulk of expired
+leases in the lease reclamation routine. The lease reclamation routines
+for both DHCP servers are implemented in the @c isc::dhcp::AllocEngine:
+- @c isc::dhcp::AllocEngine::reclaimExpiredLeases4 (DHCPv4)
+- @c isc::dhcp::AllocEngine::reclaimExpiredLeases6 (DHCPv6)
+
+Note that besides the reclamation of the leases, these methods also
+update the relevant statistics, i.e. decrease the number of assigned
+leases and increase the number of reclaimed leases.
+
+The reclamation routines are executed periodically according to
+the server configuration (see the documentation for the
+"expired-leases-processing" configuration map). Internally, they are
+registered as callback functions in the @c isc::dhcp::TimerMgr
+(see @ref timerManager for the details), during the servers' startup
+or reconfiguration.
+
+Execution of the reclamation routine may take a relatively
+long period of time. It depends on the complexity of the callouts,
+whether the DNS update is required for leases, and the type of the
+lease database used. While the reclamation routine is
+executed, the server will not process any DHCP messages to avoid
+race conditions being a result of concurrent access to the lease
+database to allocate and reclaim leases. To make sure that the
+server remains responsive, it is possible to limit the number of
+leases being processed by the leases reclamation routine and/or
+limit the time for the reclamation routine to process
+leases. Both limits are specified in the respective arguments
+passed to the lease reclamation routines.
+
+As mentioned above, reclaimed leases may be marked as such, by
+updating their state to @c Lease::STATE_EXPIRED_RECLAIMED or by
+being removed. This behavior is controlled by the boolean parameter
+passed to the reclamation routine. The first approach is desired
+when the server should provide "lease affinity", i.e. ability to
+re-assign the same lease to the returning client. By only
+updating the lease state, the server preserves association of the
+lease with a particular client. When that client returns the
+server may assign the same lease to the client, assuming that this
+lease is still available. The lease is removed during the
+reclamation when the lease affinity is not required and it is
+preferred to not keep redundant information (about expired
+leases) in the lease database.
+
+If the reclaimed leases are not removed, they are held in the
+database for a specified amount of time after their expiration.
+Each reclaimed lease is removed when this time elapses for it.
+The @c isc::dhcp::LeaseMgr::deleteExpiredReclaimedLeases4 and
+@c isc::dhcp::LeaseMgr::deleteExpiredReclaimedLeases6 are used
+to remove those leases for which the specified amount of time
+since expiration elapsed. These methods are executed periodically
+by the DHCP servers using the dedicated timers registered in the
+@c isc::dhcp::TimerMgr.
+
+@section subnetSelect Subnet Selection
+
+An important service offered by this library is the subnet selection
+from a query packet.
+
+@subsection dhcp4SubnetSelect DHCPv4 Subnet Selection
+
+Selectors (i.e., members of @c SubnetSelector class) are:
+- incoming interface name
+- gateway address - giaddr field
+- client address - ciaddr field
+- local address
+- remote address
+- option select - from the first Relay Agent Link Selection suboption or
+ from a Subnet Selection option
+- client classes - used to reject a matching rule and try next rules
+
+First use the option select, next if the message was relayed (not undefined
+gateway address) use the gateway address as a subnet relay address.
+
+If a subnet was not already selected choose an address between:
+
+- if the gateway address is not undefined the gateway address
+- if the client address is not undefined and the local address not the
+ broadcast address (i.e., renew or rebind) the client address
+- if the remote address is not undefined and the local address not the
+ broadcast address (i.e., renew or rebind) the remote address
+- at this point try the interface name as a subnet interface
+- if the interface name does not select a subnet choose the interface address
+ (last resort)
+
+Match the chosen address in a subnet address range.
+
+@subsection dhcp4o6SubnetSelect DHCPv4-over-DHCPv6 Subnet Selection
+
+Selectors (i.e., members of @c SubnetSelector class) are:
+- incoming interface name
+- gateway address - giaddr field (should be always undefined)
+- client address - ciaddr field
+- local address - set to the interface IPv4 address
+- remote address - IPv6 address
+- option select - from a Subnet Selection option
+- first relay link address - (IPv6) undefined or the first relay link
+ address which is not undefined or link local (i.e., usable)
+- interface ID - (IPv6) when a relay message includes an interface ID
+ relay option
+- client classes - used to reject a matching rule and try next rules
+
+Check if DHCPv4-over-DHCPv6 is enabled for this particular subnet and
+continue with the next subnet is if it is not.
+
+First the remote address is matched in a subnet IPv6 range, second
+the interface ID if it is set is matched, third the interface name.
+
+These rules are applied for each subnet configuration so if two
+subnets match the first one is returned (vs. the first matching rule).
+
+@todo better DHCPv4-over-DHCPv6 selection, e.g., handle relayed
+messages and return best (vs first) match.
+
+@subsection dhcp6SubnetSelection DHCPv6 Subnet Selection
+
+Selectors (i.e., members of @c SubnetSelector class) are:
+- incoming interface name
+- remote address
+- first relay link address - undefined or the first relay link address which
+ is not undefined or link local (i.e., usable)
+- interface ID - when a relay message includes an interface ID relay option
+- client classes - used to reject a matching rule and try next rules
+
+If the first relay link address is undefined the client is directly connected:
+the interface name is matched and if it does not select a subnet the remote
+address is matched in a subnet address range.
+
+If the first relay link address is not undefined the query was relayed:
+the interface ID is tried and if it does not select a subnet the first
+relay address is matched as a subnet relay address.
+
+@section dhcp4o6Ipc DHCPv4-over-DHCPv6 Inter Process Communication
+
+DHCPv4-over-DHCPv6 support is implemented using cooperating
+DHCPv6 and DHCPv6 servers. Servers communicate over a pair of
+local UDP sockets using consecutive ports. The common part of
+the Inter Process Communication (IPC) is provided by the base class
+@c isc::dhcp::Dhcp4o6IpcBase.
+
+The receiving interface name and remote IPv6 address meta information
+are conveyed within a Vendor Specific Information option with the ISC
+enterprise ID carrying interface and remote address suboptions.
+\ref isc::dhcp::Dhcp4o6IpcBase::send adds them,
+\ref isc::dhcp::Dhcp4o6IpcBase::receive decodes and removes them.
+
+Also see \ref dhcpv4o6Dhcp4 and \ref dhcpv4o6Dhcp6 for details on how IPC
+is used by DHCPv4 and DHCPv6 components.
+
+@todo
+
+DHCPv4-over-DHCPv6 which are relayed by a DHCPv6 relay are not yet supported.
+
+@section libdhcpsrvMTConsiderations Multi-Threading Consideration for Server DHCP Library
+
+Note that for backends specific consideration is in @ref
+dhcpDatabaseBackendsMTConsiderations.
+
+Below Kea thread safe means thread safe when the multi-threading mode is
+true (when it is false packets are processed by the main thread).
+
+By default this library is not thread safe, in particular all classes used
+for configuration are not thread safe. Exceptions are:
+
+ - allocation engine allocator is Kea thread safe.
+
+ - resource handler is thread safe.
+
+ - last allocated members of subnets are Kea thread safe.
+
+ - timer manager functions are Kea thread safe.
+
+*/