Commit 4546dd18 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[master] Merge branch 'trac3329'

b10-dhcp4 now fully able to generate and send DHCP-DDNS requests
parents 5ba01762 c0343b41
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-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
......@@ -114,6 +114,16 @@ ControlledDhcpv4Srv::dhcp4ConfigHandler(ConstElementPtr new_config) {
return (answer);
}
// Server will start DDNS communications if its enabled.
try {
server_->startD2();
} catch (const std::exception& ex) {
std::ostringstream err;
err << "error starting DHCP_DDNS client "
" after server reconfiguration: " << ex.what();
return (isc::config::createAnswer(1, err.str()));
}
// Configuration may change active interfaces. Therefore, we have to reopen
// sockets according to new configuration. This operation is not exception
// safe and we really don't want to emit exceptions to the callback caller.
......@@ -211,11 +221,15 @@ void ControlledDhcpv4Srv::establishSession() {
try {
configureDhcp4Server(*this, config_session_->getFullConfig());
// Server will start DDNS communications if its enabled.
server_->startD2();
// Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration.
openActiveSockets(getPort(), useBroadcast());
} catch (const DhcpConfigError& ex) {
} catch (const std::exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(ex.what());
}
......
......@@ -20,11 +20,11 @@ to receive DHCPv4 traffic. IPv4 socket on this interface will be opened once
Interface Manager starts up procedure of opening sockets.
% DHCP4_CCSESSION_STARTED control channel session started on socket %1
A debug message issued during startup after the IPv4 DHCP server has
A debug message issued during startup after the DHCPv4 server has
successfully established a session with the BIND 10 control channel.
% DHCP4_CCSESSION_STARTING starting control channel session, specfile: %1
This debug message is issued just before the IPv4 DHCP server attempts
This debug message is issued just before the DHCPv4 server attempts
to establish a session with the BIND 10 control channel.
% DHCP4_CLIENT_NAME_PROC_FAIL failed to process the fqdn or hostname sent by a client: %1
......@@ -42,7 +42,7 @@ class or classes. This is a norma
% DHCP4_COMMAND_RECEIVED received command %1, arguments: %2
A debug message listing the command (and possible arguments) received
from the BIND 10 control system by the IPv4 DHCP server.
from the BIND 10 control system by the DHCPv4 server.
% DHCP4_CONFIG_COMPLETE DHCPv4 server has completed configuration: %1
This is an informational message announcing the successful processing of a
......@@ -70,7 +70,7 @@ configuration. That happens at start up and also when a server configuration
change is committed by the administrator.
% DHCP4_CONFIG_UPDATE updated configuration received: %1
A debug message indicating that the IPv4 DHCP server has received an
A debug message indicating that the DHCPv4 server has received an
updated configuration from the BIND 10 configuration system.
% DHCP4_DB_BACKEND_STARTED lease database started (type: %1, name: %2)
......@@ -194,12 +194,12 @@ which this message has been received. The IPv4 address assigned on this
interface must belong to one of the configured subnets. Otherwise
received message is dropped.
% DHCP4_NOT_RUNNING IPv4 DHCP server is not running
% DHCP4_NOT_RUNNING DHCPv4 server is not running
A warning message is issued when an attempt is made to shut down the
IPv4 DHCP server but it is not running.
DHCPv4 server but it is not running.
% DHCP4_OPEN_SOCKET opening sockets on port %1
A debug message issued during startup, this indicates that the IPv4 DHCP
A debug message issued during startup, this indicates that the DHCPv4
server is about to open sockets on the specified port.
% DHCP4_PACKET_NOT_FOR_US received DHCPv4 message (transid=%1, iface=%2) dropped because it contains foreign server identifier
......@@ -214,7 +214,7 @@ A warning message issued when IfaceMgr fails to open and bind a socket. The reas
for the failure is appended as an argument of the log message.
% DHCP4_PACKET_PARSE_FAIL failed to parse incoming packet: %1
The IPv4 DHCP server has received a packet that it is unable to
The DHCPv4 server has received a packet that it is unable to
interpret. The reason why the packet is invalid is included in the message.
% DHCP4_PACKET_PROCESS_FAIL failed to process packet received from %1: %2
......@@ -233,35 +233,35 @@ may well be a valid DHCP packet, just a type not expected by the server
(e.g. it will report a received OFFER packet as UNKNOWN).
% DHCP4_PACKET_RECEIVE_FAIL error on attempt to receive packet: %1
The IPv4 DHCP server tried to receive a packet but an error
The DHCPv4 server tried to receive a packet but an error
occurred during this attempt. The reason for the error is included in
the message.
% DHCP4_PACKET_SEND_FAIL failed to send DHCPv4 packet: %1
This error is output if the IPv4 DHCP server fails to send an assembled
This error is output if the DHCPv4 server fails to send an assembled
DHCP message to a client. The reason for the error is included in the
message.
% DHCP4_PARSER_COMMIT_EXCEPTION parser failed to commit changes
On receipt of message containing details to a change of the IPv4 DHCP
On receipt of message containing details to a change of the DHCPv4
server configuration, a set of parsers were successfully created, but one
of them failed to commit its changes due to a low-level system exception
being raised. Additional messages may be output indicating the reason.
% DHCP4_PARSER_COMMIT_FAIL parser failed to commit changes: %1
On receipt of message containing details to a change of the IPv4 DHCP
On receipt of message containing details to a change of the DHCPv4
server configuration, a set of parsers were successfully created, but
one of them failed to commit its changes. The reason for the failure
is given in the message.
% DHCP4_PARSER_CREATED created parser for configuration element %1
A debug message output during a configuration update of the IPv4 DHCP
A debug message output during a configuration update of the DHCPv4
server, notifying that the parser for the specified configuration element
has been successfully created.
% DHCP4_PARSER_EXCEPTION failed to create or run parser for configuration element %1
On receipt of message containing details to a change of its configuration,
the IPv4 DHCP server failed to create a parser to decode the contents of
the DHCPv4 server failed to create a parser to decode the contents of
the named configuration element, or the creation succeeded but the parsing
actions and committal of changes failed. The message has been output in
response to a non-BIND 10 exception being raised. Additional messages
......@@ -269,7 +269,7 @@ may give further information.
% DHCP4_PARSER_FAIL failed to create or run parser for configuration element %1: %2
On receipt of message containing details to a change of its configuration,
the IPv4 DHCP server failed to create a parser to decode the contents
the DHCPv4 server failed to create a parser to decode the contents
of the named configuration element, or the creation succeeded but the
parsing actions and committal of changes failed. The reason for the
failure is given in the message.
......@@ -324,40 +324,40 @@ both clones use the same client-id.
A debug message listing the data returned to the client.
% DHCP4_SERVER_FAILED server failed: %1
The IPv4 DHCP server has encountered a fatal error and is terminating.
The DHCPv4 server has encountered a fatal error and is terminating.
The reason for the failure is included in the message.
% DHCP4_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 IPv4 DHCP server is properly integrated with the rest of BIND 10.)
the DHCPv4 server is properly integrated with the rest of BIND 10.)
% DHCP4_SHUTDOWN server shutdown
The IPv4 DHCP server has terminated normally.
The DHCPv4 server has terminated normally.
% DHCP4_SHUTDOWN_REQUEST shutdown of server requested
This debug message indicates that a shutdown of the IPv4 server has
This debug message indicates that a shutdown of the DHCPv4 server has
been requested via a call to the 'shutdown' method of the core Dhcpv4Srv
object.
% DHCP4_SRV_CONSTRUCT_ERROR error creating Dhcpv4Srv object, reason: %1
This error message indicates that during startup, the construction of a
core component within the IPv4 DHCP server (the Dhcpv4 server object)
core component within the DHCPv4 server (the Dhcpv4 server object)
has failed. As a result, the server will exit. The reason for the
failure is given within the message.
% DHCP4_STANDALONE skipping message queue, running standalone
This is a debug message indicating that the IPv4 server is running in
This is a debug message indicating that the DHCPv4 server is running in
standalone mode, not connected to the message queue. Standalone mode
is only useful during program development, and should not be used in a
production environment.
% DHCP4_STARTING server starting
This informational message indicates that the IPv4 DHCP server has
This informational message indicates that the DHCPv4 server has
processed any command-line switches and is starting.
% DHCP4_START_INFO pid: %1, port: %2, verbose: %3, standalone: %4
This is a debug message issued during the IPv4 DHCP server startup.
This is a debug message issued during the DHCPv4 server startup.
It lists some information about the parameters with which the server
is running.
......@@ -370,3 +370,8 @@ steps in the processing of incoming client message.
This warning message is output when a packet was received from a subnet
for which the DHCPv4 server has not been configured. The most probable
cause is a misconfiguration of the server.
% DHCP4_DDNS_REQUEST_SEND_FAILED failed sending a request to b10-dhcp-ddns, error: %1, ncr: %2
This error message indicates that DHCP4 server attempted to send a DDNS
update reqeust to the DHCP-DDNS server. This is most likely a configuration or
networking error.
......@@ -420,9 +420,6 @@ Dhcpv4Srv::run() {
LOG_ERROR(dhcp4_logger, DHCP4_PACKET_SEND_FAIL)
.arg(e.what());
}
// Send NameChangeRequests to the b10-dhcp_ddns module.
sendNameChangeRequests();
}
return (true);
......@@ -881,26 +878,23 @@ queueNameChangeRequest(const isc::dhcp_ddns::NameChangeType chg_type,
.arg(ex.what());
return;
}
// Create NameChangeRequest
NameChangeRequest ncr(chg_type, lease->fqdn_fwd_, lease->fqdn_rev_,
lease->hostname_, lease->addr_.toText(),
dhcid, lease->cltt_ + lease->valid_lft_,
lease->valid_lft_);
// And queue it.
NameChangeRequestPtr ncr(new NameChangeRequest(chg_type, lease->fqdn_fwd_,
lease->fqdn_rev_,
lease->hostname_,
lease->addr_.toText(),
dhcid,
(lease->cltt_ +
lease->valid_lft_),
lease->valid_lft_));
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL_DATA, DHCP4_QUEUE_NCR)
.arg(chg_type == CHG_ADD ? "add" : "remove")
.arg(ncr.toText());
name_change_reqs_.push(ncr);
}
.arg(ncr->toText());
void
Dhcpv4Srv::sendNameChangeRequests() {
while (!name_change_reqs_.empty()) {
/// @todo Once next NameChangeRequest is picked from the queue
/// we should send it to the b10-dhcp_ddns module. Currently we
/// just drop it.
name_change_reqs_.pop();
}
// And pass it to the the manager.
CfgMgr::instance().getD2ClientMgr().sendRequest(ncr);
}
void
......@@ -1869,5 +1863,29 @@ bool Dhcpv4Srv::classSpecificProcessing(const Pkt4Ptr& query, const Pkt4Ptr& rsp
return (true);
}
void
Dhcpv4Srv::startD2() {
D2ClientMgr& d2_mgr = CfgMgr::instance().getD2ClientMgr();
if (d2_mgr.ddnsEnabled()) {
// Updates are enabled, so lets start the sender, passing in
// our error handler.
// This may throw so wherever this is called needs to ready.
d2_mgr.startSender(boost::bind(&Dhcpv4Srv::d2ClientErrorHandler,
this, _1, _2));
}
}
void
Dhcpv4Srv::d2ClientErrorHandler(const
dhcp_ddns::NameChangeSender::Result result,
dhcp_ddns::NameChangeRequestPtr& ncr) {
LOG_ERROR(dhcp4_logger, DHCP4_DDNS_REQUEST_SEND_FAILED).
arg(result).arg((ncr ? ncr->toText() : " NULL "));
// We cannot communicate with b10-dhcp-ddns, suspend futher updates.
/// @todo We may wish to revisit this, but for now we will simpy turn
/// them off.
CfgMgr::instance().getD2ClientMgr().suspendUpdates();
}
} // namespace dhcp
} // namespace isc
......@@ -21,6 +21,7 @@
#include <dhcp/option4_client_fqdn.h>
#include <dhcp/option_custom.h>
#include <dhcp_ddns/ncr_msg.h>
#include <dhcpsrv/d2_client_mgr.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/alloc_engine.h>
#include <hooks/callout_handle.h>
......@@ -165,6 +166,30 @@ public:
/// @param use_bcast should broadcast flags be set on the sockets.
static void openActiveSockets(const uint16_t port, const bool use_bcast);
/// @brief Starts DHCP_DDNS client IO if DDNS updates are enabled.
///
/// If updates are enabled, it Instructs the D2ClientMgr singleton to
/// enter send mode. If D2ClientMgr encounters errors it may throw
/// D2ClientErrors. This method does not catch exceptions.
void startD2();
/// @brief Implements the error handler for DHCP_DDNS IO errors
///
/// Invoked when a NameChangeRequest send to b10-dhcp-ddns completes with
/// a failed status. These are communications errors, not data related
/// failures.
///
/// This method logs the failure and then suspends all further updates.
/// Updating can only be restored by reconfiguration or restarting the
/// server. There is currently no retry logic so the first IO error that
/// occurs will suspend updates.
/// @todo We may wish to make this more robust or sophisticated.
///
/// @param result Result code of the send operation.
/// @param ncr NameChangeRequest which failed to send.
virtual void d2ClientErrorHandler(const dhcp_ddns::
NameChangeSender::Result result,
dhcp_ddns::NameChangeRequestPtr& ncr);
protected:
/// @name Functions filtering and sanity-checking received messages.
......@@ -455,10 +480,10 @@ protected:
/// @brief Creates the NameChangeRequest and adds to the queue for
/// processing.
///
/// This function adds the @c isc::dhcp_ddns::NameChangeRequest to the
/// queue and emits the debug message which indicates whether the request
/// being added is to remove DNS entry or add a new entry. This function
/// is exception free.
/// This creates the @c isc::dhcp_ddns::NameChangeRequest; emits a
/// the debug message which indicates whether the request being added is
/// to remove DNS entry or add a new entry; and then sends the request
/// to the D2ClientMgr for transmission to b10-dhcp-ddns.
///
/// @param chg_type A type of the NameChangeRequest (ADD or REMOVE).
/// @param lease A lease for which the NameChangeRequest is created and
......@@ -466,17 +491,6 @@ protected:
void queueNameChangeRequest(const isc::dhcp_ddns::NameChangeType chg_type,
const Lease4Ptr& lease);
/// @brief Sends all outstanding NameChangeRequests to b10-dhcp-ddns module.
///
/// The purpose of this function is to pick all outstanding
/// NameChangeRequests from the FIFO queue and send them to b10-dhcp-ddns
/// module.
///
/// @todo Currently this function simply removes all requests from the
/// queue but doesn't send them anywhere. In the future, the
/// NameChangeSender will be used to deliver requests to the other module.
void sendNameChangeRequests();
/// @brief Attempts to renew received addresses
///
/// Attempts to renew existing lease. This typically includes finding a lease that
......@@ -686,12 +700,6 @@ private:
int hook_index_pkt4_receive_;
int hook_index_subnet4_select_;
int hook_index_pkt4_send_;
protected:
/// Holds a list of @c isc::dhcp_ddns::NameChangeRequest objects which
/// are waiting for sending to b10-dhcp-ddns module.
std::queue<isc::dhcp_ddns::NameChangeRequest> name_change_reqs_;
};
}; // namespace isc::dhcp
......
......@@ -76,6 +76,7 @@ TESTS += dhcp4_unittests
dhcp4_unittests_SOURCES = ../dhcp4_srv.h ../dhcp4_srv.cc ../ctrl_dhcp4_srv.cc
dhcp4_unittests_SOURCES += ../dhcp4_log.h ../dhcp4_log.cc
dhcp4_unittests_SOURCES += ../config_parser.cc ../config_parser.h
dhcp4_unittests_SOURCES += d2_unittest.h d2_unittest.cc
dhcp4_unittests_SOURCES += dhcp4_test_utils.h
dhcp4_unittests_SOURCES += dhcp4_unittests.cc
dhcp4_unittests_SOURCES += dhcp4_srv_unittest.cc
......
// 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 <dhcp/iface_mgr.h>
#include <dhcp4/config_parser.h>
#include <dhcp4/tests/d2_unittest.h>
#include <dhcpsrv/cfgmgr.h>
#include <gtest/gtest.h>
#include <string>
using namespace isc;
using namespace isc::asiolink;
using namespace isc::data;
namespace isc {
namespace dhcp {
namespace test {
void
D2Dhcpv4Srv::d2ClientErrorHandler(const
dhcp_ddns::NameChangeSender::Result result,
dhcp_ddns::NameChangeRequestPtr& ncr) {
++error_count_;
// call base class error handler
Dhcpv4Srv::d2ClientErrorHandler(result, ncr);
}
const bool Dhcp4SrvD2Test::SHOULD_PASS;
const bool Dhcp4SrvD2Test::SHOULD_FAIL;
Dhcp4SrvD2Test::Dhcp4SrvD2Test() {
}
Dhcp4SrvD2Test::~Dhcp4SrvD2Test() {
reset();
}
dhcp_ddns::NameChangeRequestPtr
Dhcp4SrvD2Test::buildTestNcr(uint32_t dhcid_id_num) {
// Build an NCR from json string.
std::ostringstream stream;
stream <<
"{"
" \"change_type\" : 0 , "
" \"forward_change\" : true , "
" \"reverse_change\" : false , "
" \"fqdn\" : \"myhost.example.com.\" , "
" \"ip_address\" : \"192.168.2.1\" , "
" \"dhcid\" : \""
<< std::hex << std::setfill('0') << std::setw(16)
<< dhcid_id_num << "\" , "
" \"lease_expires_on\" : \"20140121132405\" , "
" \"lease_length\" : 1300 "
"}";
return (dhcp_ddns::NameChangeRequest::fromJSON(stream.str()));
}
void
Dhcp4SrvD2Test::reset() {
std::string config = "{ \"interfaces\": [ \"*\" ],"
"\"hooks-libraries\": [ ], "
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"valid-lifetime\": 4000, "
"\"subnet4\": [ ], "
"\"dhcp-ddns\": { \"enable-updates\" : false }, "
"\"option-def\": [ ], "
"\"option-data\": [ ] }";
configure(config, SHOULD_PASS);
}
void
Dhcp4SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
const std::string& ip_address,
const uint32_t port) {
std::ostringstream config;
config <<
"{ \"interfaces\": [ \"*\" ],"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ],"
" \"subnet\": \"192.0.2.0/24\" } ],"
" \"dhcp-ddns\" : {"
" \"enable-updates\" : " << (enable_d2 ? "true" : "false") << ", "
" \"server-ip\" : \"" << ip_address << "\", "
" \"server-port\" : " << port << ", "
" \"ncr-protocol\" : \"UDP\", "
" \"ncr-format\" : \"JSON\", "
" \"always-include-fqdn\" : true, "
" \"allow-client-update\" : true, "
" \"override-no-update\" : true, "
" \"override-client-update\" : true, "
" \"replace-client-name\" : true, "
" \"generated-prefix\" : \"test.prefix\", "
" \"qualifying-suffix\" : \"test.suffix.\" },"
"\"valid-lifetime\": 4000 }";
configure(config.str(), exp_result);
}
void
Dhcp4SrvD2Test::configure(const std::string& config, bool exp_result) {
ElementPtr json = Element::fromJSON(config);
ConstElementPtr status;
// Configure the server and make sure the config is accepted
EXPECT_NO_THROW(status = configureDhcp4Server(srv_, json));
ASSERT_TRUE(status);
int rcode;
ConstElementPtr comment = config::parseAnswer(rcode, status);
if (exp_result == SHOULD_PASS) {
ASSERT_EQ(0, rcode);
} else {
ASSERT_EQ(1, rcode);
}
}
// Tests ability to turn on and off ddns updates by submitting
// by submitting the appropriate configuration to Dhcp4 server
// and then invoking its startD2() method.
TEST_F(Dhcp4SrvD2Test, enableDisable) {
// Grab the manager and verify that be default ddns is off
// and a sender was not started.
dhcp::D2ClientMgr& mgr = CfgMgr::instance().getD2ClientMgr();
ASSERT_FALSE(mgr.ddnsEnabled());
ASSERT_FALSE(mgr.amSending());
// Verify a valid config with ddns enabled configures ddns properly,
// but does not start the sender.
ASSERT_NO_FATAL_FAILURE(configureD2(true));
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_FALSE(mgr.amSending());
// Verify that calling start does not throw and starts the sender.
ASSERT_NO_THROW(srv_.startD2());
ASSERT_TRUE(mgr.amSending());
// Verify a valid config with ddns disabled configures ddns properly.
// Sender should not have been started.
ASSERT_NO_FATAL_FAILURE(configureD2(false));
ASSERT_FALSE(mgr.ddnsEnabled());
ASSERT_FALSE(mgr.amSending());
// Verify that the sender does NOT get started when ddns is disabled.
srv_.startD2();
ASSERT_FALSE(mgr.amSending());
}
// Tests Dhcp4 server's ability to correctly handle a flawed dhcp-ddns configuration.
// It does so by first enabling updates by submitting a valid configuration and then
// ensuring they remain on after submitting a flawed configuration.
// and then invoking its startD2() method.
TEST_F(Dhcp4SrvD2Test, badConfig) {
// Grab the manager and verify that be default ddns is off
// and a sender was not started.
dhcp::D2ClientMgr& mgr = CfgMgr::instance().getD2ClientMgr();
ASSERT_FALSE(mgr.ddnsEnabled());
// Configure it enabled and start it.
ASSERT_NO_FATAL_FAILURE(configureD2(true));
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_NO_THROW(srv_.startD2());
ASSERT_TRUE(mgr.amSending());
// Now attempt to give it an invalid configuration.
// Result should indicate failure.
ASSERT_NO_FATAL_FAILURE(configureD2(false, SHOULD_FAIL, "bogus_ip"));
// Configure was not altered, so ddns should be enabled and still sending.
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_TRUE(mgr.amSending());
// Verify that calling start does not throw or stop the sender.
ASSERT_NO_THROW(srv_.startD2());
ASSERT_TRUE(mgr.amSending());
}
// Checks that submitting an identical dhcp-ddns configuration
// is handled properly. Not effect should be no change in
// status for ddns updating. Updates should still enabled and
// in send mode. This indicates that the sender was not stopped.
TEST_F(Dhcp4SrvD2Test, sameConfig) {
// Grab the manager and verify that be default ddns is off
// and a sender was not started.
dhcp::D2ClientMgr& mgr = CfgMgr::instance().getD2ClientMgr();
ASSERT_FALSE(mgr.ddnsEnabled());
// Configure it enabled and start it.
ASSERT_NO_FATAL_FAILURE(configureD2(true));
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_NO_THROW(srv_.startD2());
ASSERT_TRUE(mgr.amSending());
// Now submit an identical configuration.
ASSERT_NO_FATAL_FAILURE(configureD2(true));
// Configuration was not altered, so ddns should still enabled and sending.
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_TRUE(mgr.amSending());
// Verify that calling start does not throw or stop the sender.
ASSERT_NO_THROW(srv_.startD2());
ASSERT_TRUE(mgr.amSending());
}
// Checks that submitting an different, but valid dhcp-ddns configuration
// is handled properly. Updates should be enabled, however they should
// not yet be running. This indicates that the sender was stopped and
// replaced, but not yet started.
TEST_F(Dhcp4SrvD2Test, differentConfig) {
// Grab the manager and verify that be default ddns is off
// and a sender was not started.
dhcp::D2ClientMgr& mgr = CfgMgr::instance().getD2ClientMgr();
ASSERT_FALSE(mgr.ddnsEnabled());
// Configure it enabled and start it.
ASSERT_NO_FATAL_FAILURE(configureD2(true));
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_NO_THROW(srv_.startD2());
ASSERT_TRUE(mgr.amSending());
// Now enable it on a different port.
ASSERT_NO_FATAL_FAILURE(configureD2(true, SHOULD_PASS, "127.0.0.1", 54001));
// Configuration was altered, so ddns should still enabled but not sending.
ASSERT_TRUE(mgr.ddnsEnabled());
ASSERT_FALSE(mgr.amSending());
// Verify that calling start starts the sender.