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.
try {
// Pull the full configuration out from the session.
configureDhcp6Server(*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());
probable if you see many such messages. Clients will recover from this,
but they will most likely get a different IP addresses and experience
a brief service interruption.
+
+% DHCP6_DDNS_REQUEST_SEND_FAILED failed sending a request to b10-dhcp-ddns, error : %1, ncr: %2
+This error message indicates that IPv6 DHCP server attempted to send a DDNS
+update reqeust to the DHCP-DDNS server. This is most likely a configuration or
+networking error.
}
}
+void
+Dhcpv6Srv::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(&Dhcpv6Srv::d2ClientErrorHandler,
+ this, _1, _2));
+ }
+}
+
+void
+Dhcpv6Srv::d2ClientErrorHandler(const
+ dhcp_ddns::NameChangeSender::Result result,
+ dhcp_ddns::NameChangeRequestPtr& ncr) {
+ LOG_ERROR(dhcp6_logger, DHCP6_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();
+}
+
};
};
#include <dhcp/option_definition.h>
#include <dhcp/pkt6.h>
#include <dhcpsrv/alloc_engine.h>
+#include <dhcpsrv/d2_client_mgr.h>
#include <dhcpsrv/subnet.h>
#include <hooks/callout_handle.h>
/// @param port UDP port on which server should listen.
static void openActiveSockets(const uint16_t port);
+ /// @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:
/// @brief Compare received server id with our server id
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