summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcp/libdhcp++.dox
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcp/libdhcp++.dox')
-rw-r--r--src/lib/dhcp/libdhcp++.dox280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/lib/dhcp/libdhcp++.dox b/src/lib/dhcp/libdhcp++.dox
new file mode 100644
index 0000000..ef47dd7
--- /dev/null
+++ b/src/lib/dhcp/libdhcp++.dox
@@ -0,0 +1,280 @@
+// Copyright (C) 2012-2020 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 libdhcp libkea-dhcp++ - Low Level DHCP Library
+
+@section libdhcpIntro Libdhcp++ Library Introduction
+
+libdhcp++ is an all-purpose DHCP-manipulation library, written in
+C++. It offers packet parsing and assembly, DHCPv4 and DHCPv6
+options parsing and assembly, interface detection (currently on
+Linux, FreeBSD, NetBSD, OpenBSD, Max OS X, and Solaris 11) and socket operations.
+It is a generic purpose library that
+can be used by server, client, relay, performance tools and other DHCP-related
+tools. For server specific library, see \ref libdhcpsrv. Please do not
+add any server-specific code to libdhcp++ and use \ref libdhcpsrv instead.
+
+The following classes for packet manipulation are implemented:
+
+- isc::dhcp::Pkt4 - represents a DHCPv4 packet.
+- isc::dhcp::Pkt6 - represents a DHCPv6 packet.
+- isc::dhcp::Pkt4o6 - represents a DHCPv4-over-DHCPv6 packet.
+
+The following pointer types are defined: \c Pkt4Ptr, \c Pkt6Ptr and Pkt4o6Ptr.
+They are smart pointers using the \c boost::shared_ptr type. There are no const
+versions of packet types defined, as we assume that hooks can modify any
+aspect of the packet at almost any stage of processing.
+
+Both packet types use a collection of \ref isc::dhcp::Option objects to
+represent DHCPv4 and DHCPv6 options. The base class @c Option can be used to
+represent generic option that contains collection of
+bytes. Depending on whether the option is instantiated as a DHCPv4 or DHCPv6
+option, it will adjust its header (DHCPv4 options use 1 octet for
+type and 1 octet for length, while DHCPv6 options use 2 bytes for
+each).
+
+There are many specialized classes that are intended to handle options having
+specific formats:
+- isc::dhcp::Option4AddrLst -- DHCPv4 option, contains one or more IPv4 addresses;
+- isc::dhcp::Option6AddrLst -- DHCPv6 option, contains one or more IPv6 addresses;
+- isc::dhcp::Option4ClientFqdn -- DHCPv4 Client FQDN option;
+- isc::dhcp::Option6ClientFqdn -- DHCPv6 Client FQDN option;
+- isc::dhcp::Option6IAAddr -- DHCPv6 option, represents an IAADDR option (an option that
+ contains IPv6 address with extra parameters);
+- isc::dhcp::Option6IAPrefix -- DHCPv6 option, represents an IAPREFIX option (an option
+ that contains IPv6 prefix in prefix delegation);
+- isc::dhcp::Option6IA -- DHCPv6 option used to store IA_NA and its suboptions.
+- isc::dhcp::Option6StatusCode -- DHCPv6 option, carries a status code to the client;
+- isc::dhcp::OptionCustom -- Represents an option having many different formats, where
+ data fields can be accessed in a convenient way;
+- isc::dhcp::OptionInt -- DHCPv4 or DHCPv6 option, carries a single numeric value;
+- isc::dhcp::OptionString -- DHCPv4 or DHCPv6 option, carries a text value;
+- isc::dhcp::OptionVendor -- DHCPv4 or DHCPv6 option, carries Vendor Specific
+ Information;
+- isc::dhcp::OptionVendorClass -- DHCPv4 or DHCPv6 option, contains vendor class
+ information.
+
+Various options can store sub-options (i.e. options that are stored within an
+option rather than in a message directly). This functionality is commonly used in
+DHCPv6, but is rarely used in DHCPv4. \ref isc::dhcp::Option::addOption(),
+\ref isc::dhcp::Option::delOption(), \ref isc::dhcp::Option::getOption() can
+be used to add, remove and retrieve sub-options from within an option.
+
+@section libdhcpDhcp4o6 DHCPv4-over-DHCPv6 support
+
+The DHCPv4-over-DHCPv6 packet class (\c Pkt4o6) is derived from
+the DHCPv4 packet class (\c Pkt4) with:
+
+- un extra member pointing to the encapsulating DHCPv6 packet, accessible
+ by \ref isc::dhcp::Pkt4o6::getPkt6()
+- a specialized isc::dhcp::Pkt::pack() method which builds the wire-format
+ data of the whole DHCPv6-over-DHCPv4 packet.
+
+To avoid the extra overhead of dynamic casts the isc::dhcp::Pkt4::isDhcp4o6()
+virtual method returns true for \c Pkt4o6 instances and false for others.
+
+@section libdhcpRelay Relay v6 support in Pkt6
+
+DHCPv6 clients that are not connected to the same link as DHCPv6
+servers need relays to reach the server. Each relay receives a message
+on a client facing interface, encapsulates it into RELAY_MSG option
+and sends as RELAY_FORW message towards the server (or the next relay,
+which is closer to the server). This procedure can be repeated up to
+32 times. Kea is able to support up to 32 relays. Each traversed relay
+may add certain options. The most obvious example is interface-id
+option, but there may be other options as well. Each relay may add such
+an option, regardless of whether other relays added it before. Thanks
+to encapsulation, those options are separated and it is possible to
+differentiate which relay inserted specific instance of an option.
+
+Interface-id is used to identify a subnet (or interface) the original message
+came from and is used for that purpose on two occasions. First, the server
+uses the interface-id included by the first relay (the one closest to
+the client) to select appropriate subnet for a given request. Server includes
+that interface-id in its copy, when sending data back to the client.
+This will be used by the relay to choose proper interface when forwarding
+response towards the client.
+
+The Pkt6 class has a public \c Pkt6::relay_info_ field, which is of type \c Pkt6::RelayInfo.
+This is a simple structure that represents the information in each RELAY_FORW
+or RELAY_REPL message. It is important to understand the order in which
+the data appear here. Consider the following network:
+
+\verbatim
+client-------relay1-----relay2-----relay3----server
+\endverbatim
+
+Client will transmit SOLICIT message. Relay1 will forward it as
+RELAY_FORW with SOLICIT in it. Relay2 forward it as RELAY_FORW with
+RELAY_FORW with SOLICIT in it. Finally the third relay will add yet
+another RELAY_FORW around it. The server will parse the packet and
+create \c Pkt6 object for it. Its relay_info_ will have 3
+elements. Packet parsing is done in reverse order, compare to the
+order the packet traversed in the network. The first element
+(relay_info_[0]) will represent relay3 information (the "last" relay or
+in other words the one closest to the server). The second element
+will represent relay2. The third element (relay_info_[2]) will represent
+the first relay (relay1) or in other words the one closest to the client.
+
+Packets sent by the server must maintain the same encapsulation order.
+This is easy to do - just copy data from client's message object into
+server's response object. See @ref isc::dhcp::Pkt6::RelayInfo for details.
+
+@section libdhcpIfaceMgr Interface Manager
+
+Interface Manager (or IfaceMgr) is an abstraction layer for low-level
+network operations. In particular, it provides information about existing
+network interfaces See @ref isc::dhcp::Iface class and
+@ref isc::dhcp::IfaceMgr::detectIfaces() and @ref isc::dhcp::IfaceMgr::getIface().
+
+Generic parts of the code are contained in the @ref isc::dhcp::IfaceMgr class in
+src/lib/dhcp/iface_mgr.cc file. OS-specific code is located in separate
+files, e.g. iface_mgr_linux.cc, iface_mgr_bsd. The separation should be
+maintained when developing additional code.
+
+Other useful methods are dedicated to transmission
+(\ref isc::dhcp::IfaceMgr::send(), 2 overloads) and reception
+(\ref isc::dhcp::IfaceMgr::receive4() and \ref isc::dhcp::IfaceMgr::receive6()).
+Note that \c receive4() and \c receive6() methods may return NULL, e.g.
+when timeout is reached or if the DHCP daemon receives a signal.
+
+@section libdhcpPktFilter Switchable Packet Filter objects used by Interface Manager
+
+The well known problem of DHCPv4 implementation is that it must be able to
+provision devices which don't have an IPv4 address yet (the IPv4 address is
+one of the configuration parameters provided by DHCP server to a client).
+One way to communicate with such a device is to send server's response to
+a broadcast address. An obvious drawback of this approach is that the server's
+response will be received and processed by all clients in the particular
+network. Therefore, the preferred approach is that the server unicasts its
+response to a new address being assigned for the client. This client will
+identify itself as a target of this message by checking chaddr and/or
+Client Identifier value. At the same time, the other clients in the network
+will not receive the unicast message. The major problem that arises with this
+approach is that the client without an IP address doesn't respond to ARP
+messages. As a result, server's response will not be sent over IP/UDP
+socket because the system kernel will fail to resolve client's link-layer
+address.
+
+Kea supports the use of raw sockets to create a complete Data-link/IP/UDP/DHCPv4
+stack. By creating each layer of the outgoing packet, the Kea logic has full
+control over the frame contents and it may bypass the use of ARP to inject the
+link layer address into the frame.
+
+The low level operations on raw sockets are implemented within the "packet
+filtering" classes derived from @c isc::dhcp::PktFilter. The implementation
+of these classes is specific to the operating system. On Linux the
+@c isc::dhcp::PktFilterLPF is used. On BSD systems the
+@c isc::dhcp::PktFilterBPF is used.
+
+The raw sockets are bound to a specific interface, not to the IP address/UDP port.
+Therefore, the system kernel doesn't have means to verify that Kea is listening
+to the DHCP traffic on the specific address and port. This has two major implications:
+- It is possible to run another DHCPv4 sever instance which will bind socket to the
+same address and port.
+- An attempt to send a unicast message to the DHCPv4 server will result in ICMP
+"Port Unreachable" message being sent by the kernel (which is unaware that the
+DHCPv4 service is actually running).
+
+In order to overcome these issues, the packet filtering classes open a
+regular IP/UDP socket which coexists with the raw socket. The socket is referred
+to as "fallback socket" in the Kea code. All packets received through this socket
+are discarded.
+
+@section libdhcpPktFilter6 Switchable Packet Filters for DHCPv6
+
+The DHCPv6 implementation doesn't suffer from the problems described in \ref
+libdhcpPktFilter. Therefore, the socket creation and methods used to send
+and receive DHCPv6 messages are common for all OSes. However, there is
+still a need to customize the operations on the sockets to reliably unit test
+the \ref isc::dhcp::IfaceMgr logic.
+
+The \ref isc::dhcp::IfaceMgr::openSockets6 function examines configuration
+of detected interfaces for their availability to listen DHCPv6 traffic. For
+all running interfaces (except local loopback) it will try to open a socket
+and bind it to the link-local or global unicast address. The socket will
+not be opened on the interface which is down or for which it was explicitly
+specified that it should not be used to listen to DHCPv6 messages. There is
+a substantial amount of logic in this function that has to be unit tested for
+various interface configurations, e.g.:
+- multiple interfaces with link-local addresses only
+- multiple interfaces, some of them having global unicast addresses,
+- multiple interfaces, some of them disabled
+- no interfaces
+
+The \ref isc::dhcp::IfaceMgr::openSockets6 function attempts to open
+sockets on detected interfaces. At the same time, the number of interfaces,
+and their configuration is specific to OS where the tests are being run.
+So the test doesn't have any means to configure interfaces for the test case
+being run. Moreover, a unit test should not change the configuration of the
+system. For example, a change to the configuration of the interface which
+is used to access the machine running a test, may effectively break the
+access to this machine.
+
+In order to overcome the problem described above, the unit tests use
+fake interfaces which can be freely added, configured and removed from the
+\ref isc::dhcp::IfaceMgr. Obviously, it is not possible to open a socket
+on a fake interface, nor use it to send or receive IP packets. To mimic
+socket operations on fake interfaces it is required that the functions
+which open sockets, send messages and receive messages have to be
+customizable. This is achieved by implementation of replaceable packet
+filter objects which derive from the \ref isc::dhcp::PktFilter6 class.
+The default implementation of this class is \ref isc::dhcp::PktFilterInet6
+which creates a regular datagram IPv6/UDPv6 socket. The unit tests use a
+stub implementation isc::dhcp::test::PktFilter6Stub which contains no-op
+functions.
+
+Use \ref isc::dhcp::IfaceMgr::setPacketFilter function to set the custom packet
+filter object to be used by Interface Manager.
+
+@section libdhcpErrorLogging Logging non-fatal errors in IfaceMgr
+
+The libdhcp++ is a common library, meant to be used by various components,
+such as DHCP servers, relays and clients. It is also used by a perfdhcp
+benchmarking application. It provides a basic capabilities for these
+applications to perform operations on DHCP messages such as encoding
+or decoding them. It also provides capabilities to perform low level
+operations on sockets. Since libdhcp++ is a common library, its dependency
+on other BINDX modules should be minimal. In particular, errors occurring
+in the libdhcp++ are reported using exceptions, not a BINDX logger. This
+works well in most cases, but there are some cases in which it is
+undesired for a function to throw an exception in case of non-fatal error.
+
+The typical case, when exception should not be thrown, is when the \ref
+isc::dhcp::IfaceMgr::openSockets4 or \ref isc::dhcp::IfaceMgr::openSockets6
+fails to open a socket on one of the interfaces. This should not preclude
+the function from attempting to open sockets on other interfaces, which
+would be the case if exception was thrown.
+
+In such cases the IfaceMgr makes use of error handler callback function
+which may be installed by a caller. This function must implement the
+isc::dhcp::IfaceMgrErrorMsgCallback. Note that it is allowed to pass a NULL
+value instead, which would result falling back to a default behavior and
+exception will be thrown. If non-NULL value is provided, the
+\ref isc::dhcp::IfaceMgr will call error handler function and pass an
+error string as an argument. The handler function may use its logging
+mechanism to log this error message. In particular, the DHCP server
+will use BINDX logger to log the error message.
+
+@section libdhcpMTConsiderations Multi-Threading Consideration for DHCP library
+
+By default APIs provided by the DHCP library are not thread safe.
+For instance packets or options are not thread safe. Exception are:
+
+ - external sockets are thread safe (the container used to manage external
+ socket is thread safe so one can for instance delete an external socket
+ at any time).
+
+ - interface lookup cache is Kea thread safe (i.e. thread safe when the
+ multi-threading mode is true).
+
+ - interface send method is thread safe (mainly because it does not change
+ any internal state).
+
+ - packet queue ring is thread safe.
+
+*/