Commit 8f99da73 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

Merge branch 'trac3087'

parents 608638ff 33a7569f
......@@ -50,6 +50,7 @@ BUILT_SOURCES = spec_config.h d2_messages.h d2_messages.cc
pkglibexec_PROGRAMS = b10-dhcp-ddns
b10_dhcp_ddns_SOURCES = main.cc
b10_dhcp_ddns_SOURCES += d2_asio.h
b10_dhcp_ddns_SOURCES += d2_log.cc d2_log.h
b10_dhcp_ddns_SOURCES += d2_process.cc d2_process.h
b10_dhcp_ddns_SOURCES += d_controller.cc d_controller.h
......@@ -63,6 +64,7 @@ b10_dhcp_ddns_SOURCES += d2_update_mgr.cc d2_update_mgr.h
b10_dhcp_ddns_SOURCES += d2_zone.cc d2_zone.h
b10_dhcp_ddns_SOURCES += dns_client.cc dns_client.h
b10_dhcp_ddns_SOURCES += labeled_value.cc labeled_value.h
b10_dhcp_ddns_SOURCES += nc_add.cc nc_add.h
b10_dhcp_ddns_SOURCES += nc_trans.cc nc_trans.h
b10_dhcp_ddns_SOURCES += state_model.cc state_model.h
......
// Copyright (C) 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.
#ifndef D2_ASIO_H
#define D2_ASIO_H
#include <asiolink/asiolink.h>
#include <boost/shared_ptr.hpp>
namespace isc {
namespace d2 {
/// @brief Defines a smart pointer to an IOService instance.
typedef boost::shared_ptr<isc::asiolink::IOService> IOServicePtr;
}; // namespace isc::d2
}; // namespace isc
#endif
......@@ -15,9 +15,9 @@
#ifndef D2_CFG_MGR_H
#define D2_CFG_MGR_H
#include <asiolink/io_address.h>
#include <cc/data.h>
#include <exceptions/exceptions.h>
#include <d2/d2_asio.h>
#include <d2/d_cfg_mgr.h>
#include <d2/d2_config.h>
......
......@@ -15,8 +15,8 @@
#ifndef D2_CONFIG_H
#define D2_CONFIG_H
#include <asiolink/io_address.h>
#include <cc/data.h>
#include <d2/d2_asio.h>
#include <d2/d_cfg_mgr.h>
#include <dhcpsrv/dhcp_parsers.h>
#include <exceptions/exceptions.h>
......
......@@ -190,7 +190,7 @@ indicate a network connectivity or system resource issue.
% DHCP_DDNS_QUEUE_MGR_RESUME_ERROR application could not restart the queue manager, reason: %1
This is an error message indicating that DHCP_DDNS's Queue Manager could not
be restarted after stopping due to an a full receive queue. This means that
be restarted after stopping due to a full receive queue. This means that
the application cannot receive requests. This is most likely due to DHCP_DDNS
configuration parameters referring to resources such as an IP address or port,
that is no longer unavailable. DHCP_DDNS will attempt to restart the queue
......@@ -258,3 +258,69 @@ This is error message issued when the application fails to process a
NameChangeRequest correctly. Some or all of the DNS updates requested as part
of this update did not succeed. This is a programmatic error and should be
reported.
% DHCP_DDNS_FORWARD_ADD_REJECTED DNS Server, %1, rejected a DNS update request to add the address mapping for FQDN, %2, with an RCODE: %3
This is an error message issued when an update was rejected by the DNS server
it was sent to for the reason given by the RCODE. The rcode values are defined
in RFC 2136.
% DHCP_DDNS_FORWARD_ADD_IO_ERROR DHCP_DDNS encountered an IO error sending a forward mapping add for FQDN %1 to DNS server %2
This is an error message issued when a communication error occurs while
DHCP_DDNS is carrying out a forward address update. The application will
retry against the same server or others as appropriate.
% DHCP_DDNS_FORWARD_ADD_RESP_CORRUPT DHCP_DDNS received a corrupt response from the DNS server, %1, while adding forward address mapping for FQDN, %2
This is an error message issued when the response received by DHCP_DDNS, to a
update request to add a forward address mapping, is mangled or malformed.
The application will retry against the same server or others as appropriate.
% DHCP_DDNS_FORWARD_ADD_BAD_DNSCLIENT_STATUS DHCP_DDNS received an unknown DNSClient status: %1, while adding a forward address mapping for FQDN %2 to DNS server %3
This is an error message issued when DNSClient returns an unrecognized status
while DHCP_DDNS was adding a forward address mapping. The request will be
aborted. This is most likely a programmatic issue and should be reported.
% DHCP_DDNS_FORWARD_REPLACE_REJECTED DNS Server, %1, rejected a DNS update request to replace the address mapping for FQDN, %2, with an RCODE: %3
This is an error message issued when an update was rejected by the DNS server
it was sent to for the reason given by the RCODE. The rcode values are defined
in RFC 2136.
% DHCP_DDNS_FORWARD_REPLACE_IO_ERROR DHCP_DDNS encountered an IO error sending a forward mapping replace for FQDN %1 to DNS server %2
This is an error message issued when a communication error occurs while
DHCP_DDNS is carrying out a forward address update. The application will
retry against the same server or others as appropriate.
% DHCP_DDNS_FORWARD_REPLACE_RESP_CORRUPT DHCP_DDNS received a corrupt response from the DNS server, %1, while replacing forward address mapping for FQDN, %2
This is an error message issued when the response received by DHCP_DDNS, to a
update request to replace a forward address mapping, is mangled or malformed.
The application will retry against the same server or others as appropriate.
% DHCP_DDNS_FORWARD_REPLACE_BAD_DNSCLIENT_STATUS DHCP_DDNS received an unknown DNSClient status: %1, while replacing forward address mapping for FQDN %2 to DNS server %3
This is an error message issued when DNSClient returns an unrecognized status
while DHCP_DDNS was replacing a forward address mapping. The request will be
aborted. This is most likely a programmatic issue and should be reported.
% DHCP_DDNS_REVERSE_REPLACE_REJECTED DNS Server, %1, rejected a DNS update request to replace the reverse mapping for FQDN, %2, with an RCODE: %3
This is an error message issued when an update was rejected by the DNS server
it was sent to for the reason given by the RCODE. The rcode values are defined
in RFC 2136.
% DHCP_DDNS_REVERSE_REPLACE_IO_ERROR DHCP_DDNS encountered an IO error sending a reverse mapping replacement for FQDN %1 to DNS server %2
This is an error message issued when a communication error occurs while
DHCP_DDNS is carrying out a reverse address update. The application will
retry against the same server or others as appropriate.
% DHCP_DDNS_REVERSE_REPLACE_RESP_CORRUPT DHCP_DDNS received a corrupt response from the DNS server, %1, while replacing reverse address mapping for FQDN, %2
This is an error message issued when the response received by DHCP_DDNS, to a
update request to replace a reverse address, is mangled or malformed.
The application will retry against the same server or others as appropriate.
% DHCP_DDNS_REVERSE_REPLACE_BAD_DNSCLIENT_STATUS DHCP_DDNS received an unknown DNSClient status: %1, while replacing reverse address mapping for FQDN %2 to DNS server %3
This is an error message issued when DNSClient returns an unrecognized status
while DHCP_DDNS was replacing a reverse address mapping. The request will be
aborted. This is most likely a programmatic issue and should be reported.
% DHCP_DDNS_TRANS_SEND_ERROR application encountered an unexpected error while attempting to send a DNS update: %1
This is error message issued when the application is able to construct an update
message but the attempt to send it suffered a unexpected error. This is most
likely a programmatic error, rather than a communications issue. Some or all
of the DNS updates requested as part of this request did not succeed.
......@@ -35,13 +35,13 @@ D2Process::D2Process(const char* name, IOServicePtr io_service)
// been received. This means that until we receive the configuration,
// D2 will neither receive nor process NameChangeRequests.
// Pass in IOService for NCR IO event processing.
queue_mgr_.reset(new D2QueueMgr(*getIoService()));
queue_mgr_.reset(new D2QueueMgr(getIoService()));
// Instantiate update manager.
// Pass in both queue manager and configuration manager.
// Pass in IOService for DNS update transaction IO event processing.
D2CfgMgrPtr tmp = getD2CfgMgr();
update_mgr_.reset(new D2UpdateMgr(queue_mgr_, tmp, *getIoService()));
update_mgr_.reset(new D2UpdateMgr(queue_mgr_, tmp, getIoService()));
};
void
......
......@@ -22,10 +22,13 @@ namespace d2 {
// Makes constant visible to Google test macros.
const size_t D2QueueMgr::MAX_QUEUE_DEFAULT;
D2QueueMgr::D2QueueMgr(isc::asiolink::IOService& io_service,
const size_t max_queue_size)
D2QueueMgr::D2QueueMgr(IOServicePtr& io_service, const size_t max_queue_size)
: io_service_(io_service), max_queue_size_(max_queue_size),
mgr_state_(NOT_INITTED), target_stop_state_(NOT_INITTED) {
if (!io_service_) {
isc_throw(D2QueueMgrError, "IOServicePtr cannot be null");
}
// Use setter to do validation.
setMaxQueueSize(max_queue_size);
}
......@@ -129,7 +132,7 @@ D2QueueMgr::startListening() {
// Instruct the listener to start listening and set state accordingly.
try {
listener_->startListening(io_service_);
listener_->startListening(*io_service_);
mgr_state_ = RUNNING;
} catch (const isc::Exception& ex) {
isc_throw(D2QueueMgrError, "D2QueueMgr listener start failed: "
......
......@@ -17,9 +17,8 @@
/// @file d2_queue_mgr.h This file defines the class D2QueueMgr.
#include <asiolink/io_address.h>
#include <asiolink/io_service.h>
#include <exceptions/exceptions.h>
#include <d2/d2_asio.h>
#include <dhcp_ddns/ncr_msg.h>
#include <dhcp_ddns/ncr_io.h>
......@@ -166,7 +165,7 @@ public:
/// This value must be greater than zero. It defaults to MAX_QUEUE_DEFAULT.
///
/// @throw D2QueueMgrError if max_queue_size is zero.
D2QueueMgr(isc::asiolink::IOService& io_service,
D2QueueMgr(IOServicePtr& io_service,
const size_t max_queue_size = MAX_QUEUE_DEFAULT);
/// @brief Destructor
......@@ -328,7 +327,7 @@ public:
void updateStopState();
/// @brief IOService that our listener should use for IO management.
isc::asiolink::IOService& io_service_;
IOServicePtr io_service_;
/// @brief Dictates the maximum number of entries allowed in the queue.
size_t max_queue_size_;
......
......@@ -24,7 +24,7 @@ namespace d2 {
const size_t D2UpdateMgr::MAX_TRANSACTIONS_DEFAULT;
D2UpdateMgr::D2UpdateMgr(D2QueueMgrPtr& queue_mgr, D2CfgMgrPtr& cfg_mgr,
isc::asiolink::IOService& io_service,
IOServicePtr& io_service,
const size_t max_transactions)
:queue_mgr_(queue_mgr), cfg_mgr_(cfg_mgr), io_service_(io_service) {
if (!queue_mgr_) {
......@@ -36,6 +36,10 @@ D2UpdateMgr::D2UpdateMgr(D2QueueMgrPtr& queue_mgr, D2CfgMgrPtr& cfg_mgr,
"D2UpdateMgr configuration manager cannot be null");
}
if (!io_service_) {
isc_throw(D2UpdateMgrError, "IOServicePtr cannot be null");
}
// Use setter to do validation.
setMaxTransactions(max_transactions);
}
......
......@@ -17,8 +17,8 @@
/// @file d2_update_mgr.h This file defines the class D2UpdateMgr.
#include <asiolink/io_service.h>
#include <exceptions/exceptions.h>
#include <d2/d2_asio.h>
#include <d2/d2_log.h>
#include <d2/d2_queue_mgr.h>
#include <d2/d2_cfg_mgr.h>
......@@ -100,7 +100,7 @@ public:
/// @throw D2UpdateMgrError if either the queue manager or configuration
/// managers are NULL, or max transactions is less than one.
D2UpdateMgr(D2QueueMgrPtr& queue_mgr, D2CfgMgrPtr& cfg_mgr,
isc::asiolink::IOService& io_service,
IOServicePtr& io_service,
const size_t max_transactions = MAX_TRANSACTIONS_DEFAULT);
/// @brief Destructor
......@@ -228,7 +228,7 @@ private:
/// passed into transactions to manager their IO events.
/// (For future reference, multi-threaded transactions would each use their
/// own IOService instance.)
isc::asiolink::IOService& io_service_;
IOServicePtr io_service_;
/// @brief Maximum number of concurrent transactions.
size_t max_transactions_;
......
......@@ -15,10 +15,10 @@
#ifndef D_CONTROLLER_H
#define D_CONTROLLER_H
#include <asiolink/asiolink.h>
#include <cc/data.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <d2/d2_asio.h>
#include <d2/d2_log.h>
#include <d2/d_process.h>
#include <exceptions/exceptions.h>
......
......@@ -15,16 +15,14 @@
#ifndef D_PROCESS_H
#define D_PROCESS_H
#include <asiolink/asiolink.h>
#include <cc/data.h>
#include <d2/d2_asio.h>
#include <d2/d_cfg_mgr.h>
#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
typedef boost::shared_ptr<isc::asiolink::IOService> IOServicePtr;
namespace isc {
namespace d2 {
......
......@@ -162,7 +162,7 @@ DNSClientImpl::getStatus(const asiodns::IOFetch::Result result) {
}
void
DNSClientImpl::doUpdate(IOService& io_service,
DNSClientImpl::doUpdate(asiolink::IOService& io_service,
const IOAddress& ns_addr,
const uint16_t ns_port,
D2UpdateMessage& update,
......@@ -191,6 +191,7 @@ DNSClientImpl::doUpdate(IOService& io_service,
// caller that the unsigned timeout value will fit into int.
IOFetch io_fetch(IOFetch::UDP, io_service, msg_buf, ns_addr, ns_port,
in_buf_, this, static_cast<int>(wait));
// Post the task to the task queue in the IO service. Caller will actually
// run these tasks by executing IOService::run.
io_service.post(io_fetch);
......@@ -213,7 +214,7 @@ DNSClient::getMaxTimeout() {
}
void
DNSClient::doUpdate(IOService&,
DNSClient::doUpdate(asiolink::IOService&,
const IOAddress&,
const uint16_t,
D2UpdateMessage&,
......@@ -224,7 +225,7 @@ DNSClient::doUpdate(IOService&,
}
void
DNSClient::doUpdate(IOService& io_service,
DNSClient::doUpdate(asiolink::IOService& io_service,
const IOAddress& ns_addr,
const uint16_t ns_port,
D2UpdateMessage& update,
......
// Copyright (C) 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 <d2/d2_log.h>
#include <d2/nc_add.h>
#include <boost/function.hpp>
#include <boost/bind.hpp>
namespace isc {
namespace d2 {
// NameAddTransaction states
const int NameAddTransaction::ADDING_FWD_ADDRS_ST;
const int NameAddTransaction::REPLACING_FWD_ADDRS_ST;
const int NameAddTransaction::REPLACING_REV_PTRS_ST;
// NameAddTransaction events
const int NameAddTransaction::FQDN_IN_USE_EVT;
const int NameAddTransaction::FQDN_NOT_IN_USE_EVT;
NameAddTransaction::
NameAddTransaction(IOServicePtr& io_service,
dhcp_ddns::NameChangeRequestPtr& ncr,
DdnsDomainPtr& forward_domain,
DdnsDomainPtr& reverse_domain)
: NameChangeTransaction(io_service, ncr, forward_domain, reverse_domain) {
if (ncr->getChangeType() != isc::dhcp_ddns::CHG_ADD) {
isc_throw (NameAddTransactionError,
"NameAddTransaction, request type must be CHG_ADD");
}
}
NameAddTransaction::~NameAddTransaction(){
}
void
NameAddTransaction::defineEvents() {
// Call superclass impl first.
NameChangeTransaction::defineEvents();
// Define NCT events.
defineEvent(FQDN_IN_USE_EVT, "FQDN_IN_USE_EVT");
defineEvent(FQDN_NOT_IN_USE_EVT, "FQDN_NOT_IN_USE_EVT");
}
void
NameAddTransaction::verifyEvents() {
// Call superclass impl first.
NameChangeTransaction::verifyEvents();
// Verify NCT events.
getEvent(FQDN_IN_USE_EVT);
getEvent(FQDN_NOT_IN_USE_EVT);
}
void
NameAddTransaction::defineStates() {
// Call superclass impl first.
NameChangeTransaction::defineStates();
// Define the states.
defineState(READY_ST, "READY_ST",
boost::bind(&NameAddTransaction::readyHandler, this));
defineState(SELECTING_FWD_SERVER_ST, "SELECTING_FWD_SERVER_ST",
boost::bind(&NameAddTransaction::selectingFwdServerHandler, this));
defineState(SELECTING_REV_SERVER_ST, "SELECTING_REV_SERVER_ST",
boost::bind(&NameAddTransaction::selectingRevServerHandler, this));
defineState(ADDING_FWD_ADDRS_ST, "ADDING_FWD_ADDRS_ST",
boost::bind(&NameAddTransaction::addingFwdAddrsHandler, this));
defineState(REPLACING_FWD_ADDRS_ST, "REPLACING_FWD_ADDRS_ST",
boost::bind(&NameAddTransaction::replacingFwdAddrsHandler, this));
defineState(REPLACING_REV_PTRS_ST, "REPLACING_REV_PTRS_ST",
boost::bind(&NameAddTransaction::replacingRevPtrsHandler, this));
defineState(PROCESS_TRANS_OK_ST, "PROCESS_TRANS_OK_ST",
boost::bind(&NameAddTransaction::processAddOkHandler, this));
defineState(PROCESS_TRANS_FAILED_ST, "PROCESS_TRANS_FAILED_ST",
boost::bind(&NameAddTransaction::processAddFailedHandler, this));
}
void
NameAddTransaction::verifyStates() {
// Call superclass impl first.
NameChangeTransaction::verifyStates();
// Verify NCT states. This ensures that derivations provide the handlers.
getState(ADDING_FWD_ADDRS_ST);
getState(REPLACING_FWD_ADDRS_ST);
getState(REPLACING_REV_PTRS_ST);
}
void
NameAddTransaction::readyHandler() {
switch(getNextEvent()) {
case START_EVT:
if (getForwardDomain()) {
// Request includes a forward change, do that first.
transition(SELECTING_FWD_SERVER_ST, SELECT_SERVER_EVT);
} else {
// Reverse change only, transition accordingly.
transition(SELECTING_REV_SERVER_ST, SELECT_SERVER_EVT);
}
break;
default:
// Event is invalid.
isc_throw(NameAddTransactionError,
"Wrong event for context: " << getContextStr());
}
}
void
NameAddTransaction::selectingFwdServerHandler() {
switch(getNextEvent()) {
case SELECT_SERVER_EVT:
// First time through for this transaction, so initialize server
// selection.
initServerSelection(getForwardDomain());
break;
case SERVER_IO_ERROR_EVT:
// We failed to communicate with current server. Attempt to select
// another one below.
break;
default:
// Event is invalid.
isc_throw(NameAddTransactionError,
"Wrong event for context: " << getContextStr());
}
// Select the next server from the list of forward servers.
if (selectNextServer()) {
// We have a server to try.
transition(ADDING_FWD_ADDRS_ST, SERVER_SELECTED_EVT);
}
else {
// Server list is exhausted, so fail the transaction.
transition(PROCESS_TRANS_FAILED_ST, NO_MORE_SERVERS_EVT);
}
}
void
NameAddTransaction::addingFwdAddrsHandler() {
if (doOnEntry()) {
// Clear the request on initial transition. This allows us to reuse
// the request on retries if necessary.
clearDnsUpdateRequest();
}
switch(getNextEvent()) {
case SERVER_SELECTED_EVT:
if (!getDnsUpdateRequest()) {
// Request hasn't been constructed yet, so build it.
buildAddFwdAddressRequest();
}
// Call sendUpdate() to initiate the async send. Note it also sets
// next event to NOP_EVT.
sendUpdate();
break;
case IO_COMPLETED_EVT: {
switch (getDnsUpdateStatus()) {
case DNSClient::SUCCESS: {
// We successfully received a response packet from the server.
const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
if (rcode == dns::Rcode::NOERROR()) {
// We were able to add it. Mark it as done.
setForwardChangeCompleted(true);
// If request calls for reverse update then do that next,
// otherwise we can process ok.
if (getReverseDomain()) {
transition(SELECTING_REV_SERVER_ST, SELECT_SERVER_EVT);
} else {
transition(PROCESS_TRANS_OK_ST, UPDATE_OK_EVT);
}
} else if (rcode == dns::Rcode::YXDOMAIN()) {
// FQDN is in use so we need to attempt to replace
// forward address.
transition(REPLACING_FWD_ADDRS_ST, FQDN_IN_USE_EVT);
} else {
// Per RFC4703 any other value means cease.
// If we get not authorized should we try the next server in
// the list? @todo This needs some discussion perhaps.
LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_ADD_REJECTED)
.arg(getCurrentServer()->getIpAddress())
.arg(getNcr()->getFqdn())
.arg(rcode.getCode());
transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
}
break;
}
case DNSClient::TIMEOUT:
case DNSClient::OTHER:
// We couldn't send to the current server, log it and set up
// to select the next server for a retry.
// @note For now we treat OTHER as an IO error like TIMEOUT. It
// is not entirely clear if this is accurate.
LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_ADD_IO_ERROR)
.arg(getNcr()->getFqdn())
.arg(getCurrentServer()->getIpAddress());
retryTransition(SELECTING_FWD_SERVER_ST);
break;
case DNSClient::INVALID_RESPONSE:
// A response was received but was corrupt. Retry it like an IO
// error.
LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_ADD_RESP_CORRUPT)
.arg(getCurrentServer()->getIpAddress())
.arg(getNcr()->getFqdn());
retryTransition(SELECTING_FWD_SERVER_ST);
break;
default:
// Any other value and we will fail this transaction, something
// bigger is wrong.
LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_ADD_BAD_DNSCLIENT_STATUS)
.arg(getDnsUpdateStatus())
.arg(getNcr()->getFqdn())
.arg(getCurrentServer()->getIpAddress());
transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
break;
} // end switch on dns_status
break;
} // end case IO_COMPLETE_EVT
default:
// Event is invalid.
isc_throw(NameAddTransactionError,
"Wrong event for context: " << getContextStr());
}
}
void
NameAddTransaction::replacingFwdAddrsHandler() {
if (doOnEntry()) {
// Clear the request on initial transition. This allows us to reuse
// the request on retries if necessary.
clearDnsUpdateRequest();
}
switch(getNextEvent()) {
case FQDN_IN_USE_EVT:
case SERVER_SELECTED_EVT:
if (!getDnsUpdateRequest()) {
// Request hasn't been constructed yet, so build it.
buildReplaceFwdAddressRequest();
}
// Call sendUpdate() to initiate the async send. Note it also sets
// next event to NOP_EVT.
sendUpdate();
break;
case IO_COMPLETED_EVT: {
switch (getDnsUpdateStatus()) {
case DNSClient::SUCCESS: {
// We successfully received a response packet from the server.
const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
if (rcode == dns::Rcode::NOERROR()) {
// We were able to replace the forward mapping. Mark it as done.
setForwardChangeCompleted(true);
// If request calls for reverse update then do that next,
// otherwise we can process ok.
if (getReverseDomain()) {
transition(SELECTING_REV_SERVER_ST, SELECT_SERVER_EVT);
} else {
transition(PROCESS_TRANS_OK_ST, UPDATE_OK_EVT);
}
} else if (rcode == dns::Rcode::NXDOMAIN()) {