123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697 |
- // 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/d2_cfg_mgr.h>
- #include <d2/nc_add.h>
- #include <boost/function.hpp>
- #include <boost/bind.hpp>
- #include <util/buffer.h>
- #include <dns/rdataclass.h>
- 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 NameAddTransaction 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 implementation first to verify its events. These are
- // events common to all transactions, and they must be defined.
- // SELECT_SERVER_EVT
- // SERVER_SELECTED_EVT
- // SERVER_IO_ERROR_EVT
- // NO_MORE_SERVERS_EVT
- // IO_COMPLETED_EVT
- // UPDATE_OK_EVT
- // UPDATE_FAILED_EVT
- NameChangeTransaction::verifyEvents();
- // Verify NameAddTransaction events by attempting to fetch them.
- getEvent(FQDN_IN_USE_EVT);
- getEvent(FQDN_NOT_IN_USE_EVT);
- }
- void
- NameAddTransaction::defineStates() {
- // Call superclass impl first.
- NameChangeTransaction::defineStates();
- // Define NameAddTransaction 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 implementation first to verify its states. These are
- // states common to all transactions, and they must be defined.
- // READY_ST
- // SELECTING_FWD_SERVER_ST
- // SELECTING_REV_SERVER_ST
- // PROCESS_TRANS_OK_ST
- // PROCESS_TRANS_FAILED_ST
- NameChangeTransaction::verifyStates();
- // Verify NameAddTransaction states by attempting to fetch them.
- 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.
- try {
- buildAddFwdAddressRequest();
- } catch (const std::exception& ex) {
- // While unlikely, the build might fail if we have invalid
- // data. Should that be the case, we need to fail the
- // transaction.
- LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_ADD_BUILD_FAILURE)
- .arg(getNcr()->toText())
- .arg(ex.what());
- transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
- break;
- }
- }
- // 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.
- try {
- buildReplaceFwdAddressRequest();
- } catch (const std::exception& ex) {
- // While unlikely, the build might fail if we have invalid
- // data. Should that be the case, we need to fail the
- // transaction.
- LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REPLACE_BUILD_FAILURE)
- .arg(getNcr()->toText())
- .arg(ex.what());
- transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
- break;
- }
- }
- // 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()) {
- // FQDN is NOT in use so go back and do the forward add address.
- // Covers the case that it was there when we tried to add it,
- // but has since been removed per RFC 4703.
- transition(ADDING_FWD_ADDRS_ST, SERVER_SELECTED_EVT);
- } else {
- // Per RFC4703 any other value means cease.
- // If we get not authorized should try the next server in
- // the list? @todo This needs some discussion perhaps.
- LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REPLACE_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_REPLACE_IO_ERROR)
- .arg(getNcr()->getFqdn())
- .arg(getCurrentServer()->getIpAddress());
- // If we are out of retries on this server, we go back and start
- // all over on a new server.
- 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_REPLACE_RESP_CORRUPT)
- .arg(getCurrentServer()->getIpAddress())
- .arg(getNcr()->getFqdn());
- // If we are out of retries on this server, we go back and start
- // all over on a new server.
- 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_REPLACE_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::selectingRevServerHandler() {
- switch(getNextEvent()) {
- case SELECT_SERVER_EVT:
- // First time through for this transaction, so initialize server
- // selection.
- initServerSelection(getReverseDomain());
- 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(REPLACING_REV_PTRS_ST, SERVER_SELECTED_EVT);
- }
- else {
- // Server list is exhausted, so fail the transaction.
- transition(PROCESS_TRANS_FAILED_ST, NO_MORE_SERVERS_EVT);
- }
- }
- void
- NameAddTransaction::replacingRevPtrsHandler() {
- 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.
- try {
- buildReplaceRevPtrsRequest();
- } catch (const std::exception& ex) {
- // While unlikely, the build might fail if we have invalid
- // data. Should that be the case, we need to fail the
- // transaction.
- LOG_ERROR(dctl_logger, DHCP_DDNS_REVERSE_REPLACE_BUILD_FAILURE)
- .arg(getNcr()->toText())
- .arg(ex.what());
- transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
- break;
- }
- }
- // 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 update the reverse mapping. Mark it as done.
- setReverseChangeCompleted(true);
- transition(PROCESS_TRANS_OK_ST, UPDATE_OK_EVT);
- } else {
- // Per RFC4703 any other value means cease.
- // If we get not authorized should try the next server in
- // the list? @todo This needs some discussion perhaps.
- LOG_ERROR(dctl_logger, DHCP_DDNS_REVERSE_REPLACE_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_REVERSE_REPLACE_IO_ERROR)
- .arg(getNcr()->getFqdn())
- .arg(getCurrentServer()->getIpAddress());
- // If we are out of retries on this server, we go back and start
- // all over on a new server.
- retryTransition(SELECTING_REV_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_REVERSE_REPLACE_RESP_CORRUPT)
- .arg(getCurrentServer()->getIpAddress())
- .arg(getNcr()->getFqdn());
- // If we are out of retries on this server, we go back and start
- // all over on a new server.
- retryTransition(SELECTING_REV_SERVER_ST);
- break;
- default:
- // Any other value and we will fail this transaction, something
- // bigger is wrong.
- LOG_ERROR(dctl_logger,
- DHCP_DDNS_REVERSE_REPLACE_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::processAddOkHandler() {
- switch(getNextEvent()) {
- case UPDATE_OK_EVT:
- LOG_DEBUG(dctl_logger, DBGLVL_TRACE_DETAIL, DHCP_DDNS_ADD_SUCCEEDED)
- .arg(getNcr()->toText());
- setNcrStatus(dhcp_ddns::ST_COMPLETED);
- endModel();
- break;
- default:
- // Event is invalid.
- isc_throw(NameAddTransactionError,
- "Wrong event for context: " << getContextStr());
- }
- }
- void
- NameAddTransaction::processAddFailedHandler() {
- switch(getNextEvent()) {
- case UPDATE_FAILED_EVT:
- case NO_MORE_SERVERS_EVT:
- LOG_ERROR(dctl_logger, DHCP_DDNS_ADD_FAILED).arg(getNcr()->toText())
- .arg(getContextStr());
- setNcrStatus(dhcp_ddns::ST_FAILED);
- endModel();
- break;
- default:
- // Event is invalid.
- isc_throw(NameAddTransactionError,
- "Wrong event for context: " << getContextStr());
- }
- }
- void
- NameAddTransaction::buildAddFwdAddressRequest() {
- // Construct an empty request.
- D2UpdateMessagePtr request = prepNewRequest(getForwardDomain());
- // Construct dns::Name from NCR fqdn.
- dns::Name fqdn(dns::Name(getNcr()->getFqdn()));
- // Content on this request is based on RFC 4703, section 5.3.1
- // First build the Prerequisite Section.
- // Create 'FQDN Is Not In Use' prerequisite and add it to the
- // prerequisite section.
- // Based on RFC 2136, section 2.4.5
- dns::RRsetPtr prereq(new dns::RRset(fqdn, dns::RRClass::NONE(),
- dns::RRType::ANY(), dns::RRTTL(0)));
- request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
- // Next build the Update Section.
- // Create the FQDN/IP 'add' RR and add it to the to update section.
- // Based on RFC 2136, section 2.5.1
- dns::RRsetPtr update(new dns::RRset(fqdn, dns::RRClass::IN(),
- getAddressRRType(), dns::RRTTL(0)));
- addLeaseAddressRdata(update);
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Now create the FQDN/DHCID 'add' RR and add it to update section.
- // Based on RFC 2136, section 2.5.1
- update.reset(new dns::RRset(fqdn, dns::RRClass::IN(),
- dns::RRType::DHCID(), dns::RRTTL(0)));
- addDhcidRdata(update);
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Set the transaction's update request to the new request.
- setDnsUpdateRequest(request);
- }
- void
- NameAddTransaction::buildReplaceFwdAddressRequest() {
- // Construct an empty request.
- D2UpdateMessagePtr request = prepNewRequest(getForwardDomain());
- // Construct dns::Name from NCR fqdn.
- dns::Name fqdn(dns::Name(getNcr()->getFqdn()));
- // Content on this request is based on RFC 4703, section 5.3.2
- // First build the Prerequisite Section.
- // Create an 'FQDN Is In Use' prerequisite and add it to the
- // pre-requisite section.
- // Based on RFC 2136, section 2.4.4
- dns::RRsetPtr prereq(new dns::RRset(fqdn, dns::RRClass::ANY(),
- dns::RRType::ANY(), dns::RRTTL(0)));
- request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
- // Create an DHCID matches prerequisite RR and add it to the
- // pre-requisite section.
- // Based on RFC 2136, section 2.4.2.
- prereq.reset(new dns::RRset(fqdn, dns::RRClass::IN(),
- dns::RRType::DHCID(), dns::RRTTL(0)));
- addDhcidRdata(prereq);
- request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
- // Next build the Update Section.
- // Create the FQDN/IP 'delete' RR and add it to the update section.
- // Based on RFC 2136, section 2.5.2
- dns::RRsetPtr update(new dns::RRset(fqdn, dns::RRClass::ANY(),
- getAddressRRType(), dns::RRTTL(0)));
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Create the FQDN/IP 'add' RR and add it to the update section.
- // Based on RFC 2136, section 2.5.1
- update.reset(new dns::RRset(fqdn, dns::RRClass::IN(),
- getAddressRRType(), dns::RRTTL(0)));
- addLeaseAddressRdata(update);
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Set the transaction's update request to the new request.
- setDnsUpdateRequest(request);
- }
- void
- NameAddTransaction::buildReplaceRevPtrsRequest() {
- // Construct an empty request.
- D2UpdateMessagePtr request = prepNewRequest(getReverseDomain());
- // Create the reverse IP address "FQDN".
- std::string rev_addr = D2CfgMgr::reverseIpAddress(getNcr()->getIpAddress());
- dns::Name rev_ip(rev_addr);
- // Content on this request is based on RFC 4703, section 5.4
- // Reverse replacement has no prerequisites so straight on to
- // building the Update section.
- // Create the PTR 'delete' RR and add it to update section.
- dns::RRsetPtr update(new dns::RRset(rev_ip, dns::RRClass::ANY(),
- dns::RRType::PTR(), dns::RRTTL(0)));
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Create the DHCID 'delete' RR and add it to the update section.
- update.reset(new dns::RRset(rev_ip, dns::RRClass::ANY(),
- dns::RRType::DHCID(), dns::RRTTL(0)));
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Create the FQDN/IP PTR 'add' RR, add the FQDN as the PTR Rdata
- // then add it to update section.
- update.reset(new dns::RRset(rev_ip, dns::RRClass::IN(),
- dns::RRType::PTR(), dns::RRTTL(0)));
- addPtrRdata(update);
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Create the FQDN/IP PTR 'add' RR, add the DHCID Rdata
- // then add it to update section.
- update.reset(new dns::RRset(rev_ip, dns::RRClass::IN(),
- dns::RRType::DHCID(), dns::RRTTL(0)));
- addDhcidRdata(update);
- request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
- // Set the transaction's update request to the new request.
- setDnsUpdateRequest(request);
- }
- } // namespace isc::d2
- } // namespace isc
|