Commit c8899cc4 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[3400] Initial JSON file read support added in b10-dhcp6

- added --with-kea-config=JSON,BIND10 added to configure.ac
- JSON-file config backend added for b10-dhcp6
- Config file can now be read from a JSON file
parent 2dbdfeb0
......@@ -565,6 +565,9 @@ AC_SUBST(PYCOVERAGE)
AC_SUBST(PYCOVERAGE_RUN)
AC_SUBST(USE_PYCOVERAGE)
enable_gtest="no"
GTEST_INCLUDES=
......@@ -1282,6 +1285,32 @@ AC_SUBST(PERL)
AC_PATH_PROGS(AWK, gawk awk)
AC_SUBST(AWK)
# Kea configuration backend section
# Currently there are 2 backends available: BIND10 and JSON
# It is possible that we may extend this to accept additional backends.
AC_ARG_WITH(kea-config,
AC_HELP_STRING([--with-kea-config],
[Selects configuration backend; currently available options are: BIND10 (default) or JSON]),
[CONFIG_BACKEND="$withval"],
[CONFIG_BACKEND=BIND10])
AM_CONDITIONAL(CONFIG_BACKEND_BIND10, test "x$CONFIG_BACKEND" = "xBIND10")
AM_CONDITIONAL(CONFIG_BACKEND_JSON, test "x$CONFIG_BACKEND" = "xJSON")
if test "x$CONFIG_BACKEND" = "xBIND10"; then
AC_DEFINE(CONFIG_BACKEND_BIND10, 1, [Define to 1 if Kea config was set to BIND10])
fi
if test "x$CONFIG_BACKEND" = "xJSON"; then
AC_DEFINE(CONFIG_BACKEND_JSON, 1, [Define to 1 if Kea config was set to JSON])
fi
# Let's sanity check if the specified backend value is allowed
if test "x$CONFIG_BACKEND" != "xBIND10" && test "x$CONFIG_BACKEND" != "xJSON"; then
AC_MSG_ERROR("Invalid configuration backend specified: $CONFIG_BACKEND. The only supported are: BIND10 JSON")
fi
AC_ARG_ENABLE(generate_docs, [AC_HELP_STRING([--enable-generate-docs],
[regenerate documentation using Docbook [default=no]])],
enable_generate_docs=$enableval, enable_generate_docs=no)
......@@ -1619,6 +1648,10 @@ SQLite:
SQLITE_VERSION: ${SQLITE_VERSION}
SQLITE_CFLAGS: ${SQLITE_CFLAGS}
SQLITE_LIBS: ${SQLITE_LIBS}
Kea config backend:
CONFIG_BACKEND: ${CONFIG_BACKEND}
END
# Avoid confusion on DNS/DHCP and only mention MySQL if it
......
......@@ -52,10 +52,17 @@ BUILT_SOURCES = spec_config.h dhcp6_messages.h dhcp6_messages.cc
pkglibexec_PROGRAMS = b10-dhcp6
b10_dhcp6_SOURCES = main.cc
b10_dhcp6_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
b10_dhcp6_SOURCES += config_parser.cc config_parser.h
b10_dhcp6_SOURCES += dhcp6_log.cc dhcp6_log.h
b10_dhcp6_SOURCES += dhcp6_srv.cc dhcp6_srv.h
b10_dhcp6_SOURCES += ctrl_dhcp6_srv.h
if CONFIG_BACKEND_BIND10
b10_dhcp6_SOURCES += json_config_parser.cc json_config_parser.h ctrl_bind10_dhcp6_srv.cc
endif
if CONFIG_BACKEND_JSON
b10_dhcp6_SOURCES += json_config_parser.cc json_config_parser.h ctrl_json_dhcp6_srv.cc
endif
nodist_b10_dhcp6_SOURCES = dhcp6_messages.h dhcp6_messages.cc
EXTRA_DIST += dhcp6_messages.mes
......
......@@ -21,7 +21,7 @@
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/dhcp_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/spec_config.h>
......@@ -186,7 +186,14 @@ void ControlledDhcpv6Srv::sessionReader(void) {
}
}
void ControlledDhcpv6Srv::establishSession() {
bool
ControlledDhcpv6Srv::init(const std::string& /* config_file*/) {
// This is BIND10 configuration backed. It established control session
// that is used to connect to BIND10 framework.
//
// Creates session that will be used to receive commands and updated
// configuration from cfgmgr (or indirectly from user via bindctl).
string specfile;
if (getenv("B10_FROM_BUILD")) {
......@@ -242,9 +249,11 @@ void ControlledDhcpv6Srv::establishSession() {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_CCSESSION_STARTED)
.arg(ctrl_socket);
IfaceMgr::instance().addExternalSocket(ctrl_socket, sessionReader);
return (true);
}
void ControlledDhcpv6Srv::disconnectSession() {
void ControlledDhcpv6Srv::cleanup() {
if (config_session_) {
delete config_session_;
config_session_ = NULL;
......@@ -273,7 +282,7 @@ void ControlledDhcpv6Srv::shutdown() {
}
ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
disconnectSession();
cleanup();
server_ = NULL; // forget this instance. There should be no callback anymore
// at this stage anyway.
......@@ -290,5 +299,12 @@ ControlledDhcpv6Srv::execDhcpv6ServerCommand(const std::string& command_id,
}
}
void
Daemon::loggerInit(const char* log_name, bool verbose, bool stand_alone) {
isc::log::initLogger(log_name,
(verbose ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone);
}
};
};
......@@ -46,11 +46,15 @@ public:
/// @brief Destructor.
~ControlledDhcpv6Srv();
/// @brief Establishes msgq session.
/// @brief Initializes the server.
///
/// Creates session that will be used to receive commands and updated
/// configuration from cfgmgr (or indirectly from user via bindctl).
void establishSession();
/// Depending on the configuration backend, it establishes msgq session,
/// reads the JSON file from disk or may perform any other setup
/// operation. For specific details, see actual implementation in
/// ctrl_*_dhcp6_srv.cc
///
/// @return true if initialization was successful, false if it failed
bool init(const std::string& config_file);
/// @brief Terminates existing msgq session.
///
......@@ -59,7 +63,7 @@ public:
/// may be received.
///
/// It is ok to call this method when session is disconnected already.
void disconnectSession();
void cleanup();
/// @brief Initiates shutdown procedure for the whole DHCPv6 server.
void shutdown();
......
// Copyright (C) 2012-2013 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.
#include <config.h>
#include <asiolink/asiolink.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/dhcp_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/spec_config.h>
#include <exceptions/exceptions.h>
#include <util/buffer.h>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using namespace isc::asiolink;
using namespace isc::cc;
using namespace isc::config;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::log;
using namespace isc::util;
using namespace std;
namespace isc {
namespace dhcp {
// Need to provide dummy reader. JSON-file backend does not use any control
// readers for now. Eventually, we may consider having a socket (named socket?)
// that other processes (like IPAM) could write to, triggering specific actions.
// For now, it's a no-op method.
void ControlledDhcpv6Srv::sessionReader(void) {
}
bool
ControlledDhcpv6Srv::init(const std::string& file_name) {
// This is a configuration backend implementation that reads the
// configuration from a JSON file.
isc::data::ConstElementPtr json;
isc::data::ConstElementPtr result;
// Basic sanity check: file name must not be empty.
if (file_name.empty()) {
isc_throw(BadValue, "JSON configuration file not specified");
}
try {
// Read contents of the file
string config = readFile(file_name);
// Try to parse it as JSON
json = Element::fromJSON(config);
// Use parsed JSON structures to configure the server
result = configureDhcp6Server(*this, json);
} catch (const std::exception& ex) {
LOG_ERROR(dhcp6_logger, DHCP6_CONFIG_LOAD_FAIL).arg(ex.what());
isc_throw(BadValue, "Unable to process JSON configuration file:"
+ file_name);
}
if (!result) {
// Undetermined status of the configuration. This should never happen,
// but as the configureDhcp6Server returns a pointer, it is theoretically
// possible that it will return NULL.
LOG_ERROR(dhcp6_logger, DHCP6_CONFIG_LOAD_FAIL)
.arg("Configuration failed: Undefined result of configureDhcp6Server"
"() function after attempting to read " + file_name);
return (false);
}
// Now check is the returned result is successful (rcode=0) or not
ConstElementPtr comment; /// see @ref isc::config::parseAnswer
int rcode;
comment = parseAnswer(rcode, result);
if (rcode != 0) {
string reason = "";
if (comment) {
reason = string(" (") + comment->stringValue() + string(")");
}
LOG_ERROR(dhcp6_logger, DHCP6_CONFIG_LOAD_FAIL).arg(reason);
return (false);
}
// Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration.
openActiveSockets(getPort());
// Server will start DDNS communications if its enabled.
this->startD2();
return (true);
}
void ControlledDhcpv6Srv::cleanup() {
// Nothing to do here. No need to disconnect from anything.
}
ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port)
: Dhcpv6Srv(port), cc_session_(NULL), config_session_(NULL) {
}
void ControlledDhcpv6Srv::shutdown() {
// Stop ASIO transmissions. Even though we didn't use it for
// configuration reading, there may be on-going transmissions
// with D2.
io_service_.stop();
Dhcpv6Srv::shutdown(); // Initiate DHCPv6 shutdown procedure.
}
ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
cleanup();
}
};
};
......@@ -499,10 +499,11 @@ to recover.
The IPv6 DHCP server has encountered a fatal error and is terminating.
The reason for the failure is included in the message.
% DHCP6_SESSION_FAIL failed to establish BIND 10 session (%1), running stand-alone
The server has failed to establish communication with the rest of BIND
10 and is running in stand-alone mode. (This behavior will change once
the IPv6 DHCP server is properly integrated with the rest of BIND 10.)
% DHCP6_INIT_FAIL failed to initialize Kea server: %1
The server has failed to establish communication with the rest of BIND 10,
failed to read JSON configuration file or excountered any other critical
issue that prevents it from starting up properly. Attached error message
provides more details about the issue.
% DHCP6_SHUTDOWN server shutdown
The IPv6 DHCP server has terminated normally.
......
......@@ -27,8 +27,7 @@
#include <dhcpsrv/d2_client_mgr.h>
#include <dhcpsrv/subnet.h>
#include <hooks/callout_handle.h>
#include <boost/noncopyable.hpp>
#include <dhcpsrv/daemon.h>
#include <iostream>
#include <queue>
......@@ -52,11 +51,7 @@ public:
/// that is going to be used as server-identifier, receives incoming
/// packets, processes them, manages leases assignment and generates
/// appropriate responses.
///
/// @note Only one instance of this class is instantiated as it encompasses
/// the whole operation of the server. Nothing, however, enforces the
/// singleton status of the object.
class Dhcpv6Srv : public boost::noncopyable {
class Dhcpv6Srv : public Daemon {
public:
/// @brief defines if certain option may, must or must not appear
......
......@@ -16,7 +16,7 @@
#include <cc/data.h>
#include <config/ccsession.h>
#include <dhcp/libdhcp++.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/cfgmgr.h>
......
......@@ -18,6 +18,7 @@
#include <dhcp6/dhcp6_log.h>
#include <log/logger_support.h>
#include <log/logger_manager.h>
#include <exceptions/exceptions.h>
#include <boost/lexical_cast.hpp>
......@@ -38,13 +39,16 @@ using namespace std;
namespace {
const char* const DHCP6_NAME = "b10-dhcp6";
const char* const DHCP6_LOGGER_NAME = "bind10";
void
usage() {
cerr << "Usage: " << DHCP6_NAME << " [-v] [-s] [-p number]" << endl;
cerr << "Usage: " << DHCP6_NAME << " [-v] [-s] [-p port_number] [-c cfgfile]" << endl;
cerr << " -v: verbose output" << endl;
cerr << " -s: stand-alone mode (don't connect to BIND10)" << endl;
cerr << " -p number: specify non-standard port number 1-65535 "
<< "(useful for testing only)" << endl;
cerr << " -c file: specify configuration file" << endl;
exit(EXIT_FAILURE);
}
} // end of anonymous namespace
......@@ -57,17 +61,20 @@ main(int argc, char* argv[]) {
bool stand_alone = false; // Should be connect to BIND10 msgq?
bool verbose_mode = false; // Should server be verbose?
while ((ch = getopt(argc, argv, "vsp:")) != -1) {
// The standard config file
std::string config_file("");
while ((ch = getopt(argc, argv, "vsp:c:")) != -1) {
switch (ch) {
case 'v':
verbose_mode = true;
break;
case 's':
case 's': // stand-alone
stand_alone = true;
break;
case 'p':
case 'p': // port number
try {
port_number = boost::lexical_cast<int>(optarg);
} catch (const boost::bad_lexical_cast &) {
......@@ -82,6 +89,10 @@ main(int argc, char* argv[]) {
}
break;
case 'c': // config file
config_file = optarg;
break;
default:
usage();
}
......@@ -92,39 +103,52 @@ main(int argc, char* argv[]) {
usage();
}
// Initialize logging. If verbose, we'll use maximum verbosity.
// If standalone is enabled, do not buffer initial log messages
isc::log::initLogger(DHCP6_NAME,
(verbose_mode ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone);
LOG_INFO(dhcp6_logger, DHCP6_STARTING);
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_START_INFO)
.arg(getpid()).arg(port_number).arg(verbose_mode ? "yes" : "no")
.arg(stand_alone ? "yes" : "no" );
int ret = EXIT_SUCCESS;
bool status = true;
try {
// Initialize logging. If verbose, we'll use maximum verbosity.
// If standalone is enabled, do not buffer initial log messages
Daemon::loggerInit(DHCP6_LOGGER_NAME, verbose_mode, stand_alone);
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_START_INFO)
.arg(getpid()).arg(port_number).arg(verbose_mode ? "yes" : "no")
.arg(stand_alone ? "yes" : "no" );
LOG_INFO(dhcp6_logger, DHCP6_STARTING);
ControlledDhcpv6Srv server(port_number);
if (!stand_alone) {
try {
server.establishSession();
// Initialize the server, i.e. establish control session
// if BIND10 backend is used or read a configuration file
//
status = server.init(config_file);
} catch (const std::exception& ex) {
LOG_ERROR(dhcp6_logger, DHCP6_SESSION_FAIL).arg(ex.what());
// Let's continue. It is useful to have the ability to run
// DHCP server in stand-alone mode, e.g. for testing
// We do need to make sure logging is no longer buffered
// since then it would not print until dhcp6 is stopped
LOG_ERROR(dhcp6_logger, DHCP6_INIT_FAIL).arg(ex.what());
// We should not continue if were told to configure (either read
// config file or establish BIND10 control session).
isc::log::LoggerManager log_manager;
log_manager.process();
cerr << "Failed to initialize server: " << ex.what() << endl;
return (EXIT_FAILURE);
}
} else {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_STANDALONE);
}
if (!status) {
isc_throw(isc::Unexpected, "Failed to initialize configuration backend.");
}
server.run();
LOG_INFO(dhcp6_logger, DHCP6_SHUTDOWN);
} catch (const std::exception& ex) {
LOG_FATAL(dhcp6_logger, DHCP6_SERVER_FAILED).arg(ex.what());
cerr << "Fatal error during start up: " << ex.what() << endl;
ret = EXIT_FAILURE;
}
......
......@@ -75,18 +75,26 @@ dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES += fqdn_unittest.cc
dhcp6_unittests_SOURCES += hooks_unittest.cc
dhcp6_unittests_SOURCES += dhcp6_test_utils.cc dhcp6_test_utils.h
dhcp6_unittests_SOURCES += ctrl_dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES += config_parser_unittest.cc
dhcp6_unittests_SOURCES += d2_unittest.cc d2_unittest.h
dhcp6_unittests_SOURCES += marker_file.cc
dhcp6_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../dhcp6_log.h ../dhcp6_log.cc
dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
dhcp6_unittests_SOURCES += wireshark.cc
dhcp6_unittests_SOURCES += dhcp6_client.cc dhcp6_client.h
dhcp6_unittests_SOURCES += rebind_unittest.cc
if CONFIG_BACKEND_BIND10
dhcp6_unittests_SOURCES += ../json_config_parser.cc ../json_config_parser.h ../ctrl_bind10_dhcp6_srv.cc
dhcp6_unittests_SOURCES += ctrl_dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES += config_parser_unittest.cc
endif
if CONFIG_BACKEND_JSON
dhcp6_unittests_SOURCES += ../json_config_parser.cc ../json_config_parser.h ../ctrl_json_dhcp6_srv.cc
dhcp6_unittests_SOURCES += config_parser_unittest.cc
endif
nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
nodist_dhcp6_unittests_SOURCES += marker_file.h test_libraries.h
......
......@@ -20,7 +20,7 @@
#include <dhcp/iface_mgr.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/dhcp6_srv.h>
#include <dhcpsrv/addr_utilities.h>
#include <dhcpsrv/cfgmgr.h>
......@@ -600,6 +600,11 @@ TEST_F(Dhcp6ParserTest, multipleSubnets) {
ElementPtr json = Element::fromJSON(config);
ofstream out("config.json");
out << config;
out.close();
do {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
ASSERT_TRUE(x);
......
......@@ -13,7 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcp/iface_mgr.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/tests/d2_unittest.h>
#include <dhcpsrv/cfgmgr.h>
......
......@@ -26,7 +26,7 @@
#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
#include <dhcp/iface_mgr.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp/dhcp6.h>
#include <dhcp/docsis3_option_defs.h>
#include <dhcp/tests/iface_mgr_test_config.h>
......@@ -197,12 +197,12 @@ TEST_F(Dhcpv6SrvTest, basic) {
ASSERT_NO_THROW( {
// Skip opening any sockets
srv.reset(new Dhcpv6Srv(0));
srv.reset(new NakedDhcpv6Srv(0));
});
srv.reset();
ASSERT_NO_THROW({
// open an unpriviledged port
srv.reset(new Dhcpv6Srv(DHCP6_SERVER_PORT + 10000));
srv.reset(new NakedDhcpv6Srv(DHCP6_SERVER_PORT + 10000));
});
}
......
......@@ -14,7 +14,7 @@
#include <gtest/gtest.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
using namespace isc::data;
using namespace isc::dhcp;
......
......@@ -17,7 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp/dhcp6.h>
#include <dhcp/duid.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp/dhcp6.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
......
......@@ -16,7 +16,7 @@
#include <asiolink/io_address.h>
#include <cc/data.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/tests/dhcp6_client.h>
......
......@@ -3,6 +3,7 @@ SUBDIRS = . tests
dhcp_data_dir = @localstatedir@/@PACKAGE@
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib -DDHCP_DATA_DIR="\"$(dhcp_data_dir)\""
AM_CPPFLAGS += -DTOP_BUILDDIR="\"$(top_builddir)\""
AM_CPPFLAGS += $(BOOST_INCLUDES)
if HAVE_MYSQL
AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
......@@ -48,6 +49,7 @@ libkea_dhcpsrv_la_SOURCES += csv_lease_file4.cc csv_lease_file4.h
libkea_dhcpsrv_la_SOURCES += csv_lease_file6.cc csv_lease_file6.h
libkea_dhcpsrv_la_SOURCES += d2_client_cfg.cc d2_client_cfg.h
libkea_dhcpsrv_la_SOURCES += d2_client_mgr.cc d2_client_mgr.h
libkea_dhcpsrv_la_SOURCES += daemon.cc daemon.h
libkea_dhcpsrv_la_SOURCES += dbaccess_parser.cc dbaccess_parser.h
libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES += cfgmgr.cc cfgmgr.h
......@@ -58,6 +60,7 @@ libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
libkea_dhcpsrv_la_SOURCES += lease_mgr_factory.cc lease_mgr_factory.h
libkea_dhcpsrv_la_SOURCES += memfile_lease_mgr.cc memfile_lease_mgr.h
if HAVE_MYSQL
libkea_dhcpsrv_la_SOURCES += mysql_lease_mgr.cc mysql_lease_mgr.h
endif
......
// Copyright (C) 2014 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.
#include <config.h>
#include <log/logger_level.h>
#include <log/logger_name.h>
#include <log/logger_manager.h>
#include <log/logger_specification.h>
#include <log/logger_support.h>
#include <log/output_option.h>
#include <dhcpsrv/daemon.h>
#include <exceptions/exceptions.h>
#include <fstream>
#include <errno.h>
/// @brief provides default implementation for basic daemon operations
///
/// This file provides stub implementations that are expected to be redefined
/// in derived classes (e.g. ControlledDhcpv6Srv)
namespace isc {
namespace dhcp {
Daemon::Daemon() {
}
bool Daemon::init(const std::string&) {
return false;
}
void Daemon::