-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
-// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// of servers is an error which will be logged and the request will be
/// discarded.
///
+ /// Finally, If conflict resolution is enabled, it will instantiate either
+ /// a NameAddTranscation or a NameRemoveTransaction. If disabled it will
+ /// instantiate either a SimpleAddTransaction or a SimpleRemoveTranscation.
+ ///
/// @param ncr the NameChangeRequest for which to create a transaction.
///
/// @throw D2UpdateMgrError if a transaction for this DHCID already
/// @brief Embodies the "life-cycle" required to carry out a DDNS Add update.
///
/// SimpleAddTransaction implements a state machine for adding (or replacing) a
-/// forward and/or reverse DNS mapping. This state machine is based upon the
-/// processing logic described in RFC 4703, Sections 5.3 and 5.4. That logic
-/// may be paraphrased as follows:
+/// forward and/or reverse DNS mapping. This state machine follows a basic
+/// remove and replace scheme, that does not attempt to avoid conflicts
+/// between updating clients. The logic may be paraphrased as follows:
///
/// @code
///
/// If the request includes a forward change:
/// Select a forward server
-/// Send the server a request to add the forward entry
-/// If the server responds with already in use:
-/// Send a server a request to delete and then add forward entry
-///
-/// If the forward update is unsuccessful:
-/// abandon the update
+/// Send the server a request to delete and then add forward entry
///
/// If the request includes a reverse change:
/// Select a reverse server
/// handler simply attempts to select the next server.
///
/// Transitions to:
- /// - REPLACING_FWD_ADDRS_ST with next event of SERVER_SELECTED upon successful
- /// server selection
+ /// - REPLACING_FWD_ADDRS_ST with next event of SERVER_SELECTED upon
+ /// successful server selection
///
/// - PROCESS_TRANS_FAILED with next event of NO_MORE_SERVERS_EVT upon
/// failure to select a server
/// handler simply attempts to select the next server.
///
/// Transitions to:
- /// - REPLACING_REV_PTRS_ST with next event of SERVER_SELECTED upon successful
- /// server selection
+ /// - REPLACING_REV_PTRS_ST with next event of SERVER_SELECTED upon
+ /// successful server selection
///
/// - PROCESS_TRANS_FAILED with next event of NO_MORE_SERVERS_EVT upon
/// failure to select a server
/// UPDATE_FAILED_EVT
void processAddFailedHandler();
- /// @brief Builds a DNS request to add/replace a forward DNS entry for an FQDN
+ /// @brief Builds a DNS request to add/replace a forward DNS entry for an
+ /// FQDN
///
/// Constructs a DNS update request, based upon the NCR, for adding a
/// forward DNS mapping. Once constructed, the request is stored as
/// - There are no prerequisites.
///
/// Updates RRsets:
- /// 1. A delete of all RRs for the given FQDN
- /// 1. An FQDN/IP RR addition (type A for IPv4, AAAA for IPv6)
- /// 2. An FQDN/DHCID RR addition (type DHCID)
+ /// -# A delete of any existing PTR RRs for the lease address
+ /// -# A delete of any existing DHCID RRs for the lease address
+ /// -# An FQDN/IP RR addition (type A for IPv4, AAAA for IPv6)
+ /// -# An FQDN/DHCID RR addition (type DHCID)
///
/// @throw This method does not throw but underlying methods may.
void buildReplaceFwdAddressRequest();
/// - There are no prerequisites.
///
/// Updates RRsets:
- /// 1. A delete of any existing PTR RRs for the lease address
- /// 2. A delete of any existing DHCID RRs for the lease address
- /// 3. A PTR RR addition for the lease address and FQDN
- /// 4. A DHCID RR addition for the lease address and lease client DHCID
+ /// -# A delete of any existing PTR RRs for the lease address
+ /// -# A delete of any existing DHCID RRs for the lease address
+ /// -# A PTR RR addition for the lease address and FQDN
+ /// -# A DHCID RR addition for the lease address and lease client DHCID
///
/// @throw This method does not throw but underlying methods may.
void buildReplaceRevPtrsRequest();
// Construct dns::Name from NCR fqdn.
dns::Name fqdn(dns::Name(getNcr()->getFqdn()));
- // Build the Update Section.
+ // Build the Update Section.
// Create the FQDN/IP 'delete' RR and add it to update section.
dns::RRsetPtr update(new dns::RRset(fqdn, dns::RRClass::ANY(),
std::string rev_addr = D2CfgMgr::reverseIpAddress(getNcr()->getIpAddress());
dns::Name rev_ip(rev_addr);
- /// TKM @todo - not sure we need this pre-req
- // Create an assertion that the PTRDNAME in the PTR record matches the
- // client's FQDN for the address that was released.
- // Based on RFC 2136, section 3.2.3
- dns::RRsetPtr prereq(new dns::RRset(rev_ip, dns::RRClass::IN(),
- dns::RRType::PTR(), dns::RRTTL(0)));
- addPtrRdata(prereq);
- request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
+ // There are no pre-requisites.
- // Now, build the Update section.
+ // Build the Update section.
- // Create a delete of any RRs for the FQDN and add it to update section.
- // Based on RFC 2136, section 3.4.2.3
+ // Create the FQDN/IP PTR 'delete' RR for this IP and add it to
+ // the update section.
dns::RRsetPtr update(new dns::RRset(rev_ip, dns::RRClass::ANY(),
- dns::RRType::ANY(), dns::RRTTL(0)));
+ 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);
// Set the transaction's update request to the new request.
/// @brief Embodies the "life-cycle" required to carry out a DDNS Remove update.
///
/// SimpleRemoveTransaction implements a state machine for removing a forward
-/// and/or reverse DNS mappings. This state machine is based upon the processing
-/// logic described in RFC 4703, Section 5.5. That logic may be paraphrased as
-/// follows:
+/// and/or reverse DNS mappings. This state machine follows a basic
+/// removal scheme, that does not attempt to avoid conflicts between updating
+/// clients. The logic may be paraphrased as follows:
///
/// @code
///
/// If the request includes a forward change:
/// Select a forward server
-/// Send the server a request to remove client's specific forward address RR
-/// If it succeeds or the server responds with name no longer in use
-/// Send a server a request to delete any other RRs for that FQDN, such
-/// as the DHCID RR.
-/// otherwise
+/// Send the server a request to remove client's specific forward address
+/// RR and DHCID RR.
+/// If it does not succeed
/// abandon the update
///
/// If the request includes a reverse change:
/// Select a reverse server
-/// Send a server a request to delete reverse entry (PTR RR)
+/// Send a server a request to delete the matching PTR and DHCID RRs.
///
/// @endcode
///
/// @brief Builds a DNS request to remove all forward DNS RRs for a FQDN.
///
- /// Constructs a DNS update request, based upon the NCR, for removing any
- /// remaining forward DNS RRs, once all A or AAAA entries for the FQDN
- /// have been removed. Once constructed, the request is stored as the
- /// transaction's DNS update request.
- ///
- /// The request content is adherent to RFC 4703 section 5.5, paragraph 5.
+ /// Constructs a DNS update request, based upon the NCR, to remove the
+ /// forward DNS (A or AAAA) RR and DHCID RR. Once constructed, the request
+ /// is stored as the transaction's DNS update request.
///
/// Prerequisite RRsets:
/// - None
/// reverse DNS mapping. Once constructed, the request is stored as
/// the transaction's DNS update request.
///
- /// The request content is adherent to RFC 4703 section 5.5, paragraph 2:
- ///
/// Prerequisite RRsets:
- /// 1. An assertion that a PTR record matching the client's FQDN exists.
+ /// - None
///
/// Updates RRsets:
- /// 1. A delete of all RRs for the FQDN
+ /// -# A delete of PTR RR for the IP
+ /// -# A delete of DHCID RR for the IP
///
/// @throw This method does not throw but underlying methods may.
void buildRemoveRevPtrsRequest();
ASSERT_NO_THROW(request->toWire(renderer));
}
+void checkSimpleRemoveRevPtrsRequest(NameChangeTransaction& tran) {
+ const D2UpdateMessagePtr& request = tran.getDnsUpdateRequest();
+ ASSERT_TRUE(request);
+
+ // Safety check.
+ dhcp_ddns::NameChangeRequestPtr ncr = tran.getNcr();
+ ASSERT_TRUE(ncr);
+
+ std::string exp_zone_name = tran.getReverseDomain()->getName();
+ std::string exp_rev_addr = D2CfgMgr::reverseIpAddress(ncr->getIpAddress());
+ const dns::RRType& exp_ip_rr_type = tran.getAddressRRType();
+
+ // Verify the zone section.
+ checkZone(request, exp_zone_name);
+
+ // Verify there are no RRs in the PREREQUISITE Section.
+ checkRRCount(request, D2UpdateMessage::SECTION_PREREQUISITE, 0);
+
+ // Verify there is 2 RRs in the UPDATE Section.
+ checkRRCount(request, D2UpdateMessage::SECTION_UPDATE, 2);
+
+ // Verify the FQDN delete RR.
+ dns::RRsetPtr rrset;
+ ASSERT_TRUE(rrset = getRRFromSection(request, D2UpdateMessage::
+ SECTION_UPDATE, 0));
+ checkRR(rrset, exp_rev_addr, dns::RRClass::ANY(), dns::RRType::PTR(), 0, ncr);
+
+ // Verify the DHCID delete RR.
+ ASSERT_TRUE(rrset = getRRFromSection(request, D2UpdateMessage::
+ SECTION_UPDATE, 1));
+ checkRR(rrset, exp_rev_addr, dns::RRClass::ANY(), dns::RRType::DHCID(), 0, ncr);
+
+ // Verify that it will render toWire without throwing.
+ dns::MessageRenderer renderer;
+ ASSERT_NO_THROW(request->toWire(renderer));
+}
+
void checkContext(NameChangeTransactionPtr trans, const int exp_state,
const int exp_evt, const std::string& file, int line) {
ASSERT_TRUE(trans);
/// @param tran Transaction containing the request to be verified.
extern void checkSimpleRemoveFwdRRsRequest(NameChangeTransaction& tran);
+/// @brief Verifies a simple reverse RR removal DNS update request
+///
+/// Tests that the DNS Update request for a given transaction, is correct for
+/// removing reverse RR DNS entries when not using conflict resolution.
+///
+/// @param tran Transaction containing the request to be verified.
+extern void checkSimpleRemoveRevPtrsRequest(NameChangeTransaction& tran);
+
/// @brief Creates a NameChangeRequest from JSON string.
///
/// @param ncr_str string of JSON text from which to make the request.
SimpleRemoveStubPtr name_remove;
ASSERT_NO_THROW(name_remove = makeTransaction4(REVERSE_CHG));
ASSERT_NO_THROW(name_remove->buildRemoveRevPtrsRequest());
- checkRemoveRevPtrsRequest(*name_remove);
+ checkSimpleRemoveRevPtrsRequest(*name_remove);
// Create a IPv6 reverse replace transaction.
// Verify the request builds without error.
// and then verify the request contents.
ASSERT_NO_THROW(name_remove = makeTransaction6(REVERSE_CHG));
ASSERT_NO_THROW(name_remove->buildRemoveRevPtrsRequest());
- checkRemoveRevPtrsRequest(*name_remove);
+ checkSimpleRemoveRevPtrsRequest(*name_remove);
}
// Tests the readyHandler functionality.
EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
// Verify that an update message was constructed properly.
- checkRemoveRevPtrsRequest(*name_remove);
+ checkSimpleRemoveRevPtrsRequest(*name_remove);
// Verify that we are still in this state and next event is NOP_EVT.
// This indicates we "sent" the message and are waiting for IO completion.
EXPECT_NO_THROW(name_remove->removingRevPtrsHandler());
// Verify that an update message was constructed properly.
- checkRemoveRevPtrsRequest(*name_remove);
+ checkSimpleRemoveRevPtrsRequest(*name_remove);
// Verify that we are still in this state and next event is NOP_EVT.
// This indicates we "sent" the message and are waiting for IO completion.