nc_remove.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. // Copyright (C) 2013-2015,2017 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. #ifndef NC_REMOVE_H
  7. #define NC_REMOVE_H
  8. /// @file nc_remove.h This file defines the class NameRemoveTransaction.
  9. #include <d2/nc_trans.h>
  10. namespace isc {
  11. namespace d2 {
  12. /// @brief Thrown if the NameRemoveTransaction encounters a general error.
  13. class NameRemoveTransactionError : public isc::Exception {
  14. public:
  15. NameRemoveTransactionError(const char* file, size_t line,
  16. const char* what) :
  17. isc::Exception(file, line, what) { };
  18. };
  19. /// @brief Embodies the "life-cycle" required to carry out a DDNS Remove update.
  20. ///
  21. /// NameRemoveTransaction implements a state machine for removing a forward
  22. /// and/or reverse DNS mappings. This state machine is based upon the processing
  23. /// logic described in RFC 4703, Section 5.5. That logic may be paraphrased as
  24. /// follows:
  25. ///
  26. /// @code
  27. ///
  28. /// If the request includes a forward change:
  29. /// Select a forward server
  30. /// Send the server a request to remove client's specific forward address RR
  31. /// If it succeeds or the server responds with name no longer in use
  32. /// Send a server a request to delete any other RRs for that FQDN, such
  33. /// as the DHCID RR.
  34. /// otherwise
  35. /// abandon the update
  36. ///
  37. /// If the request includes a reverse change:
  38. /// Select a reverse server
  39. /// Send a server a request to delete reverse entry (PTR RR)
  40. ///
  41. /// @endcode
  42. ///
  43. /// This class derives from NameChangeTransaction from which it inherits
  44. /// states, events, and methods common to NameChangeRequest processing.
  45. class NameRemoveTransaction : public NameChangeTransaction {
  46. public:
  47. //@{ Additional states needed for NameRemove state model.
  48. /// @brief State that attempts to remove specific forward address record.
  49. static const int REMOVING_FWD_ADDRS_ST = NCT_DERIVED_STATE_MIN + 1;
  50. /// @brief State that attempts to remove any other forward RRs for the DHCID
  51. static const int REMOVING_FWD_RRS_ST = NCT_DERIVED_STATE_MIN + 2;
  52. /// @brief State that attempts to remove reverse PTR records
  53. static const int REMOVING_REV_PTRS_ST = NCT_DERIVED_STATE_MIN + 3;
  54. //@}
  55. //@{ Additional events needed for NameRemove state model.
  56. /// @brief Event sent when replace attempt to fails with address not in use.
  57. /// @todo Currently none have been identified.
  58. //@}
  59. /// @brief Constructor
  60. ///
  61. /// Instantiates an Remove transaction that is ready to be started.
  62. ///
  63. /// @param io_service IO service to be used for IO processing
  64. /// @param ncr is the NameChangeRequest to fulfill
  65. /// @param forward_domain is the domain to use for forward DNS updates
  66. /// @param reverse_domain is the domain to use for reverse DNS updates
  67. /// @param cfg_mgr pointer to the configuration manager
  68. ///
  69. /// @throw NameRemoveTransaction error if given request is not a CHG_REMOVE,
  70. /// NameChangeTransaction error for base class construction errors.
  71. NameRemoveTransaction(asiolink::IOServicePtr& io_service,
  72. dhcp_ddns::NameChangeRequestPtr& ncr,
  73. DdnsDomainPtr& forward_domain,
  74. DdnsDomainPtr& reverse_domain,
  75. D2CfgMgrPtr& cfg_mgr);
  76. /// @brief Destructor
  77. virtual ~NameRemoveTransaction();
  78. protected:
  79. /// @brief Adds events defined by NameRemoveTransaction to the event set.
  80. ///
  81. /// Invokes NameChangeTransaction's implementation and then defines the
  82. /// events unique to NCR Remove transaction processing.
  83. ///
  84. /// @throw StateModelError if an event definition is invalid or a duplicate.
  85. virtual void defineEvents();
  86. /// @brief Validates the contents of the set of events.
  87. ///
  88. /// Invokes NameChangeTransaction's implementation and then verifies the
  89. /// Remove transaction's events. This tests that the needed events are in
  90. /// the event dictionary.
  91. ///
  92. /// @throw StateModelError if an event value is undefined.
  93. virtual void verifyEvents();
  94. /// @brief Adds states defined by NameRemoveTransaction to the state set.
  95. ///
  96. /// Invokes NameChangeTransaction's implementation and then defines the
  97. /// states unique to NCR Remove transaction processing.
  98. ///
  99. /// @throw StateModelError if an state definition is invalid or a duplicate.
  100. virtual void defineStates();
  101. /// @brief Validates the contents of the set of states.
  102. ///
  103. /// Invokes NameChangeTransaction's implementation and then verifies the
  104. /// Remove transaction's states. This tests that the needed states are in
  105. /// the state dictionary.
  106. ///
  107. /// @throw StateModelError if an event value is undefined.
  108. virtual void verifyStates();
  109. /// @brief State handler for READY_ST.
  110. ///
  111. /// Entered from:
  112. /// - INIT_ST with next event of START_EVT
  113. ///
  114. /// The READY_ST is the state the model transitions into when the inherited
  115. /// method, startTransaction() is invoked. This handler, therefore, is the
  116. /// entry point into the state model execution. Its primary task is to
  117. /// determine whether to start with a forward DNS change or a reverse DNS
  118. /// change.
  119. ///
  120. /// Transitions to:
  121. /// - SELECTING_FWD_SERVER_ST with next event of SERVER_SELECT_ST if request
  122. /// includes a forward change.
  123. ///
  124. /// - SELECTING_REV_SERVER_ST with next event of SERVER_SELECT_ST if request
  125. /// includes only a reverse change.
  126. ///
  127. /// @throw NameRemoveTransactionError if upon entry next event is not
  128. /// START_EVT.
  129. void readyHandler();
  130. /// @brief State handler for SELECTING_FWD_SERVER_ST.
  131. ///
  132. /// Entered from:
  133. /// - READY_ST with next event of SELECT_SERVER_EVT
  134. /// - REMOVING_FWD_ADDRS_ST with next event of SERVER_IO_ERROR_EVT
  135. ///
  136. /// Selects the server to be used from the forward domain for the forward
  137. /// DNS update. If next event is SELECT_SERVER_EVT the handler initializes
  138. /// the forward domain's server selection mechanism and then attempts to
  139. /// select the next server. If next event is SERVER_IO_ERROR_EVT then the
  140. /// handler simply attempts to select the next server.
  141. ///
  142. /// Transitions to:
  143. /// - REMOVING_FWD_ADDRS_ST with next event of SERVER_SELECTED upon
  144. /// successful server selection
  145. ///
  146. /// - PROCESS_TRANS_FAILED with next event of NO_MORE_SERVERS_EVT upon
  147. /// failure to select a server
  148. ///
  149. /// @throw NameRemoveTransactionError if upon entry next event is not
  150. /// SELECT_SERVER_EVT or SERVER_IO_ERROR_EVT.
  151. void selectingFwdServerHandler();
  152. /// @brief State handler for SELECTING_REV_SERVER_ST.
  153. ///
  154. /// Entered from:
  155. /// - READY_ST with next event of SELECT_SERVER_EVT
  156. /// - REMOVING_FWD_RRS_ST with next event of SELECT_SERVER_EVT
  157. /// - REMOVING_REV_PTRS_ST with next event of SERVER_IO_ERROR_EVT
  158. ///
  159. /// Selects the server to be used from the reverse domain for the reverse
  160. /// DNS update. If next event is SELECT_SERVER_EVT the handler initializes
  161. /// the reverse domain's server selection mechanism and then attempts to
  162. /// select the next server. If next event is SERVER_IO_ERROR_EVT then the
  163. /// handler simply attempts to select the next server.
  164. ///
  165. /// Transitions to:
  166. /// - REMOVING_REV_PTRS_ST with next event of SERVER_SELECTED upon
  167. /// successful server selection
  168. ///
  169. /// - PROCESS_TRANS_FAILED with next event of NO_MORE_SERVERS_EVT upon
  170. /// failure to select a server
  171. ///
  172. /// @throw NameRemoveTransactionError if upon entry next event is not
  173. /// SELECT_SERVER_EVT or SERVER_IO_ERROR_EVT.
  174. void selectingRevServerHandler();
  175. /// @brief State handler for REMOVING_FWD_ADDRS_ST.
  176. ///
  177. /// Entered from:
  178. /// - SELECTING_FWD_SERVER with next event of SERVER_SELECTED_EVT
  179. ///
  180. /// Attempts to remove the forward DNS entry for a given FQDN, provided
  181. /// a DHCID RR exists which matches the requesting DHCID. If this is
  182. /// first invocation of the handler after transitioning into this state,
  183. /// any previous update request context is deleted. If next event
  184. /// is SERVER_SELECTED_EVT, the handler builds the forward remove request,
  185. /// schedules an asynchronous send via sendUpdate(), and returns. Note
  186. /// that sendUpdate will post NOP_EVT as next event.
  187. ///
  188. /// Posting the NOP_EVT will cause runModel() to suspend execution of
  189. /// the state model thus affecting a "wait" for the update IO to complete.
  190. /// Update completion occurs via the DNSClient callback operator() method
  191. /// inherited from NameChangeTransaction. When invoked this callback will
  192. /// post a next event of IO_COMPLETED_EVT and then invoke runModel which
  193. /// resumes execution of the state model.
  194. ///
  195. /// When the handler is invoked with a next event of IO_COMPLETED_EVT,
  196. /// the DNS update status is checked and acted upon accordingly:
  197. ///
  198. /// Transitions to:
  199. /// - REMOVING_FWD_RRS_ST with next event of UPDATE_OK_EVT upon successful
  200. /// removal or RCODE of indication FQDN is no longer in use (NXDOMAIN).
  201. ///
  202. /// - PROCESS_TRANS_FAILED_ST with next event of UPDATE_FAILED_EVT if the
  203. /// DNS server rejected the update for any reason or the IO completed
  204. /// with an unrecognized status.
  205. ///
  206. /// - RE-ENTER this state with next event of SERVER_SELECTED_EVT if
  207. /// there was an IO error communicating with the server and the number of
  208. /// per server retries has not been exhausted.
  209. ///
  210. /// - SELECTING_FWD_SERVER_ST with next event of SERVER_IO_ERROR_EVT if
  211. /// there was an IO error communicating with the server and the number of
  212. /// per server retries has been exhausted.
  213. ///
  214. /// @throw NameRemoveTransactionError if upon entry next event is not
  215. /// SERVER_SELECTED_EVT or IO_COMPLETE_EVT
  216. void removingFwdAddrsHandler();
  217. /// @brief State handler for REMOVING_FWD_RRS_ST.
  218. ///
  219. /// Entered from:
  220. /// - REMOVING_FWD_ADDRS_ST with next event of UPDATE_OK_EVT
  221. ///
  222. /// Attempts to delete any remaining RRs associated with the given FQDN
  223. /// such as the DHCID RR. If this is first invocation of the handler after
  224. /// transitioning into this state, any previous update request context is
  225. /// deleted and the handler builds the forward remove request. It then
  226. /// schedules an asynchronous send via sendUpdate(),
  227. /// and returns. Note that sendUpdate will post NOP_EVT as the next event.
  228. ///
  229. /// Posting the NOP_EVT will cause runModel() to suspend execution of
  230. /// the state model thus affecting a "wait" for the update IO to complete.
  231. /// Update completion occurs via the DNSClient callback operator() method
  232. /// inherited from NameChangeTransaction. When invoked this callback will
  233. /// post a next event of IO_COMPLETED_EVT and then invoke runModel which
  234. /// resumes execution of the state model.
  235. ///
  236. /// When the handler is invoked with a next event of IO_COMPLETED_EVT,
  237. /// the DNS update status is checked and acted upon accordingly:
  238. ///
  239. /// Transitions to:
  240. /// - SELECTING_REV_SERVER_ST with a next event of SELECT_SERVER_EVT upon
  241. /// successful completion and the request includes a reverse DNS update.
  242. ///
  243. /// - PROCESS_TRANS_OK_ST with next event of UPDATE_OK_EVT upon successful
  244. /// completion and the request does not include a reverse DNS update.
  245. ///
  246. /// - PROCESS_TRANS_FAILED_ST with a next event of UPDATE_FAILED_EVT if the
  247. /// DNS server rejected the update for any other reason or the IO completed
  248. /// with an unrecognized status.
  249. ///
  250. /// - RE-ENTER this state with a next event of SERVER_SELECTED_EVT if
  251. /// there was an IO error communicating with the server and the number of
  252. /// per server retries has not been exhausted.
  253. ///
  254. /// - PROCESS_TRANS_FAILED_ST with a next event of SERVER_IO_ERROR_EVT if
  255. /// there we have reached maximum number of retries without success on the
  256. /// current server.
  257. ///
  258. /// @note If we exhaust the IO retries for the current server due to IO
  259. /// failures, we will abort the remaining updates. The rational is that
  260. /// we are only in this state, if the remove of the forward address RR
  261. /// succeeded (removingFwdAddrsHandler) on the current server so we should
  262. /// not attempt another removal on a different server. This is perhaps a
  263. /// point for discussion. @todo Should we go ahead with the reverse remove?
  264. ///
  265. /// @throw NameRemoveTransactionError if upon entry next event is not:
  266. /// UPDATE_OK_EVT or IO_COMPLETE_EVT
  267. void removingFwdRRsHandler();
  268. /// @brief State handler for REMOVING_REV_PTRS_ST.
  269. ///
  270. /// Entered from:
  271. /// - SELECTING_REV_SERVER_ST with a next event of SERVER_SELECTED_EVT
  272. ///
  273. /// Attempts to delete a reverse DNS entry for a given FQDN. If this is
  274. /// first invocation of the handler after transitioning into this state,
  275. /// any previous update request context is deleted. If next event is
  276. /// SERVER_SELECTED_EVT, the handler builds the reverse remove request,
  277. /// schedules an asynchronous send via sendUpdate(), and then returns.
  278. /// Note that sendUpdate will post NOP_EVT as next event.
  279. ///
  280. /// Posting the NOP_EVT will cause runModel() to suspend execution of
  281. /// the state model thus affecting a "wait" for the update IO to complete.
  282. /// Update completion occurs via the DNSClient callback operator() method
  283. /// inherited from NameChangeTransaction. When invoked this callback will
  284. /// post a next event of IO_COMPLETED_EVT and then invoke runModel which
  285. /// resumes execution of the state model.
  286. ///
  287. /// When the handler is invoked with a next event of IO_COMPLETED_EVT,
  288. /// the DNS update status is checked and acted upon accordingly:
  289. ///
  290. /// Transitions to:
  291. /// - PROCESS_TRANS_OK_ST with a next event of UPDATE_OK_EVT upon
  292. /// successful completion.
  293. ///
  294. /// - PROCESS_TRANS_FAILED_ST with a next event of UPDATE_FAILED_EVT If the
  295. /// DNS server rejected the update for any reason or the IO completed
  296. /// with an unrecognized status.
  297. ///
  298. /// - RE-ENTER this state with a next event of SERVER_SELECTED_EVT if
  299. /// there was an IO error communicating with the server and the number of
  300. /// per server retries has not been exhausted.
  301. ///
  302. /// - SELECTING_REV_SERVER_ST with next event of SERVER_IO_ERROR_EVT if
  303. /// there was an IO error communicating with the server and the number of
  304. /// per server retries has been exhausted.
  305. ///
  306. /// @throw NameRemoveTransactionError if upon entry next event is not:
  307. /// SERVER_SELECTED_EVT or IO_COMPLETED_EVT
  308. void removingRevPtrsHandler();
  309. /// @brief State handler for PROCESS_TRANS_OK_ST.
  310. ///
  311. /// Entered from:
  312. /// - REMOVING_FWD_RRS_ST with a next event of UPDATE_OK_EVT
  313. /// - REMOVING_REV_PTRS_ST with a next event of UPDATE_OK_EVT
  314. ///
  315. /// Sets the transaction action status to indicate success and ends
  316. /// model execution.
  317. ///
  318. /// Transitions to:
  319. /// - END_ST with a next event of END_EVT.
  320. ///
  321. /// @throw NameRemoveTransactionError if upon entry next event is not:
  322. /// UPDATE_OK_EVT
  323. void processRemoveOkHandler();
  324. /// @brief State handler for PROCESS_TRANS_FAILED_ST.
  325. ///
  326. /// Entered from:
  327. /// - SELECTING_FWD_SERVER_ST with a next event of NO_MORE_SERVERS
  328. /// - REMOVING_FWD_ADDRS_ST with a next event of UPDATE_FAILED_EVT
  329. /// - REMOVING_FWD_RRS_ST with a next event of UPDATE_FAILED_EVT
  330. /// - REMOVING_FWD_RRS_ST with a next event of SERVER_IO_ERROR_EVT
  331. /// - SELECTING_REV_SERVER_ST with a next event of NO_MORE_SERVERS
  332. /// - REMOVING_REV_PTRS_ST with a next event of UPDATE_FAILED_EVT
  333. ///
  334. /// Sets the transaction status to indicate failure and ends
  335. /// model execution.
  336. ///
  337. /// Transitions to:
  338. /// - END_ST with a next event of FAIL_EVT.
  339. ///
  340. /// @throw NameRemoveTransactionError if upon entry next event is not:
  341. /// UPDATE_FAILED_EVT
  342. void processRemoveFailedHandler();
  343. /// @brief Builds a DNS request to remove a forward DNS address for a FQDN.
  344. ///
  345. /// Constructs a DNS update request, based upon the NCR, for removing a
  346. /// forward DNS address mapping. Once constructed, the request is stored as
  347. /// the transaction's DNS update request.
  348. ///
  349. /// The request content is adherent to RFC 4703 section 5.5, paragraph 4.
  350. ///
  351. /// Prerequisite RRsets:
  352. /// 1. An assertion that a matching DHCID RR exists
  353. ///
  354. /// Updates RRsets:
  355. /// 1. A delete of the FQDN/IP RR (type A for IPv4, AAAA for IPv6)
  356. ///
  357. /// @throw This method does not throw but underlying methods may.
  358. void buildRemoveFwdAddressRequest();
  359. /// @brief Builds a DNS request to remove all forward DNS RRs for a FQDN.
  360. ///
  361. /// Constructs a DNS update request, based upon the NCR, for removing any
  362. /// remaining forward DNS RRs, once all A or AAAA entries for the FQDN
  363. /// have been removed. Once constructed, the request is stored as the
  364. /// transaction's DNS update request.
  365. ///
  366. /// The request content is adherent to RFC 4703 section 5.5, paragraph 5.
  367. ///
  368. /// Prerequisite RRsets:
  369. /// 1. An assertion that a matching DHCID RR exists
  370. /// 2. An assertion that no A RRs for the FQDN exist
  371. /// 3. An assertion that no AAAA RRs for the FQDN exist
  372. ///
  373. /// Updates RRsets:
  374. /// 1. A delete of all RRs for the FQDN
  375. ///
  376. /// @throw This method does not throw but underlying methods may.
  377. void buildRemoveFwdRRsRequest();
  378. /// @brief Builds a DNS request to remove a reverse DNS entry for a FQDN
  379. ///
  380. /// Constructs a DNS update request, based upon the NCR, for removing a
  381. /// reverse DNS mapping. Once constructed, the request is stored as
  382. /// the transaction's DNS update request.
  383. ///
  384. /// The request content is adherent to RFC 4703 section 5.5, paragraph 2:
  385. ///
  386. /// Prerequisite RRsets:
  387. /// 1. An assertion that a PTR record matching the client's FQDN exists.
  388. ///
  389. /// Updates RRsets:
  390. /// 1. A delete of all RRs for the FQDN
  391. ///
  392. /// @throw This method does not throw but underlying methods may.
  393. void buildRemoveRevPtrsRequest();
  394. };
  395. /// @brief Defines a pointer to a NameRemoveTransaction.
  396. typedef boost::shared_ptr<NameRemoveTransaction> NameRemoveTransactionPtr;
  397. } // namespace isc::d2
  398. } // namespace isc
  399. #endif