nc_remove.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. // Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <d2/d2_log.h>
  15. #include <d2/d2_cfg_mgr.h>
  16. #include <d2/nc_remove.h>
  17. #include <boost/function.hpp>
  18. #include <boost/bind.hpp>
  19. namespace isc {
  20. namespace d2 {
  21. // NameRemoveTransaction states
  22. const int NameRemoveTransaction::REMOVING_FWD_ADDRS_ST;
  23. const int NameRemoveTransaction::REMOVING_FWD_RRS_ST;
  24. const int NameRemoveTransaction::REMOVING_REV_PTRS_ST;
  25. // NameRemoveTransaction events
  26. // Currently NameRemoveTransaction does not define any events.
  27. NameRemoveTransaction::
  28. NameRemoveTransaction(asiolink::IOServicePtr& io_service,
  29. dhcp_ddns::NameChangeRequestPtr& ncr,
  30. DdnsDomainPtr& forward_domain,
  31. DdnsDomainPtr& reverse_domain,
  32. D2CfgMgrPtr& cfg_mgr)
  33. : NameChangeTransaction(io_service, ncr, forward_domain, reverse_domain,
  34. cfg_mgr) {
  35. if (ncr->getChangeType() != isc::dhcp_ddns::CHG_REMOVE) {
  36. isc_throw (NameRemoveTransactionError,
  37. "NameRemoveTransaction, request type must be CHG_REMOVE");
  38. }
  39. }
  40. NameRemoveTransaction::~NameRemoveTransaction(){
  41. }
  42. void
  43. NameRemoveTransaction::defineEvents() {
  44. // Call superclass impl first.
  45. NameChangeTransaction::defineEvents();
  46. // Define NameRemoveTransaction events.
  47. // Currently NameRemoveTransaction does not define any events.
  48. // defineEvent(TBD_EVENT, "TBD_EVT");
  49. }
  50. void
  51. NameRemoveTransaction::verifyEvents() {
  52. // Call superclass implementation first to verify its events. These are
  53. // events common to all transactions, and they must be defined.
  54. // SELECT_SERVER_EVT
  55. // SERVER_SELECTED_EVT
  56. // SERVER_IO_ERROR_EVT
  57. // NO_MORE_SERVERS_EVT
  58. // IO_COMPLETED_EVT
  59. // UPDATE_OK_EVT
  60. // UPDATE_FAILED_EVT
  61. NameChangeTransaction::verifyEvents();
  62. // Verify NameRemoveTransaction events by attempting to fetch them.
  63. // Currently NameRemoveTransaction does not define any events.
  64. // getEvent(TBD_EVENT);
  65. }
  66. void
  67. NameRemoveTransaction::defineStates() {
  68. // Call superclass impl first.
  69. NameChangeTransaction::defineStates();
  70. // Define NameRemoveTransaction states.
  71. defineState(READY_ST, "READY_ST",
  72. boost::bind(&NameRemoveTransaction::readyHandler, this));
  73. defineState(SELECTING_FWD_SERVER_ST, "SELECTING_FWD_SERVER_ST",
  74. boost::bind(&NameRemoveTransaction::selectingFwdServerHandler,
  75. this));
  76. defineState(SELECTING_REV_SERVER_ST, "SELECTING_REV_SERVER_ST",
  77. boost::bind(&NameRemoveTransaction::selectingRevServerHandler,
  78. this));
  79. defineState(REMOVING_FWD_ADDRS_ST, "REMOVING_FWD_ADDRS_ST",
  80. boost::bind(&NameRemoveTransaction::removingFwdAddrsHandler,
  81. this));
  82. defineState(REMOVING_FWD_RRS_ST, "REMOVING_FWD_RRS_ST",
  83. boost::bind(&NameRemoveTransaction::removingFwdRRsHandler,
  84. this));
  85. defineState(REMOVING_REV_PTRS_ST, "REMOVING_REV_PTRS_ST",
  86. boost::bind(&NameRemoveTransaction::removingRevPtrsHandler,
  87. this));
  88. defineState(PROCESS_TRANS_OK_ST, "PROCESS_TRANS_OK_ST",
  89. boost::bind(&NameRemoveTransaction::processRemoveOkHandler,
  90. this));
  91. defineState(PROCESS_TRANS_FAILED_ST, "PROCESS_TRANS_FAILED_ST",
  92. boost::bind(&NameRemoveTransaction::processRemoveFailedHandler,
  93. this));
  94. }
  95. void
  96. NameRemoveTransaction::verifyStates() {
  97. // Call superclass implementation first to verify its states. These are
  98. // states common to all transactions, and they must be defined.
  99. // READY_ST
  100. // SELECTING_FWD_SERVER_ST
  101. // SELECTING_REV_SERVER_ST
  102. // PROCESS_TRANS_OK_ST
  103. // PROCESS_TRANS_FAILED_ST
  104. NameChangeTransaction::verifyStates();
  105. // Verify NameRemoveTransaction states by attempting to fetch them.
  106. getState(REMOVING_FWD_ADDRS_ST);
  107. getState(REMOVING_FWD_RRS_ST);
  108. getState(REMOVING_REV_PTRS_ST);
  109. }
  110. void
  111. NameRemoveTransaction::readyHandler() {
  112. switch(getNextEvent()) {
  113. case START_EVT:
  114. if (getForwardDomain()) {
  115. // Request includes a forward change, do that first.
  116. transition(SELECTING_FWD_SERVER_ST, SELECT_SERVER_EVT);
  117. } else {
  118. // Reverse change only, transition accordingly.
  119. transition(SELECTING_REV_SERVER_ST, SELECT_SERVER_EVT);
  120. }
  121. break;
  122. default:
  123. // Event is invalid.
  124. isc_throw(NameRemoveTransactionError,
  125. "Wrong event for context: " << getContextStr());
  126. }
  127. }
  128. void
  129. NameRemoveTransaction::selectingFwdServerHandler() {
  130. switch(getNextEvent()) {
  131. case SELECT_SERVER_EVT:
  132. // First time through for this transaction, so initialize server
  133. // selection.
  134. initServerSelection(getForwardDomain());
  135. break;
  136. case SERVER_IO_ERROR_EVT:
  137. // We failed to communicate with current server. Attempt to select
  138. // another one below.
  139. break;
  140. default:
  141. // Event is invalid.
  142. isc_throw(NameRemoveTransactionError,
  143. "Wrong event for context: " << getContextStr());
  144. }
  145. // Select the next server from the list of forward servers.
  146. if (selectNextServer()) {
  147. // We have a server to try.
  148. transition(REMOVING_FWD_ADDRS_ST, SERVER_SELECTED_EVT);
  149. }
  150. else {
  151. // Server list is exhausted, so fail the transaction.
  152. transition(PROCESS_TRANS_FAILED_ST, NO_MORE_SERVERS_EVT);
  153. }
  154. }
  155. void
  156. NameRemoveTransaction::removingFwdAddrsHandler() {
  157. if (doOnEntry()) {
  158. // Clear the request on initial transition. This allows us to reuse
  159. // the request on retries if necessary.
  160. clearDnsUpdateRequest();
  161. }
  162. switch(getNextEvent()) {
  163. case SERVER_SELECTED_EVT:
  164. if (!getDnsUpdateRequest()) {
  165. // Request hasn't been constructed yet, so build it.
  166. try {
  167. buildRemoveFwdAddressRequest();
  168. } catch (const std::exception& ex) {
  169. // While unlikely, the build might fail if we have invalid
  170. // data. Should that be the case, we need to fail the
  171. // transaction.
  172. LOG_ERROR(dctl_logger,
  173. DHCP_DDNS_FORWARD_REMOVE_ADDRS_BUILD_FAILURE)
  174. .arg(getNcr()->toText())
  175. .arg(ex.what());
  176. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  177. break;
  178. }
  179. }
  180. // Call sendUpdate() to initiate the async send. Note it also sets
  181. // next event to NOP_EVT.
  182. sendUpdate("Forward A/AAAA Remove");
  183. break;
  184. case IO_COMPLETED_EVT: {
  185. switch (getDnsUpdateStatus()) {
  186. case DNSClient::SUCCESS: {
  187. // We successfully received a response packet from the server.
  188. // The RCODE will be based on a value-dependent RRset search,
  189. // see RFC 2136 section 3.2.3/3.2.4.
  190. const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
  191. if ((rcode == dns::Rcode::NOERROR()) ||
  192. (rcode == dns::Rcode::NXRRSET())) {
  193. // We were able to remove it or it wasn't there, now we
  194. // need to remove any other RRs for this FQDN.
  195. transition(REMOVING_FWD_RRS_ST, UPDATE_OK_EVT);
  196. } else {
  197. // Per RFC4703 any other value means cease.
  198. // If we get not authorized should we try the next server in
  199. // the list? @todo This needs some discussion perhaps.
  200. LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REMOVE_ADDRS_REJECTED)
  201. .arg(getCurrentServer()->toText())
  202. .arg(getNcr()->getFqdn())
  203. .arg(rcode.getCode());
  204. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  205. }
  206. break;
  207. }
  208. case DNSClient::TIMEOUT:
  209. case DNSClient::OTHER:
  210. // We couldn't send to the current server, log it and set up
  211. // to select the next server for a retry.
  212. // @note For now we treat OTHER as an IO error like TIMEOUT. It
  213. // is not entirely clear if this is accurate.
  214. LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REMOVE_ADDRS_IO_ERROR)
  215. .arg(getNcr()->getFqdn())
  216. .arg(getCurrentServer()->toText());
  217. retryTransition(SELECTING_FWD_SERVER_ST);
  218. break;
  219. case DNSClient::INVALID_RESPONSE:
  220. // A response was received but was corrupt. Retry it like an IO
  221. // error.
  222. LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REMOVE_ADDRS_RESP_CORRUPT)
  223. .arg(getCurrentServer()->toText())
  224. .arg(getNcr()->getFqdn());
  225. retryTransition(SELECTING_FWD_SERVER_ST);
  226. break;
  227. default:
  228. // Any other value and we will fail this transaction, something
  229. // bigger is wrong.
  230. LOG_ERROR(dctl_logger,
  231. DHCP_DDNS_FORWARD_REMOVE_ADDRS_BAD_DNSCLIENT_STATUS)
  232. .arg(getDnsUpdateStatus())
  233. .arg(getNcr()->getFqdn())
  234. .arg(getCurrentServer()->toText());
  235. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  236. break;
  237. } // end switch on dns_status
  238. break;
  239. } // end case IO_COMPLETE_EVT
  240. default:
  241. // Event is invalid.
  242. isc_throw(NameRemoveTransactionError,
  243. "Wrong event for context: " << getContextStr());
  244. }
  245. }
  246. void
  247. NameRemoveTransaction::removingFwdRRsHandler() {
  248. if (doOnEntry()) {
  249. // Clear the request on initial transition. This allows us to reuse
  250. // the request on retries if necessary.
  251. clearDnsUpdateRequest();
  252. }
  253. switch(getNextEvent()) {
  254. case UPDATE_OK_EVT:
  255. case SERVER_SELECTED_EVT:
  256. if (!getDnsUpdateRequest()) {
  257. // Request hasn't been constructed yet, so build it.
  258. try {
  259. buildRemoveFwdRRsRequest();
  260. } catch (const std::exception& ex) {
  261. // While unlikely, the build might fail if we have invalid
  262. // data. Should that be the case, we need to fail the
  263. // transaction.
  264. LOG_ERROR(dctl_logger,
  265. DHCP_DDNS_FORWARD_REMOVE_RRS_BUILD_FAILURE)
  266. .arg(getNcr()->toText())
  267. .arg(ex.what());
  268. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  269. break;
  270. }
  271. }
  272. // Call sendUpdate() to initiate the async send. Note it also sets
  273. // next event to NOP_EVT.
  274. sendUpdate("Forward RR Remove");
  275. break;
  276. case IO_COMPLETED_EVT: {
  277. switch (getDnsUpdateStatus()) {
  278. case DNSClient::SUCCESS: {
  279. // We successfully received a response packet from the server.
  280. // The RCODE will be based on a value-dependent RRset search,
  281. // see RFC 2136 section 3.2.3/3.2.4.
  282. const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
  283. if ((rcode == dns::Rcode::NOERROR()) ||
  284. (rcode == dns::Rcode::NXRRSET())) {
  285. // We were able to remove them or they were not there (
  286. // Rcode of NXRRSET means there are no matching RRsets).
  287. // In either case, we consider it success and mark it as done.
  288. setForwardChangeCompleted(true);
  289. // If request calls for reverse update then do that next,
  290. // otherwise we can process ok.
  291. if (getReverseDomain()) {
  292. transition(SELECTING_REV_SERVER_ST, SELECT_SERVER_EVT);
  293. } else {
  294. transition(PROCESS_TRANS_OK_ST, UPDATE_OK_EVT);
  295. }
  296. } else {
  297. // Per RFC4703 any other value means cease.
  298. // If we get not authorized should try the next server in
  299. // the list? @todo This needs some discussion perhaps.
  300. LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_REJECTED)
  301. .arg(getCurrentServer()->toText())
  302. .arg(getNcr()->getFqdn())
  303. .arg(rcode.getCode());
  304. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  305. }
  306. break;
  307. }
  308. case DNSClient::TIMEOUT:
  309. case DNSClient::OTHER:
  310. // We couldn't send to the current server, log it and set up
  311. // to select the next server for a retry.
  312. // @note For now we treat OTHER as an IO error like TIMEOUT. It
  313. // is not entirely clear if this is accurate.
  314. LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_IO_ERROR)
  315. .arg(getNcr()->getFqdn())
  316. .arg(getCurrentServer()->toText());
  317. // @note If we exhaust the IO retries for the current server
  318. // due to IO failures, we will abort the remaining updates.
  319. // The rational is that we are only in this state, if the remove
  320. // of the forward address RR succeeded (removingFwdAddrsHandler)
  321. // on the current server. Therefore we should not attempt another
  322. // removal on a different server. This is perhaps a point
  323. // for discussion.
  324. // @todo Should we go ahead with the reverse remove?
  325. retryTransition(PROCESS_TRANS_FAILED_ST);
  326. break;
  327. case DNSClient::INVALID_RESPONSE:
  328. // A response was received but was corrupt. Retry it like an IO
  329. // error.
  330. LOG_ERROR(dctl_logger, DHCP_DDNS_FORWARD_REMOVE_RRS_RESP_CORRUPT)
  331. .arg(getCurrentServer()->toText())
  332. .arg(getNcr()->getFqdn());
  333. // If we are out of retries on this server abandon the transaction.
  334. // (Same logic as the case for TIMEOUT above).
  335. retryTransition(PROCESS_TRANS_FAILED_ST);
  336. break;
  337. default:
  338. // Any other value and we will fail this transaction, something
  339. // bigger is wrong.
  340. LOG_ERROR(dctl_logger,
  341. DHCP_DDNS_FORWARD_REMOVE_RRS_BAD_DNSCLIENT_STATUS)
  342. .arg(getDnsUpdateStatus())
  343. .arg(getNcr()->getFqdn())
  344. .arg(getCurrentServer()->toText());
  345. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  346. break;
  347. } // end switch on dns_status
  348. break;
  349. } // end case IO_COMPLETE_EVT
  350. default:
  351. // Event is invalid.
  352. isc_throw(NameRemoveTransactionError,
  353. "Wrong event for context: " << getContextStr());
  354. }
  355. }
  356. void
  357. NameRemoveTransaction::selectingRevServerHandler() {
  358. switch(getNextEvent()) {
  359. case SELECT_SERVER_EVT:
  360. // First time through for this transaction, so initialize server
  361. // selection.
  362. initServerSelection(getReverseDomain());
  363. break;
  364. case SERVER_IO_ERROR_EVT:
  365. // We failed to communicate with current server. Attempt to select
  366. // another one below.
  367. break;
  368. default:
  369. // Event is invalid.
  370. isc_throw(NameRemoveTransactionError,
  371. "Wrong event for context: " << getContextStr());
  372. }
  373. // Select the next server from the list of forward servers.
  374. if (selectNextServer()) {
  375. // We have a server to try.
  376. transition(REMOVING_REV_PTRS_ST, SERVER_SELECTED_EVT);
  377. }
  378. else {
  379. // Server list is exhausted, so fail the transaction.
  380. transition(PROCESS_TRANS_FAILED_ST, NO_MORE_SERVERS_EVT);
  381. }
  382. }
  383. void
  384. NameRemoveTransaction::removingRevPtrsHandler() {
  385. if (doOnEntry()) {
  386. // Clear the request on initial transition. This allows us to reuse
  387. // the request on retries if necessary.
  388. clearDnsUpdateRequest();
  389. }
  390. switch(getNextEvent()) {
  391. case SERVER_SELECTED_EVT:
  392. if (!getDnsUpdateRequest()) {
  393. // Request hasn't been constructed yet, so build it.
  394. try {
  395. buildRemoveRevPtrsRequest();
  396. } catch (const std::exception& ex) {
  397. // While unlikely, the build might fail if we have invalid
  398. // data. Should that be the case, we need to fail the
  399. // transaction.
  400. LOG_ERROR(dctl_logger, DHCP_DDNS_REVERSE_REMOVE_BUILD_FAILURE)
  401. .arg(getNcr()->toText())
  402. .arg(ex.what());
  403. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  404. break;
  405. }
  406. }
  407. // Call sendUpdate() to initiate the async send. Note it also sets
  408. // next event to NOP_EVT.
  409. sendUpdate("Reverse Remove");
  410. break;
  411. case IO_COMPLETED_EVT: {
  412. switch (getDnsUpdateStatus()) {
  413. case DNSClient::SUCCESS: {
  414. // We successfully received a response packet from the server.
  415. // The RCODE will be based on a value-dependent RRset search,
  416. // see RFC 2136 section 3.2.3/3.2.4.
  417. const dns::Rcode& rcode = getDnsUpdateResponse()->getRcode();
  418. if ((rcode == dns::Rcode::NOERROR()) ||
  419. (rcode == dns::Rcode::NXRRSET())) {
  420. // We were able to remove the reverse mapping or they were
  421. // not there (Rcode of NXRRSET means there are no matching
  422. // RRsets). In either case, mark it as done.
  423. setReverseChangeCompleted(true);
  424. transition(PROCESS_TRANS_OK_ST, UPDATE_OK_EVT);
  425. } else {
  426. // Per RFC4703 any other value means cease.
  427. // If we get not authorized should try the next server in
  428. // the list? @todo This needs some discussion perhaps.
  429. LOG_ERROR(dctl_logger, DHCP_DDNS_REVERSE_REMOVE_REJECTED)
  430. .arg(getCurrentServer()->toText())
  431. .arg(getNcr()->getFqdn())
  432. .arg(rcode.getCode());
  433. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  434. }
  435. break;
  436. }
  437. case DNSClient::TIMEOUT:
  438. case DNSClient::OTHER:
  439. // We couldn't send to the current server, log it and set up
  440. // to select the next server for a retry.
  441. // @note For now we treat OTHER as an IO error like TIMEOUT. It
  442. // is not entirely clear if this is accurate.
  443. LOG_ERROR(dctl_logger, DHCP_DDNS_REVERSE_REMOVE_IO_ERROR)
  444. .arg(getNcr()->getFqdn())
  445. .arg(getCurrentServer()->toText());
  446. // If we are out of retries on this server, we go back and start
  447. // all over on a new server.
  448. retryTransition(SELECTING_REV_SERVER_ST);
  449. break;
  450. case DNSClient::INVALID_RESPONSE:
  451. // A response was received but was corrupt. Retry it like an IO
  452. // error.
  453. LOG_ERROR(dctl_logger, DHCP_DDNS_REVERSE_REMOVE_RESP_CORRUPT)
  454. .arg(getCurrentServer()->toText())
  455. .arg(getNcr()->getFqdn());
  456. // If we are out of retries on this server, we go back and start
  457. // all over on a new server.
  458. retryTransition(SELECTING_REV_SERVER_ST);
  459. break;
  460. default:
  461. // Any other value and we will fail this transaction, something
  462. // bigger is wrong.
  463. LOG_ERROR(dctl_logger,
  464. DHCP_DDNS_REVERSE_REMOVE_BAD_DNSCLIENT_STATUS)
  465. .arg(getDnsUpdateStatus())
  466. .arg(getNcr()->getFqdn())
  467. .arg(getCurrentServer()->toText());
  468. transition(PROCESS_TRANS_FAILED_ST, UPDATE_FAILED_EVT);
  469. break;
  470. } // end switch on dns_status
  471. break;
  472. } // end case IO_COMPLETE_EVT
  473. default:
  474. // Event is invalid.
  475. isc_throw(NameRemoveTransactionError,
  476. "Wrong event for context: " << getContextStr());
  477. }
  478. }
  479. void
  480. NameRemoveTransaction::processRemoveOkHandler() {
  481. switch(getNextEvent()) {
  482. case UPDATE_OK_EVT:
  483. LOG_INFO(dctl_logger, DHCP_DDNS_REMOVE_SUCCEEDED)
  484. .arg(getNcr()->toText());
  485. setNcrStatus(dhcp_ddns::ST_COMPLETED);
  486. endModel();
  487. break;
  488. default:
  489. // Event is invalid.
  490. isc_throw(NameRemoveTransactionError,
  491. "Wrong event for context: " << getContextStr());
  492. }
  493. }
  494. void
  495. NameRemoveTransaction::processRemoveFailedHandler() {
  496. switch(getNextEvent()) {
  497. case UPDATE_FAILED_EVT:
  498. case NO_MORE_SERVERS_EVT:
  499. case SERVER_IO_ERROR_EVT:
  500. setNcrStatus(dhcp_ddns::ST_FAILED);
  501. LOG_ERROR(dctl_logger, DHCP_DDNS_REMOVE_FAILED)
  502. .arg(transactionOutcomeString());
  503. endModel();
  504. break;
  505. default:
  506. // Event is invalid.
  507. isc_throw(NameRemoveTransactionError,
  508. "Wrong event for context: " << getContextStr());
  509. }
  510. }
  511. void
  512. NameRemoveTransaction::buildRemoveFwdAddressRequest() {
  513. // Construct an empty request.
  514. D2UpdateMessagePtr request = prepNewRequest(getForwardDomain());
  515. // Content on this request is based on RFC 4703, section 5.5, paragraph 4.
  516. // Construct dns::Name from NCR fqdn.
  517. dns::Name fqdn(dns::Name(getNcr()->getFqdn()));
  518. // First build the Prerequisite Section
  519. // Create an DHCID matches prerequisite RR and add it to the
  520. // pre-requisite section
  521. // Based on RFC 2136, section 2.4.2.
  522. dns::RRsetPtr prereq(new dns::RRset(fqdn, dns::RRClass::IN(),
  523. dns::RRType::DHCID(), dns::RRTTL(0)));
  524. addDhcidRdata(prereq);
  525. request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
  526. // Next build the Update Section
  527. // Create the FQDN/IP 'delete' RR and add it to the update section.
  528. // Add the RR to update section.
  529. // Based on 2136 section 2.5.4
  530. dns::RRsetPtr update(new dns::RRset(fqdn, dns::RRClass::NONE(),
  531. getAddressRRType(), dns::RRTTL(0)));
  532. addLeaseAddressRdata(update);
  533. request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
  534. // Set the transaction's update request to the new request.
  535. setDnsUpdateRequest(request);
  536. }
  537. void
  538. NameRemoveTransaction::buildRemoveFwdRRsRequest() {
  539. // Construct an empty request.
  540. D2UpdateMessagePtr request = prepNewRequest(getForwardDomain());
  541. // Construct dns::Name from NCR fqdn.
  542. dns::Name fqdn(dns::Name(getNcr()->getFqdn()));
  543. // Content on this request is based on RFC 4703, section 5.5, paragraph 5.
  544. // First build the Prerequisite Section.
  545. // Now create an DHCID matches prerequisite RR.
  546. // Set the RR's RData to DHCID.
  547. // Add it to the pre-requisite section.
  548. // Based on RFC 2136, section 2.4.2.
  549. dns::RRsetPtr prereq(new dns::RRset(fqdn, dns::RRClass::IN(),
  550. dns::RRType::DHCID(), dns::RRTTL(0)));
  551. addDhcidRdata(prereq);
  552. request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
  553. // Create an assertion that there are no A RRs for the FQDN.
  554. // Add it to the pre-reqs.
  555. // Based on RFC 2136, section 2.4.3.
  556. prereq.reset(new dns::RRset(fqdn, dns::RRClass::NONE(),
  557. dns::RRType::A(), dns::RRTTL(0)));
  558. request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
  559. // Create an assertion that there are no A RRs for the FQDN.
  560. // Add it to the pre-reqs.
  561. // Based on RFC 2136, section 2.4.3.
  562. prereq.reset(new dns::RRset(fqdn, dns::RRClass::NONE(),
  563. dns::RRType::AAAA(), dns::RRTTL(0)));
  564. request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
  565. // Next build the Update Section.
  566. // Create the 'delete' of all RRs for FQDN.
  567. // Set the message RData to lease address.
  568. // Add the RR to update section.
  569. // Based on RFC 2136, section 2.5.3.
  570. dns::RRsetPtr update(new dns::RRset(fqdn, dns::RRClass::ANY(),
  571. dns::RRType::ANY(), dns::RRTTL(0)));
  572. request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
  573. // Set the transaction's update request to the new request.
  574. setDnsUpdateRequest(request);
  575. }
  576. void
  577. NameRemoveTransaction::buildRemoveRevPtrsRequest() {
  578. // Construct an empty request.
  579. D2UpdateMessagePtr request = prepNewRequest(getReverseDomain());
  580. // Create the reverse IP address "FQDN".
  581. std::string rev_addr = D2CfgMgr::reverseIpAddress(getNcr()->getIpAddress());
  582. dns::Name rev_ip(rev_addr);
  583. // Content on this request is based on RFC 4703, section 5.5, paragraph 2.
  584. // First build the Prerequisite Section.
  585. // (Note that per RFC 4703, section 5.4, there is no need to validate
  586. // DHCID RR for PTR entries.)
  587. // Create an assertion that the PTRDNAME in the PTR record matches the
  588. // client's FQDN for the address that was released.
  589. // Based on RFC 2136, section 3.2.3
  590. dns::RRsetPtr prereq(new dns::RRset(rev_ip, dns::RRClass::IN(),
  591. dns::RRType::PTR(), dns::RRTTL(0)));
  592. addPtrRdata(prereq);
  593. request->addRRset(D2UpdateMessage::SECTION_PREREQUISITE, prereq);
  594. // Now, build the Update section.
  595. // Create a delete of any RRs for the FQDN and add it to update section.
  596. // Based on RFC 2136, section 3.4.2.3
  597. dns::RRsetPtr update(new dns::RRset(rev_ip, dns::RRClass::ANY(),
  598. dns::RRType::ANY(), dns::RRTTL(0)));
  599. request->addRRset(D2UpdateMessage::SECTION_UPDATE, update);
  600. // Set the transaction's update request to the new request.
  601. setDnsUpdateRequest(request);
  602. }
  603. } // namespace isc::d2
  604. } // namespace isc