d2_client_unittest.cc 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. // Copyright (C) 2012-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 <config.h>
  15. #include <dhcp/option4_client_fqdn.h>
  16. #include <dhcp/option6_client_fqdn.h>
  17. #include <dhcpsrv/d2_client_mgr.h>
  18. #include <exceptions/exceptions.h>
  19. #include <gtest/gtest.h>
  20. using namespace std;
  21. using namespace isc::asiolink;
  22. using namespace isc::dhcp;
  23. using namespace isc::util;
  24. using namespace isc;
  25. namespace {
  26. /// @brief Checks constructors and accessors of D2ClientConfig.
  27. TEST(D2ClientConfigTest, constructorsAndAccessors) {
  28. D2ClientConfigPtr d2_client_config;
  29. // Verify default constructor creates a disabled instance.
  30. ASSERT_NO_THROW(d2_client_config.reset(new D2ClientConfig()));
  31. EXPECT_FALSE(d2_client_config->getEnableUpdates());
  32. // Verify the enable-updates can be toggled.
  33. d2_client_config->enableUpdates(true);
  34. EXPECT_TRUE(d2_client_config->getEnableUpdates());
  35. d2_client_config->enableUpdates(false);
  36. EXPECT_FALSE(d2_client_config->getEnableUpdates());
  37. d2_client_config.reset();
  38. bool enable_updates = true;
  39. isc::asiolink::IOAddress server_ip("127.0.0.1");
  40. size_t server_port = 477;
  41. isc::asiolink::IOAddress sender_ip("127.0.0.1");
  42. size_t sender_port = 478;
  43. size_t max_queue_size = 2048;
  44. dhcp_ddns::NameChangeProtocol ncr_protocol = dhcp_ddns::NCR_UDP;
  45. dhcp_ddns::NameChangeFormat ncr_format = dhcp_ddns::FMT_JSON;
  46. bool always_include_fqdn = true;
  47. bool override_no_update = true;
  48. bool override_client_update = true;
  49. bool replace_client_name = true;
  50. std::string generated_prefix = "the_prefix";
  51. std::string qualifying_suffix = "the.suffix.";
  52. // Verify that we can construct a valid, enabled instance.
  53. ASSERT_NO_THROW(d2_client_config.reset(new
  54. D2ClientConfig(enable_updates,
  55. server_ip,
  56. server_port,
  57. sender_ip,
  58. sender_port,
  59. max_queue_size,
  60. ncr_protocol,
  61. ncr_format,
  62. always_include_fqdn,
  63. override_no_update,
  64. override_client_update,
  65. replace_client_name,
  66. generated_prefix,
  67. qualifying_suffix)));
  68. ASSERT_TRUE(d2_client_config);
  69. // Verify that the accessors return the expected values.
  70. EXPECT_EQ(d2_client_config->getEnableUpdates(), enable_updates);
  71. EXPECT_EQ(d2_client_config->getServerIp(), server_ip);
  72. EXPECT_EQ(d2_client_config->getServerPort(), server_port);
  73. EXPECT_EQ(d2_client_config->getSenderIp(), sender_ip);
  74. EXPECT_EQ(d2_client_config->getSenderPort(), sender_port);
  75. EXPECT_EQ(d2_client_config->getMaxQueueSize(), max_queue_size);
  76. EXPECT_EQ(d2_client_config->getNcrProtocol(), ncr_protocol);
  77. EXPECT_EQ(d2_client_config->getNcrFormat(), ncr_format);
  78. EXPECT_EQ(d2_client_config->getAlwaysIncludeFqdn(), always_include_fqdn);
  79. EXPECT_EQ(d2_client_config->getOverrideNoUpdate(), override_no_update);
  80. EXPECT_EQ(d2_client_config->getOverrideClientUpdate(),
  81. override_client_update);
  82. EXPECT_EQ(d2_client_config->getReplaceClientName(), replace_client_name);
  83. EXPECT_EQ(d2_client_config->getGeneratedPrefix(), generated_prefix);
  84. EXPECT_EQ(d2_client_config->getQualifyingSuffix(), qualifying_suffix);
  85. // Verify that toText called by << operator doesn't bomb.
  86. ASSERT_NO_THROW(std::cout << "toText test:" << std::endl <<
  87. *d2_client_config << std::endl);
  88. // Verify that constructor does not allow use of NCR_TCP.
  89. /// @todo obviously this becomes invalid once TCP is supported.
  90. ASSERT_THROW(d2_client_config.reset(new
  91. D2ClientConfig(enable_updates,
  92. server_ip,
  93. server_port,
  94. sender_ip,
  95. sender_port,
  96. max_queue_size,
  97. dhcp_ddns::NCR_TCP,
  98. ncr_format,
  99. always_include_fqdn,
  100. override_no_update,
  101. override_client_update,
  102. replace_client_name,
  103. generated_prefix,
  104. qualifying_suffix)),
  105. D2ClientError);
  106. /// @todo if additional validation is added to ctor, this test needs to
  107. /// expand accordingly.
  108. }
  109. /// @brief Tests the equality and inequality operators of D2ClientConfig.
  110. TEST(D2ClientConfigTest, equalityOperator) {
  111. D2ClientConfigPtr ref_config;
  112. D2ClientConfigPtr test_config;
  113. isc::asiolink::IOAddress ref_address("127.0.0.1");
  114. isc::asiolink::IOAddress test_address("127.0.0.2");
  115. // Create an instance to use as a reference.
  116. ASSERT_NO_THROW(ref_config.reset(new D2ClientConfig(true,
  117. ref_address, 477, ref_address, 478, 1024,
  118. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  119. true, true, true, true,
  120. "pre-fix", "suf-fix")));
  121. ASSERT_TRUE(ref_config);
  122. // Check a configuration that is identical to reference configuration.
  123. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  124. ref_address, 477, ref_address, 478, 1024,
  125. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  126. true, true, true, true,
  127. "pre-fix", "suf-fix")));
  128. ASSERT_TRUE(test_config);
  129. EXPECT_TRUE(*ref_config == *test_config);
  130. EXPECT_FALSE(*ref_config != *test_config);
  131. // Check a configuration that differs only by enable flag.
  132. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(false,
  133. ref_address, 477, ref_address, 478, 1024,
  134. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  135. true, true, true, true,
  136. "pre-fix", "suf-fix")));
  137. ASSERT_TRUE(test_config);
  138. EXPECT_FALSE(*ref_config == *test_config);
  139. EXPECT_TRUE(*ref_config != *test_config);
  140. // Check a configuration that differs only by server ip.
  141. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  142. test_address, 477, ref_address, 478, 1024,
  143. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  144. true, true, true, true,
  145. "pre-fix", "suf-fix")));
  146. ASSERT_TRUE(test_config);
  147. EXPECT_FALSE(*ref_config == *test_config);
  148. EXPECT_TRUE(*ref_config != *test_config);
  149. // Check a configuration that differs only by server port.
  150. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  151. ref_address, 333, ref_address, 478, 1024,
  152. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  153. true, true, true, true,
  154. "pre-fix", "suf-fix")));
  155. ASSERT_TRUE(test_config);
  156. EXPECT_FALSE(*ref_config == *test_config);
  157. EXPECT_TRUE(*ref_config != *test_config);
  158. // Check a configuration that differs only by sender ip.
  159. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  160. ref_address, 477, test_address, 478, 1024,
  161. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  162. true, true, true, true,
  163. "pre-fix", "suf-fix")));
  164. ASSERT_TRUE(test_config);
  165. EXPECT_FALSE(*ref_config == *test_config);
  166. EXPECT_TRUE(*ref_config != *test_config);
  167. // Check a configuration that differs only by sender port.
  168. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  169. ref_address, 477, ref_address, 333, 1024,
  170. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  171. true, true, true, true,
  172. "pre-fix", "suf-fix")));
  173. ASSERT_TRUE(test_config);
  174. EXPECT_FALSE(*ref_config == *test_config);
  175. EXPECT_TRUE(*ref_config != *test_config);
  176. // Check a configuration that differs only by max queue size.
  177. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  178. ref_address, 477, ref_address, 478, 2048,
  179. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  180. true, true, true, true,
  181. "pre-fix", "suf-fix")));
  182. ASSERT_TRUE(test_config);
  183. EXPECT_FALSE(*ref_config == *test_config);
  184. EXPECT_TRUE(*ref_config != *test_config);
  185. // Check a configuration that differs only by always_include_fqdn.
  186. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  187. ref_address, 477, ref_address, 478, 1024,
  188. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  189. false, true, true, true,
  190. "pre-fix", "suf-fix")));
  191. ASSERT_TRUE(test_config);
  192. EXPECT_FALSE(*ref_config == *test_config);
  193. EXPECT_TRUE(*ref_config != *test_config);
  194. // Check a configuration that differs only by override_no_update.
  195. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  196. ref_address, 477, ref_address, 478, 1024,
  197. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  198. true, false, true, true,
  199. "pre-fix", "suf-fix")));
  200. ASSERT_TRUE(test_config);
  201. EXPECT_FALSE(*ref_config == *test_config);
  202. EXPECT_TRUE(*ref_config != *test_config);
  203. // Check a configuration that differs only by override_client_update.
  204. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  205. ref_address, 477, ref_address, 478, 1024,
  206. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  207. true, true, false, true,
  208. "pre-fix", "suf-fix")));
  209. ASSERT_TRUE(test_config);
  210. EXPECT_FALSE(*ref_config == *test_config);
  211. EXPECT_TRUE(*ref_config != *test_config);
  212. // Check a configuration that differs only by replace_client_name.
  213. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  214. ref_address, 477, ref_address, 478, 1024,
  215. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  216. true, true, true, false,
  217. "pre-fix", "suf-fix")));
  218. ASSERT_TRUE(test_config);
  219. EXPECT_FALSE(*ref_config == *test_config);
  220. EXPECT_TRUE(*ref_config != *test_config);
  221. // Check a configuration that differs only by generated_prefix.
  222. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  223. ref_address, 477, ref_address, 478, 1024,
  224. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  225. true, true, true, true,
  226. "bogus", "suf-fix")));
  227. ASSERT_TRUE(test_config);
  228. EXPECT_FALSE(*ref_config == *test_config);
  229. EXPECT_TRUE(*ref_config != *test_config);
  230. // Check a configuration that differs only by qualifying_suffix.
  231. ASSERT_NO_THROW(test_config.reset(new D2ClientConfig(true,
  232. ref_address, 477, ref_address, 478, 1024,
  233. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  234. true, true, true, true,
  235. "pre-fix", "bogus")));
  236. ASSERT_TRUE(test_config);
  237. EXPECT_FALSE(*ref_config == *test_config);
  238. EXPECT_TRUE(*ref_config != *test_config);
  239. }
  240. /// @brief Checks the D2ClientMgr constructor.
  241. TEST(D2ClientMgr, constructor) {
  242. D2ClientMgrPtr d2_client_mgr;
  243. // Verify we can construct with the default constructor.
  244. ASSERT_NO_THROW(d2_client_mgr.reset(new D2ClientMgr()));
  245. // After construction, D2 configuration should be disabled.
  246. // Fetch it and verify this is the case.
  247. D2ClientConfigPtr original_config = d2_client_mgr->getD2ClientConfig();
  248. ASSERT_TRUE(original_config);
  249. EXPECT_FALSE(original_config->getEnableUpdates());
  250. // Make sure convenience method agrees.
  251. EXPECT_FALSE(d2_client_mgr->ddnsEnabled());
  252. }
  253. /// @brief Checks passing the D2ClientMgr a valid D2 client configuration.
  254. /// @todo Once NameChangeSender is integrated, this test needs to expand, and
  255. /// additional scenario tests will need to be written.
  256. TEST(D2ClientMgr, validConfig) {
  257. D2ClientMgrPtr d2_client_mgr;
  258. // Construct the manager and fetch its initial configuration.
  259. ASSERT_NO_THROW(d2_client_mgr.reset(new D2ClientMgr()));
  260. D2ClientConfigPtr original_config = d2_client_mgr->getD2ClientConfig();
  261. ASSERT_TRUE(original_config);
  262. // Verify that we cannot set the config to an empty pointer.
  263. D2ClientConfigPtr new_cfg;
  264. ASSERT_THROW(d2_client_mgr->setD2ClientConfig(new_cfg), D2ClientError);
  265. // Create a new, enabled config.
  266. ASSERT_NO_THROW(new_cfg.reset(new D2ClientConfig(true,
  267. isc::asiolink::IOAddress("127.0.0.1"), 477,
  268. isc::asiolink::IOAddress("127.0.0.1"), 478,
  269. 1024,
  270. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  271. true, true, true, true,
  272. "pre-fix", "suf-fix")));
  273. // Verify that we can assign a new, non-empty configuration.
  274. ASSERT_NO_THROW(d2_client_mgr->setD2ClientConfig(new_cfg));
  275. // Verify that we can fetch the newly assigned configuration.
  276. D2ClientConfigPtr updated_config = d2_client_mgr->getD2ClientConfig();
  277. ASSERT_TRUE(updated_config);
  278. EXPECT_TRUE(updated_config->getEnableUpdates());
  279. // Make sure convenience method agrees with the updated configuration.
  280. EXPECT_TRUE(d2_client_mgr->ddnsEnabled());
  281. // Make sure the configuration we fetched is the one we assigned,
  282. // and not the original configuration.
  283. EXPECT_EQ(*new_cfg, *updated_config);
  284. EXPECT_NE(*original_config, *updated_config);
  285. }
  286. /// @brief Tests that analyzeFqdn detects invalid combination of both the
  287. /// client S and N flags set to true.
  288. TEST(D2ClientMgr, analyzeFqdnInvalidCombination) {
  289. D2ClientMgr mgr;
  290. bool server_s = false;
  291. bool server_n = false;
  292. // Create disabled configuration.
  293. D2ClientConfigPtr cfg;
  294. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig()));
  295. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  296. ASSERT_FALSE(mgr.ddnsEnabled());
  297. // client S=1 N=1 is invalid. analyzeFqdn should throw.
  298. ASSERT_THROW(mgr.analyzeFqdn(true, true, server_s, server_n),
  299. isc::BadValue);
  300. // Create enabled configuration with all controls off (no overrides).
  301. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  302. isc::asiolink::IOAddress("127.0.0.1"), 477,
  303. isc::asiolink::IOAddress("127.0.0.1"), 478,
  304. 1024,
  305. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  306. false, false, false, false,
  307. "pre-fix", "suf-fix")));
  308. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  309. ASSERT_TRUE(mgr.ddnsEnabled());
  310. // client S=1 N=1 is invalid. analyzeFqdn should throw.
  311. ASSERT_THROW(mgr.analyzeFqdn(true, true, server_s, server_n),
  312. isc::BadValue);
  313. }
  314. /// @brief Tests that analyzeFqdn generates correct server S and N flags when
  315. /// updates are enabled and all overrides are off.
  316. TEST(D2ClientMgr, analyzeFqdnEnabledNoOverrides) {
  317. D2ClientMgr mgr;
  318. bool server_s = false;
  319. bool server_n = false;
  320. // Create enabled configuration with all controls off (no overrides).
  321. D2ClientConfigPtr cfg;
  322. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  323. isc::asiolink::IOAddress("127.0.0.1"), 477,
  324. isc::asiolink::IOAddress("127.0.0.1"), 478,
  325. 1024,
  326. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  327. false, false, false, false,
  328. "pre-fix", "suf-fix")));
  329. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  330. ASSERT_TRUE(mgr.ddnsEnabled());
  331. ASSERT_FALSE(cfg->getOverrideClientUpdate());
  332. ASSERT_FALSE(cfg->getOverrideNoUpdate());
  333. // client S=0 N=0 means client wants to do forward update.
  334. // server S should be 0 (server is not doing forward updates)
  335. // and server N should be 0 (server doing reverse updates)
  336. mgr.analyzeFqdn(false, false, server_s, server_n);
  337. EXPECT_FALSE(server_s);
  338. EXPECT_FALSE(server_n);
  339. // client S=1 N=0 means client wants server to do forward update.
  340. // server S should be 1 (server is doing forward updates)
  341. // and server N should be 0 (server doing updates)
  342. mgr.analyzeFqdn(true, false, server_s, server_n);
  343. EXPECT_TRUE(server_s);
  344. EXPECT_FALSE(server_n);
  345. // client S=0 N=1 means client wants no one to do forward updates.
  346. // server S should be 0 (server is not forward updates)
  347. // and server N should be 1 (server is not doing any updates)
  348. mgr.analyzeFqdn(false, true, server_s, server_n);
  349. EXPECT_FALSE(server_s);
  350. EXPECT_TRUE(server_n);
  351. }
  352. /// @brief Tests that analyzeFqdn generates correct server S and N flags when
  353. /// updates are enabled and override-no-update is on.
  354. TEST(D2ClientMgr, analyzeFqdnEnabledOverrideNoUpdate) {
  355. D2ClientMgr mgr;
  356. bool server_s = false;
  357. bool server_n = false;
  358. // Create enabled configuration with OVERRIDE_NO_UPDATE on.
  359. D2ClientConfigPtr cfg;
  360. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  361. isc::asiolink::IOAddress("127.0.0.1"), 477,
  362. isc::asiolink::IOAddress("127.0.0.1"), 478,
  363. 1024,
  364. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  365. false, true, false, false,
  366. "pre-fix", "suf-fix")));
  367. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  368. ASSERT_TRUE(mgr.ddnsEnabled());
  369. ASSERT_TRUE(cfg->getOverrideNoUpdate());
  370. ASSERT_FALSE(cfg->getOverrideClientUpdate());
  371. // client S=0 N=0 means client wants to do forward update.
  372. // server S should be 0 (server is not doing forward updates)
  373. // and server N should be 0 (server is doing reverse updates)
  374. mgr.analyzeFqdn(false, false, server_s, server_n);
  375. EXPECT_FALSE(server_s);
  376. EXPECT_FALSE(server_n);
  377. // client S=1 N=0 means client wants server to do forward update.
  378. // server S should be 1 (server is doing forward updates)
  379. // and server N should be 0 (server doing updates)
  380. mgr.analyzeFqdn(true, false, server_s, server_n);
  381. EXPECT_TRUE(server_s);
  382. EXPECT_FALSE(server_n);
  383. // client S=0 N=1 means client wants no one to do forward updates.
  384. // server S should be 1 (server is doing forward updates)
  385. // and server N should be 0 (server is doing updates)
  386. mgr.analyzeFqdn(false, true, server_s, server_n);
  387. EXPECT_TRUE(server_s);
  388. EXPECT_FALSE(server_n);
  389. }
  390. /// @brief Tests that analyzeFqdn generates correct server S and N flags when
  391. /// updates are enabled and override-client-update is on.
  392. TEST(D2ClientMgr, analyzeFqdnEnabledOverrideClientUpdate) {
  393. D2ClientMgr mgr;
  394. bool server_s = false;
  395. bool server_n = false;
  396. // Create enabled configuration with OVERRIDE_CLIENT_UPDATE on.
  397. D2ClientConfigPtr cfg;
  398. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  399. isc::asiolink::IOAddress("127.0.0.1"), 477,
  400. isc::asiolink::IOAddress("127.0.0.1"), 478,
  401. 1024,
  402. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  403. false, false, true, false,
  404. "pre-fix", "suf-fix")));
  405. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  406. ASSERT_TRUE(mgr.ddnsEnabled());
  407. ASSERT_FALSE(cfg->getOverrideNoUpdate());
  408. ASSERT_TRUE(cfg->getOverrideClientUpdate());
  409. // client S=0 N=0 means client wants to do forward update.
  410. // server S should be 1 (server is doing forward updates)
  411. // and server N should be 0 (server doing updates)
  412. mgr.analyzeFqdn(false, false, server_s, server_n);
  413. EXPECT_TRUE(server_s);
  414. EXPECT_FALSE(server_n);
  415. // client S=1 N=0 means client wants server to do forward update.
  416. // server S should be 1 (server is doing forward updates)
  417. // and server N should be 0 (server doing updates)
  418. mgr.analyzeFqdn(true, false, server_s, server_n);
  419. EXPECT_TRUE(server_s);
  420. EXPECT_FALSE(server_n);
  421. // client S=0 N=1 means client wants no one to do forward updates.
  422. // server S should be 0 (server is not forward updates)
  423. // and server N should be 1 (server is not doing any updates)
  424. mgr.analyzeFqdn(false, true, server_s, server_n);
  425. EXPECT_FALSE(server_s);
  426. EXPECT_TRUE(server_n);
  427. }
  428. /// @brief Verifies the adustFqdnFlags template with Option4ClientFqdn objects.
  429. /// Ensures that the method can set the N, S, and O flags properly.
  430. /// Other permutations are covered by analyzeFqdnFlag tests.
  431. TEST(D2ClientMgr, adjustFqdnFlagsV4) {
  432. D2ClientMgr mgr;
  433. Option4ClientFqdnPtr request;
  434. Option4ClientFqdnPtr response;
  435. // Create enabled configuration and override-no-update on.
  436. D2ClientConfigPtr cfg;
  437. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  438. isc::asiolink::IOAddress("127.0.0.1"), 477,
  439. isc::asiolink::IOAddress("127.0.0.1"), 478,
  440. 1024,
  441. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  442. false, true, false, false,
  443. "pre-fix", "suf-fix")));
  444. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  445. ASSERT_TRUE(mgr.ddnsEnabled());
  446. ASSERT_TRUE(cfg->getOverrideNoUpdate());
  447. ASSERT_FALSE(cfg->getOverrideClientUpdate());
  448. // client S=0 N=0 means client wants to do forward update.
  449. // server S should be 0 (server is not doing forward updates)
  450. // and server N should be 0 (server is doing reverse updates)
  451. // and server O should be 0
  452. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  453. "", Option4ClientFqdn::PARTIAL));
  454. response.reset(new Option4ClientFqdn(*request));
  455. response->resetFlags();
  456. mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response);
  457. EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_S));
  458. EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_N));
  459. EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_O));
  460. // client S=1 N=0 means client wants server to do forward update.
  461. // server S should be 1 (server is doing forward updates)
  462. // and server N should be 0 (server doing updates)
  463. // and server O should be 0
  464. request.reset(new Option4ClientFqdn(Option4ClientFqdn::FLAG_S,
  465. Option4ClientFqdn::RCODE_CLIENT(),
  466. "", Option4ClientFqdn::PARTIAL));
  467. response.reset(new Option4ClientFqdn(*request));
  468. response->resetFlags();
  469. mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response);
  470. EXPECT_TRUE(response->getFlag(Option4ClientFqdn::FLAG_S));
  471. EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_N));
  472. EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_O));
  473. // client S=0 N=1 means client wants no one to do updates
  474. // server S should be 1 (server is doing forward updates)
  475. // and server N should be 0 (server doing updates)
  476. // and O should be 1 (overriding client S)
  477. request.reset(new Option4ClientFqdn(Option4ClientFqdn::FLAG_N,
  478. Option4ClientFqdn::RCODE_CLIENT(),
  479. "", Option4ClientFqdn::PARTIAL));
  480. response.reset(new Option4ClientFqdn(*request));
  481. response->resetFlags();
  482. mgr.adjustFqdnFlags<Option4ClientFqdn>(*request, *response);
  483. EXPECT_TRUE(response->getFlag(Option4ClientFqdn::FLAG_S));
  484. EXPECT_FALSE(response->getFlag(Option4ClientFqdn::FLAG_N));
  485. EXPECT_TRUE(response->getFlag(Option4ClientFqdn::FLAG_O));
  486. }
  487. /// @brief Verified the getUpdateDirections template method with
  488. /// Option4ClientFqdn objects.
  489. TEST(D2ClientMgr, updateDirectionsV4) {
  490. D2ClientMgr mgr;
  491. Option4ClientFqdnPtr response;
  492. bool do_forward = false;
  493. bool do_reverse = false;
  494. // Response S=0, N=0 should mean do reverse only.
  495. response.reset(new Option4ClientFqdn(0,
  496. Option4ClientFqdn::RCODE_CLIENT(),
  497. "", Option4ClientFqdn::PARTIAL));
  498. mgr.getUpdateDirections(*response, do_forward, do_reverse);
  499. EXPECT_FALSE(do_forward);
  500. EXPECT_TRUE(do_reverse);
  501. // Response S=0, N=1 should mean don't do either.
  502. response.reset(new Option4ClientFqdn(Option4ClientFqdn::FLAG_N,
  503. Option4ClientFqdn::RCODE_CLIENT(),
  504. "", Option4ClientFqdn::PARTIAL));
  505. mgr.getUpdateDirections(*response, do_forward, do_reverse);
  506. EXPECT_FALSE(do_forward);
  507. EXPECT_FALSE(do_reverse);
  508. // Response S=1, N=0 should mean do both.
  509. response.reset(new Option4ClientFqdn(Option4ClientFqdn::FLAG_S,
  510. Option4ClientFqdn::RCODE_CLIENT(),
  511. "", Option4ClientFqdn::PARTIAL));
  512. mgr.getUpdateDirections(*response, do_forward, do_reverse);
  513. EXPECT_TRUE(do_forward);
  514. EXPECT_TRUE(do_reverse);
  515. // Response S=1, N=1 isn't possible.
  516. }
  517. /// @brief Tests the qualifyName method's ability to construct FQDNs
  518. TEST(D2ClientMgr, qualifyName) {
  519. D2ClientMgr mgr;
  520. // Create enabled configuration.
  521. D2ClientConfigPtr cfg;
  522. //append suffix and dot
  523. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  524. isc::asiolink::IOAddress("127.0.0.1"), 477,
  525. isc::asiolink::IOAddress("127.0.0.1"), 478,
  526. 1024,
  527. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  528. false, false, true, false,
  529. "prefix", "suffix.com")));
  530. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  531. // Verify that the qualifying suffix gets appended with trailing dot added.
  532. std::string partial_name = "somehost";
  533. std::string qualified_name = mgr.qualifyName(partial_name, true);
  534. EXPECT_EQ("somehost.suffix.com.", qualified_name);
  535. //append suffix but dot
  536. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  537. isc::asiolink::IOAddress("127.0.0.1"), 477,
  538. isc::asiolink::IOAddress("127.0.0.1"), 478,
  539. 1024,
  540. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  541. false, false, true, false,
  542. "prefix", "suffix.com")));
  543. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  544. partial_name = "somehost";
  545. qualified_name = mgr.qualifyName(partial_name, false); //false means no dot
  546. EXPECT_EQ("somehost.suffix.com", qualified_name);
  547. //append no suffix and not dot
  548. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  549. isc::asiolink::IOAddress("127.0.0.1"), 477,
  550. isc::asiolink::IOAddress("127.0.0.1"), 478,
  551. 1024,
  552. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  553. false, false, true, false,
  554. "prefix", ""))); //empty suffix
  555. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  556. partial_name = "somehost";
  557. qualified_name = mgr.qualifyName(partial_name, false); //false means no dot
  558. EXPECT_EQ("somehost", qualified_name);
  559. // Verify that the qualifying suffix gets appended with trailing dot added.
  560. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  561. isc::asiolink::IOAddress("127.0.0.1"), 477,
  562. isc::asiolink::IOAddress("127.0.0.1"), 478,
  563. 1024,
  564. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  565. false, false, true, false,
  566. "prefix", "hasdot.com.")));
  567. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  568. // Verify that the qualifying suffix gets appended without dot added.
  569. qualified_name = mgr.qualifyName(partial_name, true);
  570. EXPECT_EQ("somehost.hasdot.com.", qualified_name);
  571. // Verify that the qualifying suffix gets appended without an
  572. // extraneous dot when partial_name ends with a "."
  573. qualified_name = mgr.qualifyName("somehost.", true);
  574. EXPECT_EQ("somehost.hasdot.com.", qualified_name);
  575. // Reconfigure to a "" suffix
  576. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  577. isc::asiolink::IOAddress("127.0.0.1"), 477,
  578. isc::asiolink::IOAddress("127.0.0.1"), 478,
  579. 1024,
  580. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  581. false, false, true, false,
  582. "prefix", "")));
  583. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  584. // Verify that a name with a trailing dot does not get an extraneous
  585. // dot when the suffix is blank
  586. qualified_name = mgr.qualifyName("somehost.", true);
  587. EXPECT_EQ("somehost.", qualified_name);
  588. // Verify that a name with no trailing dot gets just a dot when the
  589. // suffix is blank
  590. qualified_name = mgr.qualifyName("somehost", true);
  591. EXPECT_EQ("somehost.", qualified_name);
  592. // Verify that a name with no trailing dot does not get dotted when the
  593. // suffix is blank and trailing dot is false
  594. qualified_name = mgr.qualifyName("somehost", false);
  595. EXPECT_EQ("somehost", qualified_name);
  596. // Verify that a name with trailing dot gets "undotted" when the
  597. // suffix is blank and trailing dot is false
  598. qualified_name = mgr.qualifyName("somehost.", false);
  599. EXPECT_EQ("somehost", qualified_name);
  600. }
  601. /// @brief Tests the generateFdqn method's ability to construct FQDNs
  602. TEST(D2ClientMgr, generateFqdn) {
  603. D2ClientMgr mgr;
  604. // Create enabled configuration.
  605. D2ClientConfigPtr cfg;
  606. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  607. isc::asiolink::IOAddress("127.0.0.1"), 477,
  608. isc::asiolink::IOAddress("127.0.0.1"), 478,
  609. 1024,
  610. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  611. false, false, true, false,
  612. "prefix", "suffix.com")));
  613. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  614. // Verify that it works with an IPv4 address.
  615. asiolink::IOAddress v4address("192.0.2.75");
  616. EXPECT_EQ("prefix-192-0-2-75.suffix.com.", mgr.generateFqdn(v4address,true));
  617. // Verify that it works with an IPv6 address.
  618. asiolink::IOAddress v6address("2001:db8::2");
  619. EXPECT_EQ("prefix-2001-db8--2.suffix.com.", mgr.generateFqdn(v6address,true));
  620. // Create a disabled config.
  621. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig()));
  622. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  623. // Verify names generate properly with a disabled configuration.
  624. EXPECT_EQ("myhost-192-0-2-75.", mgr.generateFqdn(v4address,true));
  625. EXPECT_EQ("myhost-2001-db8--2.", mgr.generateFqdn(v6address,true));
  626. }
  627. /// @brief Tests adjustDomainName template method with Option4ClientFqdn
  628. TEST(D2ClientMgr, adjustDomainNameV4) {
  629. D2ClientMgr mgr;
  630. Option4ClientFqdnPtr request;
  631. Option4ClientFqdnPtr response;
  632. // Create enabled configuration.
  633. D2ClientConfigPtr cfg;
  634. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  635. isc::asiolink::IOAddress("127.0.0.1"), 477,
  636. isc::asiolink::IOAddress("127.0.0.1"), 478,
  637. 1024,
  638. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  639. false, false, false, false,
  640. "prefix", "suffix.com")));
  641. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  642. ASSERT_FALSE(cfg->getReplaceClientName());
  643. // replace-client-name is false, client passes in empty fqdn
  644. // reponse domain should be empty/partial.
  645. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  646. "", Option4ClientFqdn::PARTIAL));
  647. response.reset(new Option4ClientFqdn(*request));
  648. mgr.adjustDomainName<Option4ClientFqdn>(*request, *response);
  649. EXPECT_EQ("", response->getDomainName());
  650. EXPECT_EQ(Option4ClientFqdn::PARTIAL, response->getDomainNameType());
  651. // replace-client-name is false, client passes in a partial fqdn
  652. // response should contain client's name plus the qualifying suffix.
  653. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  654. "myhost", Option4ClientFqdn::PARTIAL));
  655. response.reset(new Option4ClientFqdn(*request));
  656. mgr.adjustDomainName<Option4ClientFqdn>(*request, *response);
  657. EXPECT_EQ("myhost.suffix.com.", response->getDomainName());
  658. EXPECT_EQ(Option4ClientFqdn::FULL, response->getDomainNameType());
  659. // replace-client-name is false, client passes in a full fqdn
  660. // response domain should not be altered.
  661. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  662. "myhost.example.com.",
  663. Option4ClientFqdn::FULL));
  664. response.reset(new Option4ClientFqdn(*request));
  665. mgr.adjustDomainName<Option4ClientFqdn>(*request, *response);
  666. EXPECT_EQ("myhost.example.com.", response->getDomainName());
  667. EXPECT_EQ(Option4ClientFqdn::FULL, response->getDomainNameType());
  668. // Create enabled configuration.
  669. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  670. isc::asiolink::IOAddress("127.0.0.1"), 477,
  671. isc::asiolink::IOAddress("127.0.0.1"), 478,
  672. 1024,
  673. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  674. false, false, false, true,
  675. "prefix", "suffix.com")));
  676. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  677. ASSERT_TRUE(cfg->getReplaceClientName());
  678. // replace-client-name is true, client passes in empty fqdn
  679. // reponse domain should be empty/partial.
  680. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  681. "", Option4ClientFqdn::PARTIAL));
  682. response.reset(new Option4ClientFqdn(*request));
  683. mgr.adjustDomainName<Option4ClientFqdn>(*request, *response);
  684. EXPECT_EQ("", response->getDomainName());
  685. EXPECT_EQ(Option4ClientFqdn::PARTIAL, response->getDomainNameType());
  686. // replace-client-name is true, client passes in a partial fqdn
  687. // reponse domain should be empty/partial.
  688. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  689. "myhost", Option4ClientFqdn::PARTIAL));
  690. response.reset(new Option4ClientFqdn(*request));
  691. mgr.adjustDomainName<Option4ClientFqdn>(*request, *response);
  692. EXPECT_EQ("", response->getDomainName());
  693. EXPECT_EQ(Option4ClientFqdn::PARTIAL, response->getDomainNameType());
  694. // replace-client-name is true, client passes in a full fqdn
  695. // reponse domain should be empty/partial.
  696. request.reset(new Option4ClientFqdn(0, Option4ClientFqdn::RCODE_CLIENT(),
  697. "myhost.example.com.",
  698. Option4ClientFqdn::FULL));
  699. response.reset(new Option4ClientFqdn(*request));
  700. mgr.adjustDomainName<Option4ClientFqdn>(*request, *response);
  701. EXPECT_EQ("", response->getDomainName());
  702. EXPECT_EQ(Option4ClientFqdn::PARTIAL, response->getDomainNameType());
  703. }
  704. /// @brief Tests adjustDomainName template method with Option6ClientFqdn
  705. TEST(D2ClientMgr, adjustDomainNameV6) {
  706. D2ClientMgr mgr;
  707. Option6ClientFqdnPtr request;
  708. Option6ClientFqdnPtr response;
  709. // Create enabled configuration.
  710. D2ClientConfigPtr cfg;
  711. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  712. isc::asiolink::IOAddress("127.0.0.1"), 477,
  713. isc::asiolink::IOAddress("127.0.0.1"), 478,
  714. 1024,
  715. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  716. false, false, false, false,
  717. "prefix", "suffix.com")));
  718. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  719. ASSERT_FALSE(cfg->getReplaceClientName());
  720. // replace-client-name is false, client passes in empty fqdn
  721. // reponse domain should be empty/partial.
  722. request.reset(new Option6ClientFqdn(0, "", Option6ClientFqdn::PARTIAL));
  723. response.reset(new Option6ClientFqdn(*request));
  724. mgr.adjustDomainName<Option6ClientFqdn>(*request, *response);
  725. EXPECT_EQ("", response->getDomainName());
  726. EXPECT_EQ(Option6ClientFqdn::PARTIAL, response->getDomainNameType());
  727. // replace-client-name is false, client passes in a partial fqdn
  728. // response should contain client's name plus the qualifying suffix.
  729. request.reset(new Option6ClientFqdn(0, "myhost",
  730. Option6ClientFqdn::PARTIAL));
  731. response.reset(new Option6ClientFqdn(*request));
  732. mgr.adjustDomainName<Option6ClientFqdn>(*request, *response);
  733. EXPECT_EQ("myhost.suffix.com.", response->getDomainName());
  734. EXPECT_EQ(Option6ClientFqdn::FULL, response->getDomainNameType());
  735. // replace-client-name is false, client passes in a full fqdn
  736. // response domain should not be altered.
  737. request.reset(new Option6ClientFqdn(0, "myhost.example.com.",
  738. Option6ClientFqdn::FULL));
  739. response.reset(new Option6ClientFqdn(*request));
  740. mgr.adjustDomainName<Option6ClientFqdn>(*request, *response);
  741. EXPECT_EQ("myhost.example.com.", response->getDomainName());
  742. EXPECT_EQ(Option6ClientFqdn::FULL, response->getDomainNameType());
  743. // Create enabled configuration.
  744. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  745. isc::asiolink::IOAddress("127.0.0.1"), 477,
  746. isc::asiolink::IOAddress("127.0.0.1"), 478,
  747. 1024,
  748. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  749. false, false, false, true,
  750. "prefix", "suffix.com")));
  751. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  752. ASSERT_TRUE(cfg->getReplaceClientName());
  753. // replace-client-name is true, client passes in empty fqdn
  754. // reponse domain should be empty/partial.
  755. request.reset(new Option6ClientFqdn(0, "", Option6ClientFqdn::PARTIAL));
  756. response.reset(new Option6ClientFqdn(*request));
  757. mgr.adjustDomainName<Option6ClientFqdn>(*request, *response);
  758. EXPECT_EQ("", response->getDomainName());
  759. EXPECT_EQ(Option6ClientFqdn::PARTIAL, response->getDomainNameType());
  760. // replace-client-name is true, client passes in a partial fqdn
  761. // reponse domain should be empty/partial.
  762. request.reset(new Option6ClientFqdn(0, "myhost",
  763. Option6ClientFqdn::PARTIAL));
  764. response.reset(new Option6ClientFqdn(*request));
  765. mgr.adjustDomainName<Option6ClientFqdn>(*request, *response);
  766. EXPECT_EQ("", response->getDomainName());
  767. EXPECT_EQ(Option6ClientFqdn::PARTIAL, response->getDomainNameType());
  768. // replace-client-name is true, client passes in a full fqdn
  769. // reponse domain should be empty/partial.
  770. request.reset(new Option6ClientFqdn(0, "myhost.example.com.",
  771. Option6ClientFqdn::FULL));
  772. response.reset(new Option6ClientFqdn(*request));
  773. mgr.adjustDomainName<Option6ClientFqdn>(*request, *response);
  774. EXPECT_EQ("", response->getDomainName());
  775. EXPECT_EQ(Option6ClientFqdn::PARTIAL, response->getDomainNameType());
  776. }
  777. /// @brief Verifies the adustFqdnFlags template with Option6ClientFqdn objects.
  778. /// Ensures that the method can set the N, S, and O flags properly.
  779. /// Other permutations are covered by analyzeFqdnFlags tests.
  780. TEST(D2ClientMgr, adjustFqdnFlagsV6) {
  781. D2ClientMgr mgr;
  782. Option6ClientFqdnPtr request;
  783. Option6ClientFqdnPtr response;
  784. // Create enabled configuration and override-no-update on.
  785. D2ClientConfigPtr cfg;
  786. ASSERT_NO_THROW(cfg.reset(new D2ClientConfig(true,
  787. isc::asiolink::IOAddress("127.0.0.1"), 477,
  788. isc::asiolink::IOAddress("127.0.0.1"), 478,
  789. 1024,
  790. dhcp_ddns::NCR_UDP, dhcp_ddns::FMT_JSON,
  791. false, true, false, false,
  792. "pre-fix", "suf-fix")));
  793. ASSERT_NO_THROW(mgr.setD2ClientConfig(cfg));
  794. ASSERT_TRUE(mgr.ddnsEnabled());
  795. ASSERT_TRUE(cfg->getOverrideNoUpdate());
  796. ASSERT_FALSE(cfg->getOverrideClientUpdate());
  797. // client S=0 N=0 means client wants to do forward update.
  798. // server S should be 0 (server is not doing forward updates)
  799. // and server N should be 0 (server doing reverse updates)
  800. // and server O should be 0
  801. request.reset(new Option6ClientFqdn(0, "", Option6ClientFqdn::PARTIAL));
  802. response.reset(new Option6ClientFqdn(*request));
  803. response->resetFlags();
  804. mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response);
  805. EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_S));
  806. EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_N));
  807. EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_O));
  808. // client S=1 N=0 means client wants server to do forward update.
  809. // server S should be 1 (server is doing forward updates)
  810. // and server N should be 0 (server doing updates)
  811. // and server O should be 0
  812. request.reset(new Option6ClientFqdn(Option6ClientFqdn::FLAG_S,
  813. "", Option6ClientFqdn::PARTIAL));
  814. response.reset(new Option6ClientFqdn(*request));
  815. response->resetFlags();
  816. mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response);
  817. EXPECT_TRUE(response->getFlag(Option6ClientFqdn::FLAG_S));
  818. EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_N));
  819. EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_O));
  820. // client S=0 N=1 means client wants no one to do updates
  821. // server S should be 1 (server is doing forward updates)
  822. // and server N should be 0 (server doing updates)
  823. // and O should be 1 (overriding client S)
  824. request.reset(new Option6ClientFqdn(Option6ClientFqdn::FLAG_N,
  825. "", Option6ClientFqdn::PARTIAL));
  826. response.reset(new Option6ClientFqdn(*request));
  827. response->resetFlags();
  828. mgr.adjustFqdnFlags<Option6ClientFqdn>(*request, *response);
  829. EXPECT_TRUE(response->getFlag(Option6ClientFqdn::FLAG_S));
  830. EXPECT_FALSE(response->getFlag(Option6ClientFqdn::FLAG_N));
  831. EXPECT_TRUE(response->getFlag(Option6ClientFqdn::FLAG_O));
  832. }
  833. /// @brief Verified the getUpdateDirections template method with
  834. /// Option6ClientFqdn objects.
  835. TEST(D2ClientMgr, updateDirectionsV6) {
  836. D2ClientMgr mgr;
  837. Option6ClientFqdnPtr response;
  838. bool do_forward = false;
  839. bool do_reverse = false;
  840. // Response S=0, N=0 should mean do reverse only.
  841. response.reset(new Option6ClientFqdn(0,
  842. "", Option6ClientFqdn::PARTIAL));
  843. mgr.getUpdateDirections(*response, do_forward, do_reverse);
  844. EXPECT_FALSE(do_forward);
  845. EXPECT_TRUE(do_reverse);
  846. // Response S=0, N=1 should mean don't do either.
  847. response.reset(new Option6ClientFqdn(Option6ClientFqdn::FLAG_N,
  848. "", Option6ClientFqdn::PARTIAL));
  849. mgr.getUpdateDirections(*response, do_forward, do_reverse);
  850. EXPECT_FALSE(do_forward);
  851. EXPECT_FALSE(do_reverse);
  852. // Response S=1, N=0 should mean do both.
  853. response.reset(new Option6ClientFqdn(Option6ClientFqdn::FLAG_S,
  854. "", Option6ClientFqdn::PARTIAL));
  855. mgr.getUpdateDirections(*response, do_forward, do_reverse);
  856. EXPECT_TRUE(do_forward);
  857. EXPECT_TRUE(do_reverse);
  858. // Response S=1, N=1 isn't possible.
  859. }
  860. } // end of anonymous namespace