// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

/**
 @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.

@section dhcpv4ConfigParser Configuration Parser in DHCPv4

This parser follows exactly the same logic as its DHCPv6 counterpart.
See \ref dhcpv6ConfigParser.

@section dhcpv4ConfigInherit DHCPv4 configuration inheritance

Configuration inheritance in DHCPv4 follows exactly the same logic as its DHCPv6
counterpart. See \ref dhcpv6ConfigInherit.

@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.

@section dhcpv4DDNSIntegration DHCPv4 Server Support for the Dynamic DNS Updates
T
he DHCPv4 server supports processing of the DHCPv4 Client FQDN option (RFC4702)
and the DHCPv4 Host Name option (RFC2132). Client may send one of these options
to convey its fully qualified or partial name to the server. The server may use
this name to perform DNS updates for the client. If server receives both options
in the same message, the DHCPv4 Client FQDN %Option is processed and the Host
Name option is ignored. If only Host Name Option is present in the client's
message, it is used to update DNS.

Server may be configured to use a different name to perform DNS update for the
client. In this case the server will return one of the DHCPv4 Client FQDN or
Host Name %Option in its response with the name which was selected for the
client to indicate that this name will be used to perform DNS update.

The kea-dhcp-ddns process is responsible for the actual communication with the
DNS, i.e. to send DNS update messages. The kea-dhcp4 module is responsible for
generating @ref isc::dhcp_ddns::NameChangeRequest and sending it to
the kea-dhcp-ddns module. The @ref isc::dhcp_ddns::NameChangeRequest object
represents changes to the DNS bindings, related to acquisition, renewal or
release of the DHCP lease. The kea-dhcp4 module implements the simple FIFO queue
of the NameChangeRequest objects. The module logic, which processes the incoming
DHCPv4 Client FQDN and Host Name Options puts these requests into the FIFO queue.

@todo Currently the FIFO queue is not processed after the NameChangeRequests are
generated and added to it. In the future implementation steps it is planned to
create a code which will check if there are any outstanding requests in the queue
and send them to the kea-dhcp-ddns module when server is idle waiting for DHCP
messages.

When client gets an address from the server, a DHCPv4 server may generate 0, 1
or 2 NameChangeRequests during single message processing. Server generates no
NameChangeRequests if it is not configured to update DNS or it rejects the DNS
update for any other reason.

Server may generate 1 NameChangeRequest in a case when client acquired a new
lease or it releases an existing lease. In the former case, the NameChangeRequest
type is CHG_ADD, which indicates that the kea-dhcp-ddns module should add a new
DNS binding for the client, and it is assumed that there is no DNS binding for
this client already. In the latter case, the NameChangeRequest type is CHG_REMOVE
to indicate to the kea-dhcp-ddns module that an existing DNS binding should be
removed from the DNS. The binding consists of the forward and reverse mapping.
The server may only remove the mapping which it had added. Therefore, the lease
database holds the information which updates (no update, reverse only update,
forward only update or both reverse and forward update) have been performed when
the lease was acquired or renewed. Server checks this information to make a
decision which mapping it is supposed to remove when lease is released.

Server may generate 2 NameChangeRequests in case a client is renewing a lease and
it already has a DNS binding for that lease. The DHCPv4 server will check if
there is an existing lease for the client which has sent a message and if DNS
Updates had been performed for this lease. If the notion of client's FQDN changes,
comparing to the information stored in the lease database, the DHCPv4 has to
remove an existing binding from the DNS and then add a new binding according to
the new FQDN information received from the client. If the client's FQDN
information (including the client's name and type of update performed) doesn't
change comparing to the NameChangeRequest is not generated.

The DHCPv4 Client FQDN %Option comprises flags which communicate to the server
what updates (if any) client expects the server to perform. Server may be
configured to obey client's preference or to do FQDN processing in a different way.
If the server overrides client's preference it will communicate it by sending
the DHCPv4 Client FQDN %Option in its responses to a client, with the appropriate
flags set.

@todo Note, that current implementation doesn't allow configuration of the
server's behaviour with respect to DNS Updates. This is planned for the future.
The default behaviour is constituted by the set of constants defined in the
(upper part of) dhcp4_srv.cc file. Once the configuration is implemented,
these constants will be removed.

@section dhcpv4Classifier DHCPv4 Client Classification

Kea DHCPv4 server currently supports simplified client classification. It is called
"simplified", because the incoming packets are classified based on the content
of the vendor class (60) option. More flexible classification is planned, but there
are no specific development dates agreed.

For each incoming packet, @ref isc::dhcp::Dhcpv4Srv::classifyPacket() method is called.
It attempts to extract content of the vendor class option and interpret as a name
of the class. For now, the code has been tested with two classes used in cable modem
networks: eRouter1.0 and docsis3.0, but any other content of the vendor class option will
be interpreted as a class name.

In principle any given packet can belong to zero or more classes. As the current
classifier is very modest, there's only one way to assign a class (based on vendor class
option), the ability to assign more than one class to a packet is not yet exercised.
Nevertheless, there is such a possibility and it will be used in a near future. To
check whether a packet belongs to given class, isc::dhcp::Pkt4::inClass method should
be used.

Currently there is a short code section that alternates packet processing depending on
which class it belongs to. It is planned to move that capability to an external hook
library. See ticket #3275. The class specific behavior is:

- docsis3.0 packets have siaddr (next server) field set
- docsis3.0 packets have file field set to the content of the boot-file-name option
- eRouter1.0 packets have siaddr (next server) field cleared

Aforementioned modifications are conducted in @ref isc::dhcp::Dhcpv4Srv::classSpecificProcessing.

It is possible to define class restrictions in subnet, so a given subnet is only
accessible to clients that belong to a given class. That is implemented as isc::dhcp::Pkt4::classes_
being passed in isc::dhcp::Dhcpv4Srv::selectSubnet() to isc::dhcp::CfgMgr::getSubnet4().
Currently this capability is usable, but the number of scenarios it supports is
limited.

 @section dhcpv4ConfigBackend Configuration backend for DHCPv4

There are many theoretical ways in which server configuration can be stored.
The legacy ISC-DHCP implementation uses flat files. Configuration stored in JSON files is
becoming more and more popular among various projects. There are unofficial patches for
ISC-DHCP that keep parts of the configuration in LDAP. It was also suggested that in some
cases it would be convenient to keep configuration in XML files.

Kea 0.9 has introduced configuration backends that are switchable during compilation phase. Currently the only choice is JSON.

JSON is a new configuration backend that causes Kea to read JSON configuration file from
disk. It does not require any framework and thus is considered more lightweight. It will
allow dynamic on-line reconfiguration, but will lack remote capabilities (i.e. no RESTful
API). This configuration backend is expected to be the default for upcoming Kea 0.9. It
requires <tt> -c config-file </tt> command-line option.

Internally, configuration backends are implemented as different implementations of the
isc::dhcp::ControlledDhcpv4Srv class, stored in kea_controller.cc files.

While it is unlikely that ISC will support more than one backend at any given time, there
are several aspects that make that approach appealing in the long term. First, having
two backends is essential during transition time, where both old and new backend is used.
Second, there are external organizations that develop and presumably maintain LDAP backend
for ISC-DHCP. Is at least possible that similar will happen for Kea. Finally, if we ever
extend the isc::dhcp::CfgMgr with configuration export, this approach could be used as
a migration tool.

@section dhcpv4SignalBasedReconfiguration Reconfiguring DHCPv4 server with SIGHUP signal

Online reconfiguration (reconfiguration without a need to restart the server) is an
important feature which is supported by all modern DHCP servers. When using the JSON
configuration backend, a configuration file name is specified with a command line
option of the DHCP server binary. The configuration file is used to configure the
server at startup. If the initial configuration fails, the server will fail to start.
If the server starts and configures successfully it will use the initial configuration
until it is reconfigured.

The reconfiguration request can be triggered externally (from other process) by editing
a configuration file and sending a SIGHUP signal to DHCP server process. After receiving
the SIGHUP signal, the server will re-read the configuration file specified at startup.
If the reconfiguration fails, the server will continue to run and use the last good
configuration.

The signal handler for SIGHUP (also for SIGTERM and SIGINT) are installed in the
kea_controller.cc using the @c isc::util::SignalSet class. The
@c isc::dhcp::Dhcp6Srv calls @c isc::dhcp::Daemon::handleSignal on each pass
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.

@section dhcpv4Other Other DHCPv4 topics

 For hooks API support in DHCPv4, see @ref dhcpv4Hooks.

*/
