Kea 2.7.1
simple_remove_without_dhcid.cc
Go to the documentation of this file.
1// Copyright (C) 2023-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6//
7#include <config.h>
8
10#include <d2srv/d2_cfg_mgr.h>
11#include <d2srv/d2_log.h>
12
13#include <functional>
14
15namespace isc {
16namespace d2 {
17
18
19// SimpleRemoveWithoutDHCIDTransaction states
22
23// SimpleRemoveWithoutDHCIDTransaction events
24// Currently SimpleRemoveWithoutDHCIDTransaction does not define any events.
25
29 DdnsDomainPtr& forward_domain,
30 DdnsDomainPtr& reverse_domain,
31 D2CfgMgrPtr& cfg_mgr)
32 : NameChangeTransaction(io_service, ncr, forward_domain, reverse_domain,
33 cfg_mgr) {
34 if (ncr->getChangeType() != isc::dhcp_ddns::CHG_REMOVE) {
36 "SimpleRemoveWithoutDHCIDTransaction, request type must be CHG_REMOVE");
37 }
38}
39
42
43void
45 // Call superclass impl first.
47
48 // Define SimpleRemoveWithoutDHCIDTransaction events.
49 // Currently SimpleRemoveWithoutDHCIDTransaction does not define any events.
50 // defineEvent(TBD_EVENT, "TBD_EVT");
51}
52
53void
55 // Call superclass implementation first to verify its events. These are
56 // events common to all transactions, and they must be defined.
57 // SELECT_SERVER_EVT
58 // SERVER_SELECTED_EVT
59 // SERVER_IO_ERROR_EVT
60 // NO_MORE_SERVERS_EVT
61 // IO_COMPLETED_EVT
62 // UPDATE_OK_EVT
63 // UPDATE_FAILED_EVT
65
66 // Verify SimpleRemoveWithoutDHCIDTransaction events by attempting to fetch them.
67 // Currently SimpleRemoveWithoutDHCIDTransaction does not define any events.
68 // getEvent(TBD_EVENT);
69}
70
71void
73 // Call superclass impl first.
75
76 // Define SimpleRemoveWithoutDHCIDTransaction states.
77 defineState(READY_ST, "READY_ST",
79
80 defineState(SELECTING_FWD_SERVER_ST, "SELECTING_FWD_SERVER_ST",
82 this));
83
84 defineState(SELECTING_REV_SERVER_ST, "SELECTING_REV_SERVER_ST",
86 this));
87
88 defineState(REMOVING_FWD_RRS_ST, "REMOVING_FWD_RRS_ST",
90 this));
91
92 defineState(REMOVING_REV_PTRS_ST, "REMOVING_REV_PTRS_ST",
94 this));
95
96 defineState(PROCESS_TRANS_OK_ST, "PROCESS_TRANS_OK_ST",
98 this));
99
100 defineState(PROCESS_TRANS_FAILED_ST, "PROCESS_TRANS_FAILED_ST",
102 this));
103}
104
105void
107 // Call superclass implementation first to verify its states. These are
108 // states common to all transactions, and they must be defined.
109 // READY_ST
110 // SELECTING_FWD_SERVER_ST
111 // SELECTING_REV_SERVER_ST
112 // PROCESS_TRANS_OK_ST
113 // PROCESS_TRANS_FAILED_ST
115
116 // Verify SimpleRemoveWithoutDHCIDTransaction states by attempting to fetch them.
119}
120
121void
123 switch(getNextEvent()) {
124 case START_EVT:
125 if (getForwardDomain()) {
126 // Request includes a forward change, do that first.
128 } else {
129 // Reverse change only, transition accordingly.
131 }
132
133 break;
134 default:
135 // Event is invalid.
137 "Wrong event for context: " << getContextStr());
138 }
139}
140
141void
143 switch(getNextEvent()) {
145 // First time through for this transaction, so initialize server
146 // selection.
148 break;
150 // We failed to communicate with current server. Attempt to select
151 // another one below.
152 break;
153 default:
154 // Event is invalid.
156 "Wrong event for context: " << getContextStr());
157 }
158
159 // Select the next server from the list of forward servers.
160 if (selectNextServer()) {
161 // We have a server to try.
163 }
164 else {
165 // Server list is exhausted, so fail the transaction.
167 }
168}
169
170void
172 if (doOnEntry()) {
173 // Clear the update attempts count on initial transition.
175 }
176
177 switch(getNextEvent()) {
178 case UPDATE_OK_EVT:
180 try {
183 } catch (const std::exception& ex) {
184 // While unlikely, the build might fail if we have invalid
185 // data. Should that be the case, we need to fail the
186 // transaction.
189 .arg(getRequestId())
190 .arg(getNcr()->toText())
191 .arg(ex.what());
193 break;
194 }
195
196 // Call sendUpdate() to initiate the async send. Note it also sets
197 // next event to NOP_EVT.
198 sendUpdate("Forward RR Remove");
199 break;
200
201 case IO_COMPLETED_EVT: {
202 switch (getDnsUpdateStatus()) {
203 case DNSClient::SUCCESS: {
204 // We successfully received a response packet from the server.
205 // The RCODE will be based on a value-dependent RRset search,
206 // see RFC 2136 section 3.2.3/3.2.4.
207 const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
208 if ((rcode == dns::Rcode::NOERROR()) ||
209 (rcode == dns::Rcode::NXRRSET())) {
210 // We were able to remove them or they were not there (
211 // Rcode of NXRRSET means there are no matching RRsets).
212 // In either case, we consider it success and mark it as done.
214
215 // If request calls for reverse update then do that next,
216 // otherwise we can process ok.
217 if (getReverseDomain()) {
219 } else {
221 }
222 } else {
223 // Any other value means cease.
224 // If we get not authorized should try the next server in
225 // the list? @todo This needs some discussion perhaps.
227 .arg(getRequestId())
228 .arg(getCurrentServer()->toText())
229 .arg(getNcr()->getFqdn())
230 .arg(rcode.getCode());
232 }
233
234 break;
235 }
236
238 // No response from the server, log it and set up
239 // to select the next server for a retry.
241 .arg(getRequestId())
242 .arg(getNcr()->getFqdn())
243 .arg(getCurrentServer()->toText());
244
246 break;
247
248 case DNSClient::OTHER:
249 // We couldn't send to the current server, log it and set up
250 // to select the next server for a retry.
252 .arg(getRequestId())
253 .arg(getNcr()->getFqdn())
254 .arg(getCurrentServer()->toText());
255
257 break;
258
260 // A response was received but was corrupt. Retry it like an IO
261 // error.
263 .arg(getRequestId())
264 .arg(getCurrentServer()->toText())
265 .arg(getNcr()->getFqdn());
266
268 break;
269
270 default:
271 // Any other value and we will fail this transaction, something
272 // bigger is wrong.
275 .arg(getRequestId())
276 .arg(getDnsUpdateStatus())
277 .arg(getNcr()->getFqdn())
278 .arg(getCurrentServer()->toText());
279
281 break;
282 } // end switch on dns_status
283
284 break;
285 } // end case IO_COMPLETE_EVT
286
287 default:
288 // Event is invalid.
290 "Wrong event for context: " << getContextStr());
291 }
292}
293
294
295void
297 switch(getNextEvent()) {
299 // First time through for this transaction, so initialize server
300 // selection.
302 break;
304 // We failed to communicate with current server. Attempt to select
305 // another one below.
306 break;
307 default:
308 // Event is invalid.
310 "Wrong event for context: " << getContextStr());
311 }
312
313 // Select the next server from the list of forward servers.
314 if (selectNextServer()) {
315 // We have a server to try.
317 }
318 else {
319 // Server list is exhausted, so fail the transaction.
321 }
322}
323
324
325void
327 if (doOnEntry()) {
328 // Clear the update attempts count on initial transition.
330 }
331
332 switch(getNextEvent()) {
334 try {
337 } catch (const std::exception& ex) {
338 // While unlikely, the build might fail if we have invalid
339 // data. Should that be the case, we need to fail the
340 // transaction.
342 .arg(getRequestId())
343 .arg(getNcr()->toText())
344 .arg(ex.what());
346 break;
347 }
348
349 // Call sendUpdate() to initiate the async send. Note it also sets
350 // next event to NOP_EVT.
351 sendUpdate("Reverse Remove");
352 break;
353
354 case IO_COMPLETED_EVT: {
355 switch (getDnsUpdateStatus()) {
356 case DNSClient::SUCCESS: {
357 // We successfully received a response packet from the server.
358 // The RCODE will be based on a value-dependent RRset search,
359 // see RFC 2136 section 3.2.3/3.2.4.
360 const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
361 if ((rcode == dns::Rcode::NOERROR()) ||
362 (rcode == dns::Rcode::NXRRSET())) {
363 // We were able to remove the reverse mapping or they were
364 // not there (Rcode of NXRRSET means there are no matching
365 // RRsets). In either case, mark it as done.
368 } else {
369 // Per RFC4703 any other value means cease.
370 // If we get not authorized should try the next server in
371 // the list? @todo This needs some discussion perhaps.
373 .arg(getRequestId())
374 .arg(getCurrentServer()->toText())
375 .arg(getNcr()->getFqdn())
376 .arg(rcode.getCode());
378 }
379
380 break;
381 }
382
384 // No response from the server, log it and set up
385 // to select the next server for a retry.
387 .arg(getRequestId())
388 .arg(getNcr()->getFqdn())
389 .arg(getCurrentServer()->toText());
390
391 // If we are out of retries on this server, we go back and start
392 // all over on a new server.
394 break;
395
396 case DNSClient::OTHER:
397 // We couldn't send to the current server, log it and set up
398 // to select the next server for a retry.
400 .arg(getRequestId())
401 .arg(getNcr()->getFqdn())
402 .arg(getCurrentServer()->toText());
403
404 // If we are out of retries on this server, we go back and start
405 // all over on a new server.
407 break;
408
410 // A response was received but was corrupt. Retry it like an IO
411 // error.
413 .arg(getRequestId())
414 .arg(getCurrentServer()->toText())
415 .arg(getNcr()->getFqdn());
416
417 // If we are out of retries on this server, we go back and start
418 // all over on a new server.
420 break;
421
422 default:
423 // Any other value and we will fail this transaction, something
424 // bigger is wrong.
427 .arg(getRequestId())
428 .arg(getDnsUpdateStatus())
429 .arg(getNcr()->getFqdn())
430 .arg(getCurrentServer()->toText());
431
433 break;
434 } // end switch on dns_status
435
436 break;
437 } // end case IO_COMPLETE_EVT
438
439 default:
440 // Event is invalid.
442 "Wrong event for context: " << getContextStr());
443 }
444}
445
446
447void
449 switch(getNextEvent()) {
450 case UPDATE_OK_EVT:
452 .arg(getRequestId())
453 .arg(getNcr()->toText());
455 endModel();
456 break;
457 default:
458 // Event is invalid.
460 "Wrong event for context: " << getContextStr());
461 }
462}
463
464void
466 switch(getNextEvent()) {
472 .arg(getRequestId())
474 endModel();
475 break;
476 default:
477 // Event is invalid.
479 "Wrong event for context: " << getContextStr());
480 }
481}
482
483void
485 // Construct an empty request.
487
488 // There are no pre-requisites.
489
490 // Build the Update Section
491 // Construct dns::Name from NCR fqdn.
492 dns::Name fqdn(dns::Name(getNcr()->getFqdn()));
493
494 // Build the Update Section.
495
496 // Create the FQDN/IP 'delete' RR and add it to update section.
497 dns::RRsetPtr update(new dns::RRset(fqdn, dns::RRClass::ANY(),
499
500 request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
501
502 // Set the transaction's update request to the new request.
503 setDnsUpdateRequest(request);
504}
505
506void
508 // Construct an empty request.
510
511 // Create the reverse IP address "FQDN".
512 std::string rev_addr = D2CfgMgr::reverseIpAddress(getNcr()->getIpAddress());
513 dns::Name rev_ip(rev_addr);
514
515 // There are no pre-requisites.
516
517 // Build the Update section.
518
519 // Create the FQDN/IP PTR 'delete' RR for this IP and add it to
520 // the update section.
521 dns::RRsetPtr update(new dns::RRset(rev_ip, dns::RRClass::ANY(),
523 request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
524
525 // Set the transaction's update request to the new request.
526 setDnsUpdateRequest(request);
527}
528
529} // namespace isc::d2
530} // namespace isc
static std::string reverseIpAddress(const std::string &address)
Generate a reverse order string for the given IP address.
@ TIMEOUT
No response, timeout.
Definition dns_client.h:60
@ OTHER
Other, unclassified error.
Definition dns_client.h:63
@ INVALID_RESPONSE
Response received but invalid.
Definition dns_client.h:62
@ SUCCESS
Response received and is ok.
Definition dns_client.h:59
Embodies the "life-cycle" required to carry out a DDNS update.
Definition nc_trans.h:77
static const int SELECTING_FWD_SERVER_ST
State in which forward DNS server selection is done.
Definition nc_trans.h:91
void retryTransition(const int fail_to_state)
Determines the state and next event based on update attempts.
Definition nc_trans.cc:287
static const int PROCESS_TRANS_FAILED_ST
State which processes an unsuccessful transaction conclusion.
Definition nc_trans.h:105
static const int READY_ST
State from which a transaction is started.
Definition nc_trans.h:83
const D2UpdateMessagePtr & getDnsUpdateResponse() const
Fetches the most recent DNS update response packet.
Definition nc_trans.cc:554
static const int PROCESS_TRANS_OK_ST
State which processes successful transaction conclusion.
Definition nc_trans.h:102
static const int UPDATE_OK_EVT
Issued when the attempted update successfully completed.
Definition nc_trans.h:135
virtual void verifyStates()
Validates the contents of the set of states.
Definition nc_trans.cc:266
virtual D2UpdateMessagePtr prepNewRequest(DdnsDomainPtr domain)
Creates a new DNS update request based on the given domain.
Definition nc_trans.cc:344
static const int UPDATE_FAILED_EVT
Issued when the attempted update fails to complete.
Definition nc_trans.h:141
const dns::RRType & getAddressRRType() const
Returns the DHCP data type for the lease address.
Definition nc_trans.cc:574
const dhcp_ddns::NameChangeRequestPtr & getNcr() const
Fetches the NameChangeRequest for this transaction.
Definition nc_trans.cc:426
void initServerSelection(const DdnsDomainPtr &domain)
Initializes server selection from the given DDNS domain.
Definition nc_trans.cc:456
static const int IO_COMPLETED_EVT
Issued when a DNS update packet exchange has completed.
Definition nc_trans.h:130
static const int SELECT_SERVER_EVT
Issued when a server needs to be selected.
Definition nc_trans.h:113
static const int SERVER_IO_ERROR_EVT
Issued when an update fails due to an IO error.
Definition nc_trans.h:119
std::string getRequestId() const
Fetches the request id that identifies this transaction.
Definition nc_trans.cc:436
virtual void defineStates()
Adds states defined by NameChangeTransaction to the state set.
Definition nc_trans.cc:258
virtual void sendUpdate(const std::string &comment="")
Send the update request to the current server.
Definition nc_trans.cc:193
void setForwardChangeCompleted(const bool value)
Sets the forward change completion flag to the given value.
Definition nc_trans.cc:329
bool selectNextServer()
Selects the next server in the current server list.
Definition nc_trans.cc:468
void setNcrStatus(const dhcp_ddns::NameChangeStatus &status)
Sets the status of the transaction's NameChangeRequest.
Definition nc_trans.cc:539
DdnsDomainPtr & getForwardDomain()
Fetches the forward DdnsDomain.
Definition nc_trans.cc:446
virtual void verifyEvents()
Validates the contents of the set of events.
Definition nc_trans.cc:243
void clearDnsUpdateRequest()
Destroys the current update request packet.
Definition nc_trans.cc:304
void clearUpdateAttempts()
Resets the update attempts count.
Definition nc_trans.cc:309
static const int SELECTING_REV_SERVER_ST
State in which reverse DNS server selection is done.
Definition nc_trans.h:99
DNSClient::Status getDnsUpdateStatus() const
Fetches the most recent DNS update status.
Definition nc_trans.cc:549
void setDnsUpdateRequest(D2UpdateMessagePtr &request)
Sets the update request packet to the given packet.
Definition nc_trans.cc:299
static const int NO_MORE_SERVERS_EVT
Issued when there are no more servers from which to select.
Definition nc_trans.h:125
virtual void defineEvents()
Adds events defined by NameChangeTransaction to the event set.
Definition nc_trans.cc:228
void setReverseChangeCompleted(const bool value)
Sets the reverse change completion flag to the given value.
Definition nc_trans.cc:334
const DnsServerInfoPtr & getCurrentServer() const
Fetches the currently selected server.
Definition nc_trans.cc:534
static const int SERVER_SELECTED_EVT
Issued when a server has been selected.
Definition nc_trans.h:116
DdnsDomainPtr & getReverseDomain()
Fetches the reverse DdnsDomain.
Definition nc_trans.cc:451
std::string transactionOutcomeString() const
Returns a string version of transaction outcome.
Definition nc_trans.cc:171
Thrown if the SimpleRemoveWithoutDHCIDTransaction encounters a general error.
void processRemoveOkHandler()
State handler for PROCESS_TRANS_OK_ST.
static const int REMOVING_FWD_RRS_ST
State that attempts to remove FQDN/IP RR for an FQDN.
void removingFwdRRsHandler()
State handler for REMOVING_FWD_RRS_ST.
virtual void verifyEvents()
Validates the contents of the set of events.
static const int REMOVING_REV_PTRS_ST
State that attempts to remove reverse PTR records.
void selectingRevServerHandler()
State handler for SELECTING_REV_SERVER_ST.
virtual void defineEvents()
Adds events defined by SimpleRemoveWithoutDHCIDTransaction to the event set.
void processRemoveFailedHandler()
State handler for PROCESS_TRANS_FAILED_ST.
void buildRemoveRevPtrsRequest()
Builds a DNS request to remove a reverse DNS entry for a FQDN.
void buildRemoveFwdRRsRequest()
Builds a DNS request to remove forward DNS RR for a FQDN.
void selectingFwdServerHandler()
State handler for SELECTING_FWD_SERVER_ST.
virtual void verifyStates()
Validates the contents of the set of states.
virtual void defineStates()
Adds states defined by SimpleRemoveWithoutDHCIDTransaction to the state set.
void removingRevPtrsHandler()
State handler for REMOVING_REV_PTRS_ST.
SimpleRemoveWithoutDHCIDTransaction(asiolink::IOServicePtr &io_service, dhcp_ddns::NameChangeRequestPtr &ncr, DdnsDomainPtr &forward_domain, DdnsDomainPtr &reverse_domain, D2CfgMgrPtr &cfg_mgr)
Event sent when replace attempt to fails with address not in use.
The Name class encapsulates DNS names.
Definition name.h:219
static const RRClass & ANY()
Definition rrclass.h:298
The RRTTL class encapsulates TTLs used in DNS resource records.
Definition rrttl.h:51
static const RRType & PTR()
Definition rrtype.h:303
The RRset class is a concrete derived class of BasicRRset which contains a pointer to an additional R...
Definition rrset.h:844
DNS Response Codes (RCODEs) class.
Definition rcode.h:40
static const Rcode & NOERROR()
A constant object for the NOERROR Rcode (see Rcode::NOERROR_CODE).
Definition rcode.h:228
static const Rcode & NXRRSET()
A constant object for the NXRRSET Rcode (see Rcode::NXRRSET_CODE).
Definition rcode.h:276
void endModel()
Conducts a normal transition to the end of the model.
void defineState(unsigned int value, const std::string &label, StateHandler handler, const StatePausing &state_pausing=STATE_PAUSE_NEVER)
Adds an state value and associated label to the set of states.
unsigned int getNextEvent() const
Fetches the model's next event.
void transition(unsigned int state, unsigned int event)
Sets up the model to transition into given state with a given event.
bool doOnEntry()
Checks if on entry flag is true.
static const int START_EVT
Event issued to start the model execution.
const StatePtr getStateInternal(unsigned int value)
Fetches the state referred to by value.
std::string getContextStr() const
Convenience method which returns a string rendition of the current state and next event.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
boost::shared_ptr< D2UpdateMessage > D2UpdateMessagePtr
Pointer to the DNS Update Message.
boost::shared_ptr< DdnsDomain > DdnsDomainPtr
Defines a pointer for DdnsDomain instances.
Definition d2_config.h:622
const isc::log::MessageID DHCP_DDNS_FORWARD_REMOVE_RRS_TIMEOUT
Definition d2_messages.h:38
const isc::log::MessageID DHCP_DDNS_REVERSE_REMOVE_RESP_CORRUPT
Definition d2_messages.h:74
boost::shared_ptr< D2CfgMgr > D2CfgMgrPtr
Defines a shared pointer to D2CfgMgr.
Definition d2_cfg_mgr.h:334
const isc::log::MessageID DHCP_DDNS_FORWARD_REMOVE_RRS_RESP_CORRUPT
Definition d2_messages.h:37
const isc::log::MessageID DHCP_DDNS_FORWARD_REMOVE_RRS_REJECTED
Definition d2_messages.h:36
const isc::log::MessageID DHCP_DDNS_REMOVE_SUCCEEDED
Definition d2_messages.h:68
isc::log::Logger d2_to_dns_logger("d2-to-dns")
Definition d2_log.h:20
const isc::log::MessageID DHCP_DDNS_FORWARD_REMOVE_RRS_BUILD_FAILURE
Definition d2_messages.h:34
const isc::log::MessageID DHCP_DDNS_REVERSE_REMOVE_TIMEOUT
Definition d2_messages.h:75
const isc::log::MessageID DHCP_DDNS_FORWARD_REMOVE_RRS_BAD_DNSCLIENT_STATUS
Definition d2_messages.h:33
const isc::log::MessageID DHCP_DDNS_REVERSE_REMOVE_IO_ERROR
Definition d2_messages.h:72
const isc::log::MessageID DHCP_DDNS_REVERSE_REMOVE_BAD_DNSCLIENT_STATUS
Definition d2_messages.h:70
const isc::log::MessageID DHCP_DDNS_REVERSE_REMOVE_BUILD_FAILURE
Definition d2_messages.h:71
const isc::log::MessageID DHCP_DDNS_REMOVE_FAILED
Definition d2_messages.h:67
const isc::log::MessageID DHCP_DDNS_FORWARD_REMOVE_RRS_IO_ERROR
Definition d2_messages.h:35
const isc::log::MessageID DHCP_DDNS_REVERSE_REMOVE_REJECTED
Definition d2_messages.h:73
boost::shared_ptr< NameChangeRequest > NameChangeRequestPtr
Defines a pointer to a NameChangeRequest.
Definition ncr_msg.h:241
boost::shared_ptr< AbstractRRset > RRsetPtr
A pointer-like type pointing to an RRset object.
Definition rrset.h:50
Defines the logger used by the top-level component of kea-lfc.
This file defines the class SimpleRemoveWithoutDHCIDTransaction.