Commit 5cd3fa2a authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

Merge branch 'master' into trac2431_2

parents cecd1c59 d2cc8db8
528. [func] marcin
Implemented definitions for DHCPv4 option definitions identified
by option codes: 1 to 63, 77, 81-82, 90-92, 118-119, 124-125.
These definitions are now used by the DHCPv4 server to parse
options received from a client.
(Trac #2526, git 50a73567e8067fdbe4405b7ece5b08948ef87f98)
527. [bug] jelte
Fixed a bug in the synchronous UDP server code where unexpected
errors from ASIO or the system libraries could cause b10-auth to
stop. In asynchronous mode these errors would be ignored
completely. Both types have been updated to report the problem with
an ERROR log message, drop the packet, and continue service.
(Trac #2494, git db92f30af10e6688a7dc117b254cb821e54a6d95)
526. [bug] stephen
Miscellaneous fixes to DHCP code including rationalisation of
some methods in LeaseMgr and resolving some Doxygen/cppcheck
(Trac #2546, git 0140368ed066c722e5d11d7f9cf1c01462cf7e13)
525. [func] tomek
b10-dhcp4: DHCPv4 server is now able to parse configuration. It
is possible to specify IPv4 subnets with dynamic pools within
them. Although configuration is accepted, it is not used yet. This
will be implemented shortly.
(Trac #2270, git de29c07129d41c96ee0d5eebdd30a1ea7fb9ac8a)
524. [func] tomek
b10-dhcp6 is now able to handle RENEW messages. Leases are
renewed and REPLY responses are sent back to clients.
(Trac #2325, git 7f6c9d057cc0a7a10f41ce7da9c8565b9ee85246)
523. [bug] muks
Fixed a problem in inmem NSEC3 lookup (for, instance when using a
zone with no non-apex names) which caused exceptions when the zone
origin was not added as an explicit NSEC3 record.
(Trac #2503, git 6fe86386be0e7598633fe35999112c1a6e3b0370)
522. [func]* jelte
Configuration of TSIG keys for b10-xfrin has changed; instead of
specifying the full TSIG key (<name>:<base64>:<algo>) it now expects
This diff is collapsed.
......@@ -19,7 +19,7 @@
* @section dhcpv4Session BIND10 message queue integration
* DHCPv4 server component is now integrated with BIND10 message queue.
* DHCPv4 server component is now integrated with the BIND10 message queue.
* The integration is performed by establishSession() and disconnectSession()
* functions in isc::dhcp::ControlledDhcpv4Srv class. main() method deifined
* in the src/bin/dhcp4/ file instantiates isc::dhcp::ControlledDhcpv4Srv
......@@ -57,4 +57,4 @@
* that does not support msgq. That is useful for embedded environments.
* It may also be useful in validation.
\ No newline at end of file
......@@ -20,12 +20,14 @@
* - @subpage DataScrubbing
* @section DHCP
* - @subpage dhcpv4
* - @subpage dhcp4
* - @subpage dhcpv4Session
* - @subpage dhcpv6
* - @subpage dhcpv6-session
* - @subpage dhcpv6-config-parser
* - @subpage dhcpv6-config-inherit
* - @subpage dhcpv4ConfigParser
* - @subpage dhcpv4ConfigInherit
* - @subpage dhcp6
* - @subpage dhcpv6Session
* - @subpage dhcpv6ConfigParser
* - @subpage dhcpv6ConfigInherit
* - @subpage libdhcp
* - @subpage libdhcpIntro
* - @subpage libdhcpIfaceMgr
......@@ -33,7 +35,7 @@
* - @subpage leasemgr
* - @subpage cfgmgr
* - @subpage allocengine
* - @subpage dhcp-database-backends
* - @subpage dhcpDatabaseBackends
* - @subpage perfdhcpInternals
* @section misc Miscellaneous topics
......@@ -3404,16 +3404,94 @@ then change those defaults with config set Resolver/forward_addresses[0]/address
<section id="dhcp4-config">
<title>DHCPv4 Server Configuration</title>
The DHCPv4 server does not have a lease database implemented yet
nor any support for configuration, so the same set
of configuration options (including the same fixed address)
will be assigned every time.
Once the server is started, it can be configured. To view the
current configuration, use the following command in <command>bindctl</command>:
&gt; <userinput>config show Dhcp4</userinput></screen>
When starting Dhcp4 daemon for the first time, the default configuration
will be available. It will look similar to this:
&gt; <userinput>config show Dhcp4</userinput>
Dhcp4/interface/ list (default)
Dhcp4/renew-timer 1000 integer (default)
Dhcp4/rebind-timer 2000 integer (default)
Dhcp4/preferred-lifetime 3000 integer (default)
Dhcp4/valid-lifetime 4000 integer (default)
Dhcp4/subnet4 [] list (default)</screen>
To change one of the parameters, simply follow
the usual <command>bindctl</command> procedure. For example, to make the
leases longer, change their valid-lifetime parameter:
&gt; <userinput>config set Dhcp4/valid-lifetime 7200</userinput>
&gt; <userinput>config commit</userinput></screen>
Please note that most Dhcp4 parameters are of global scope
and apply to all defined subnets, unless they are overridden on a
per-subnet basis.
The essential role of DHCPv4 server is address assignment. The server
has to be configured with at least one subnet and one pool of dynamic
addresses to be managed. For example, assume that the server
is connected to a network segment that uses the
prefix. The Administrator of that network has decided that addresses from range to are going to be managed by the Dhcp4
server. Such a configuration can be achieved in the following way:
&gt; <userinput>config add Dhcp4/subnet4</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/subnet ""</userinput>
&gt; <userinput>config set Dhcp4/subnet4[0]/pool [ " -" ]</userinput>
&gt; <userinput>config commit</userinput></screen>
Note that subnet is defined as a simple string, but the pool parameter
is actually a list of pools: for this reason, the pool definition is
enclosed in square brackets, even though only one range of addresses
is specified.</para>
<para>It is possible to define more than one pool in a
subnet: continuing the previous example, further assume that should be also be managed by the server. It could be written as to Alternatively, it can be expressed more simply as Both formats are supported by Dhcp4 and can be mixed in the pool list.
For example, one could define the following pools:
&gt; <userinput>config set Dhcp4/subnet4[0]/pool [ "", "" ]</userinput>
&gt; <userinput>config commit</userinput></screen>
The number of pools is not limited, but for performance reasons it is recommended to
use as few as possible. Space and tabulations in pool definitions are ignored, so
spaces before and after hyphen are optional. They can be used to improve readability.
The server may be configured to serve more than one subnet. To add a second subnet,
use a command similar to the following:
&gt; <userinput>config add Dhcp4/subnet4</userinput>
&gt; <userinput>config set Dhcp4/subnet4[1]/subnet ""</userinput>
&gt; <userinput>config set Dhcp4/subnet4[1]/pool [ "" ]</userinput>
&gt; <userinput>config commit</userinput></screen>
Arrays are counted from 0. subnet[0] refers to the subnet defined in the
previous example. The <command>config add Dhcp4/subnet4</command> adds
another (second) subnet. It can be referred to as
<command>Dhcp4/subnet4[1]</command>. In this example, we allow server to
dynamically assign all addresses available in the whole subnet.
When configuring a DHCPv4 server using prefix/length notation, please pay
attention to the boundary values. When specifying that the server should use
a given pool, it will be able to allocate also first (typically network
address) and the last (typically broadcast address) address from that pool.
In the aforementioned example of pool, both and addresses may be assigned as well. This may be invalid in some
network configurations. If you want to avoid this, please use min-max notation.
At this stage of development, the only way to alter the server
configuration is to modify its source code. To do so, please
edit src/bin/dhcp4/ file and modify following
parameters and recompile:
Note: Although configuration is now accepted, it is not internally used
by they server yet. At this stage of development, the only way to alter
server configuration is to modify its source code. To do so, please edit
src/bin/dhcp6/ file, modify the following parameters and
const std::string HARDCODED_LEASE = ""; // assigned lease
const std::string HARDCODED_NETMASK = "";
......@@ -3423,7 +3501,7 @@ const std::string HARDCODED_DNS_SERVER = "";
const std::string HARDCODED_DOMAIN_NAME = "";
const std::string HARDCODED_SERVER_ID = "";</screen>
Lease database and configuration support is planned for 2012.
Lease database and configuration support is planned for end of 2012.
......@@ -55,11 +55,11 @@ 3600 IN NSEC b.* A NSEC RRSIG
;; ( (qname, NXDOMAIN)
;; ) (exist)
;; * (best possible wildcard, not exist)
) 3600 IN AAAA 2001:db8::53
\) 3600 IN AAAA 2001:db8::53
;; We'll also test the case where a single NSEC proves both NXDOMAIN and the
;; non existence of wildcard. The following records will be used for that
;; test.
......@@ -44,6 +44,7 @@ pkglibexec_PROGRAMS = b10-dhcp4
b10_dhcp4_SOURCES =
b10_dhcp4_SOURCES += ctrl_dhcp4_srv.h
b10_dhcp4_SOURCES += config_parser.h
b10_dhcp4_SOURCES += dhcp4_log.h
b10_dhcp4_SOURCES += dhcp4_srv.h
......@@ -57,6 +58,7 @@ b10_dhcp4_CXXFLAGS = -Wno-unused-parameter
b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/
b10_dhcp4_LDADD += $(top_builddir)/src/lib/dhcpsrv/
b10_dhcp4_LDADD += $(top_builddir)/src/lib/exceptions/
b10_dhcp4_LDADD += $(top_builddir)/src/lib/asiolink/
b10_dhcp4_LDADD += $(top_builddir)/src/lib/log/
This diff is collapsed.
// Copyright (C) 2012 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.
#include <exceptions/exceptions.h>
#include <cc/data.h>
#include <string>
/// @todo: This header file and its .cc counterpart are very similar between
/// DHCPv4 and DHCPv6. They should be merged. A ticket #2355.
namespace isc {
namespace dhcp {
class Dhcpv4Srv;
/// @brief a collection of elements that store uint32 values (e.g. renew-timer = 900)
typedef std::map<std::string, uint32_t> Uint32Storage;
/// @brief a collection of elements that store string values
typedef std::map<std::string, std::string> StringStorage;
/// An exception that is thrown if an error occurs while configuring an
/// \c Dhcpv4Srv object.
class Dhcp4ConfigError : public isc::Exception {
/// @brief constructor
/// @param file name of the file, where exception occurred
/// @param line line of the file, where exception occurred
/// @param what text description of the issue that caused exception
Dhcp4ConfigError(const char* file, size_t line, const char* what)
: isc::Exception(file, line, what) {}
/// @brief Base abstract class for all DHCPv4 parsers
/// Each instance of a class derived from this class parses one specific config
/// element. Sometimes elements are simple (e.g. a string) and sometimes quite
/// complex (e.g. a subnet). In such case, it is likely that a parser will
/// spawn child parsers to parse child elements in the configuration.
/// @todo: Merge this class with DhcpConfigParser in src/bin/dhcp6
class Dhcp4ConfigParser {
/// \name Constructors and Destructor
/// Note: The copy constructor and the assignment operator are
/// intentionally defined as private to make it explicit that this is a
/// pure base class.
// Private construtor and assignment operator assures that nobody
// will be able to copy or assign a parser. There are no defined
// bodies for them.
Dhcp4ConfigParser(const Dhcp4ConfigParser& source);
Dhcp4ConfigParser& operator=(const Dhcp4ConfigParser& source);
/// \brief The default constructor.
/// This is intentionally defined as \c protected as this base class should
/// never be instantiated (except as part of a derived class).
Dhcp4ConfigParser() {}
/// The destructor.
virtual ~Dhcp4ConfigParser() {}
/// \brief Prepare configuration value.
/// This method parses the "value part" of the configuration identifier
/// that corresponds to this derived class and prepares a new value to
/// apply to the server.
/// This method must validate the given value both in terms of syntax
/// and semantics of the configuration, so that the server will be
/// validly configured at the time of \c commit(). Note: the given
/// configuration value is normally syntactically validated, but the
/// \c build() implementation must also expect invalid input. If it
/// detects an error it may throw an exception of a derived class
/// of \c isc::Exception.
/// Preparing a configuration value will often require resource
/// allocation. If it fails, it may throw a corresponding standard
/// exception.
/// This method is not expected to be called more than once in the
/// life of the object. Although multiple calls are not prohibited
/// by the interface, the behavior is undefined.
/// \param config_value The configuration value for the identifier
/// corresponding to the derived class.
virtual void build(isc::data::ConstElementPtr config_value) = 0;
/// \brief Apply the prepared configuration value to the server.
/// This method is expected to be exception free, and, as a consequence,
/// it should normally not involve resource allocation.
/// Typically it would simply perform exception free assignment or swap
/// operation on the value prepared in \c build().
/// In some cases, however, it may be very difficult to meet this
/// condition in a realistic way, while the failure case should really
/// be very rare. In such a case it may throw, and, if the parser is
/// called via \c configureDhcp4Server(), the caller will convert the
/// exception as a fatal error.
/// This method is expected to be called after \c build(), and only once.
/// The result is undefined otherwise.
virtual void commit() = 0;
/// @brief a pointer to configuration parser
typedef boost::shared_ptr<Dhcp4ConfigParser> ParserPtr;
/// @brief a collection of parsers
/// This container is used to store pointer to parsers for a given scope.
typedef std::vector<ParserPtr> ParserCollection;
/// \brief Configure DHCPv4 server (\c Dhcpv4Srv) with a set of configuration values.
/// This function parses configuration information stored in \c config_set
/// and configures the \c server by applying the configuration to it.
/// It provides the strong exception guarantee as long as the underlying
/// derived class implementations of \c DhcpConfigParser meet the assumption,
/// that is, it ensures that either configuration is fully applied or the
/// state of the server is intact.
/// If a syntax or semantics level error happens during the configuration
/// (such as malformed configuration or invalid configuration parameter),
/// this function returns appropriate error code.
/// This function is called every time a new configuration is received. The extra
/// parameter is a reference to DHCPv4 server component. It is currently not used
/// and CfgMgr::instance() is accessed instead.
/// This method does not throw. It catches all exceptions and returns them as
/// reconfiguration statuses. It may return the following response codes:
/// 0 - configuration successful
/// 1 - malformed configuration (parsing failed)
/// 2 - logical error (parsing was successful, but the values are invalid)
/// @param config_set a new configuration (JSON) for DHCPv4 server
/// @return answer that contains result of reconfiguration
isc::data::ConstElementPtr config_set);
}; // end of isc::dhcp namespace
}; // end of isc namespace
......@@ -22,8 +22,11 @@
#include <dhcp4/ctrl_dhcp4_srv.h>
#include <dhcp4/dhcp4_log.h>
#include <dhcp4/spec_config.h>
#include <dhcp4/config_parser.h>
#include <exceptions/exceptions.h>
#include <util/buffer.h>
#include <cassert>
#include <iostream>
#include <cassert>
#include <iostream>
......@@ -46,8 +49,14 @@ ConstElementPtr
ControlledDhcpv4Srv::dhcp4ConfigHandler(ConstElementPtr new_config) {
ConstElementPtr answer = isc::config::createAnswer(0,
"Thank you for sending config.");
if (server_) {
return (configureDhcp4Server(*server_, new_config));
// That should never happen as we install config_handler after we instantiate
// the server.
ConstElementPtr answer = isc::config::createAnswer(1,
"Configuration rejected, server is during startup/shutdown phase.");
return (answer);
......@@ -100,10 +109,22 @@ void ControlledDhcpv4Srv::establishSession() {
cc_session_ = new Session(io_service_.get_io_service());
config_session_ = new ModuleCCSession(specfile, *cc_session_,
dhcp4CommandHandler, false);
// We initially create ModuleCCSession() without configHandler, as
// the session module is too eager to send partial configuration.
// We want to get the full configuration, so we explicitly call
// getFullConfig() and then pass it to our configHandler.
try {
configureDhcp4Server(*this, config_session_->getFullConfig());
} catch (const Dhcp4ConfigError& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(ex.what());
/// Integrate the asynchronous I/O model of BIND 10 configuration
/// control with the "select" model of the DHCP server. This is
/// fully explained in \ref dhcpv4Session.
......@@ -66,7 +66,9 @@ public:
/// @brief Session callback, processes received commands.
/// @param command_id text represenation of the command (e.g. "shutdown")
/// @param command Text represenation of the command (e.g. "shutdown")
/// @param args Optional parameters
/// @param command text represenation of the command (e.g. "shutdown")
/// @param args optional parameters
/// @return status of the command
@page dhcp4 DHCPv4 Server Component
BIND10 offers DHCPv4 server implementation. It is implemented as
b10-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 trasmit 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 dhcpv4Session BIND10 message queue integration
DHCPv4 server component is now integrated with BIND10 message queue.
The integration is performed by establishSession() and disconnectSession()
functions in isc::dhcp::ControlledDhcpv4Srv class. main() method deifined
in the src/bin/dhcp4/ file instantiates isc::dhcp::ControlledDhcpv4Srv
class that establishes connection with msgq and install necessary handlers
for receiving commands and configuration updates. It is derived from
a base isc::dhcp::Dhcpv4Srv class that implements DHCPv4 server functionality,
without any controlling mechanisms.
ControlledDhcpv4Srv instantiates several components to make management
session possible. In particular, isc::cc::Session cc_session
object uses ASIO for establishing connection. It registers its socket
in isc::asiolink::IOService io_service object. Typically, other components
(e.g. auth or resolver) that use ASIO for their communication, register their
other sockets in the
same io_service and then just call method that does
not return, until one of the callback decides that it is time to shut down
the whole component cal calls io_service.stop(). DHCPv4 works in a
different way. It does receive messages using select()
(see isc::dhcp::IfaceMgr::receive4()), which is incompatible with ASIO.
To solve this problem, socket descriptor is extracted from cc_session
object and is passed to IfaceMgr by using isc::dhcp::IfaceMgr::set_session_socket().
IfaceMgr then uses this socket in its select() call. If there is some
data to be read, it calls registered callback that is supposed to
read and process incoming data.
This somewhat complicated approach is needed for a simple reason. In
embedded deployments there will be no message queue. Not referring directly
to anything related to message queue in isc::dhcp::Dhcpv4Srv and
isc::dhcp::IfaceMgr classes brings in two benefits. First, the can
be used with and without message queue. Second benefit is related to the
first one: \ref libdhcp is supposed to be simple and robust and not require
many dependencies. One notable example of a use case that benefits from
this approach is a perfdhcp tool. Finally, the idea is that it should be
possible to instantiate Dhcpv4Srv object directly, thus getting a server
that does not support msgq. That is useful for embedded environments.
It may also be useful in validation.
@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.
......@@ -4,9 +4,85 @@
"module_description": "DHCPv4 server daemon",
"config_data": [
{ "item_name": "interface",
"item_type": "string",
"item_type": "list",
"item_optional": false,
"item_default": "eth0"
"item_default": [ "all" ],
"item_name": "interface_name",
"item_type": "string",
"item_optional": false,
"item_default": "all"
} ,
{ "item_name": "renew-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 1000
{ "item_name": "rebind-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 2000
{ "item_name": "valid-lifetime",
"item_type": "integer",
"item_optional": false,
"item_default": 4000
{ "item_name": "subnet4",
"item_type": "list",
"item_optional": false,
"item_default": [],
"item_name": "single-subnet4",
"item_type": "map",
"item_optional": false,
"item_default": {},
"map_item_spec": [
{ "item_name": "subnet",
"item_type": "string",
"item_optional": false,
"item_default": ""
{ "item_name": "renew-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 1000
{ "item_name": "rebind-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 2000
{ "item_name": "valid-lifetime",
"item_type": "integer",
"item_optional": false,
"item_default": 7200
{ "item_name": "pool",
"item_type": "list",
"item_optional": false,
"item_default": [],
"item_name": "type",
"item_type": "string",
"item_optional": false,
"item_default": ""
"commands": [
......@@ -26,10 +26,30 @@ to establish a session with the BIND 10 control channel.
A debug message listing the command (and possible arguments) received
from the BIND 10 control system by the IPv4 DHCP server.
% DHCP4_CONFIG_LOAD_FAIL failed to load configuration: %1
This critical error message indicates that the initial DHCPv4
configuration has failed. The server will start, but nothing will be
served until the configuration has been corrected.
% DHCP4_CONFIG_UPDATE updated configuration received: %1