diff options
author | Piotrek Zadroga <piotrek@isc.org> | 2024-02-16 20:39:14 +0100 |
---|---|---|
committer | Piotrek Zadroga <piotrek@isc.org> | 2024-02-23 17:14:05 +0100 |
commit | cb0cc95f1adb00c2e553191c9288a0fbce2d28ff (patch) | |
tree | ae91e7030af46ef65c2f28ad7678a5f89eaea0a1 /src/lib | |
parent | [#3141] unpack SvcParams from hex data (diff) | |
download | kea-cb0cc95f1adb00c2e553191c9288a0fbce2d28ff.tar.xz kea-cb0cc95f1adb00c2e553191c9288a0fbce2d28ff.zip |
[#3141] DNRv6 UTs edited
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/dhcp/option6_dnr.h | 35 | ||||
-rw-r--r-- | src/lib/dhcp/tests/option6_dnr_unittest.cc | 441 |
2 files changed, 244 insertions, 232 deletions
diff --git a/src/lib/dhcp/option6_dnr.h b/src/lib/dhcp/option6_dnr.h index f7fbeaa4d4..e1cbcf743e 100644 --- a/src/lib/dhcp/option6_dnr.h +++ b/src/lib/dhcp/option6_dnr.h @@ -45,41 +45,6 @@ public: OptionBufferConstIter end, bool convenient_notation = false); - /// @brief Constructor of the %Option with all fields from params. - /// - /// Constructor of the %Option where all fields - /// i.e. Service priority, ADN, IP address(es) and Service params - /// are provided as ctor parameters. - /// - /// @param service_priority Service priority - /// @param adn ADN FQDN - /// @param ip_addresses Container of IP addresses - /// @param svc_params Service Parameters - /// - /// @throw InvalidOptionDnrDomainName Thrown in case of any issue with parsing ADN - /// @throw InvalidOptionDnrSvcParams Thrown when @c checkSvcParams(from_wire_data) throws - /// @throw OutOfRange Thrown in case of no IP addresses found or when IP addresses length - /// is too big - Option6Dnr(const uint16_t service_priority, - const std::string& adn, - const Option6Dnr::AddressContainer& ip_addresses, - const std::string& svc_params) - : Option(V6, D6O_V6_DNR), DnrInstance(V6, service_priority, adn, ip_addresses, svc_params) { - } - - /// @brief Constructor of the %Option in ADN only mode. - /// - /// Constructor of the %Option in ADN only mode - /// i.e. only Service priority and ADN FQDN - /// are provided as ctor parameters. - /// - /// @param service_priority Service priority - /// @param adn ADN FQDN - /// - /// @throw InvalidOptionDnrDomainName Thrown in case of any issue with parsing ADN - Option6Dnr(const uint16_t service_priority, const std::string& adn) - : Option(V6, D6O_V6_DNR), DnrInstance(V6, service_priority, adn) {} - /// @brief Copies this option and returns a pointer to the copy. /// /// @return Pointer to the copy of the option. diff --git a/src/lib/dhcp/tests/option6_dnr_unittest.cc b/src/lib/dhcp/tests/option6_dnr_unittest.cc index 29c082da68..bf00fbeaa3 100644 --- a/src/lib/dhcp/tests/option6_dnr_unittest.cc +++ b/src/lib/dhcp/tests/option6_dnr_unittest.cc @@ -283,8 +283,11 @@ TEST(Option6DnrTest, onWireCtorSvcParamsIncluded) { 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. 0x00, 0x10, // Addr Len field value = 16 dec 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef - 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, - 'a', 'b', 'c' // example SvcParams data + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q' // 3 octets long alpn-id doq }; OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); @@ -305,28 +308,34 @@ TEST(Option6DnrTest, onWireCtorSvcParamsIncluded) { const Option6Dnr::AddressContainer& addresses = option->getAddresses(); EXPECT_EQ(1, addresses.size()); EXPECT_EQ("2001:db8:1::dead:beef", addresses[0].toText()); - EXPECT_EQ(3, option->getSvcParamsLength()); - EXPECT_EQ("abc", option->getSvcParams()); + EXPECT_EQ(12, option->getSvcParamsLength()); + const OptionBuffer svc_params = { + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q' // 3 octets long alpn-id doq + }; + EXPECT_EQ(svc_params, option->getSvcParams()); // BTW let's check if len() works ok. // expected len: 20 (FQDN) + 2 (ADN Len) + 2 (Service priority) + 4 (headers) = 28 - // + 16 (IP address) + 2 (Addr Len) + 3 (SvcParams) = 49. - EXPECT_EQ(49, option->len()); + // + 16 (IP address) + 2 (Addr Len) + 12 (SvcParams) = 58. + EXPECT_EQ(58, option->len()); // BTW let's check if toText() works ok. // toText() len does not count in headers len. - EXPECT_EQ("type=144(V6_DNR), len=45, " + EXPECT_EQ("type=144(V6_DNR), len=54, " "service_priority=32769, adn_length=20, " "adn='myhost.example.com.', " "addr_length=16, " "address(es): 2001:db8:1::dead:beef, " - "svc_params='abc'", + "svc_params='alpn=dot,doq'", option->toText()); } // Test checks that exception is thrown when trying to unpack malformed wire data -// - SvcParams Key contains char that is not allowed. -TEST(Option6DnrTest, onWireCtorSvcParamsInvalidCharKey) { +// - SvcParams Key contains truncated SvcParamVal Len data. +TEST(Option6DnrTest, onWireCtorSvcParamsTruncatedParamLen) { // Prepare data to decode with invalid SvcParams. const uint8_t buf_data[] = { 0x80, 0x01, // Service priority is 32769 dec @@ -334,213 +343,247 @@ TEST(Option6DnrTest, onWireCtorSvcParamsInvalidCharKey) { 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. - 0x00, 0x10, // Addr Len field value = 48 dec + 0x00, 0x10, // Addr Len field value 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef - 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, - 'a', '+', 'c' // Allowed "a"-"z", "0"-"9", and "-" + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q', // 3 octets long alpn-id doq + 0, 3, // SvcParamKey port + 0 // truncated SvcParamVal Len }; OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); - // Create option instance. Check that constructor throws InvalidOptionDnrSvcParams exception. + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), OutOfRange); ASSERT_FALSE(option); } -// This test verifies option constructor in ADN only mode. -// Service priority and ADN are provided via ctor. -TEST(Option6DnrTest, adnOnlyModeCtor) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; +// Test checks that exception is thrown when trying to unpack malformed wire data +// - SvcParams Key contains truncated data. +TEST(Option6DnrTest, onWireCtorSvcParamsTruncatedParamData) { + // Prepare data to decode with invalid SvcParams. + const uint8_t buf_data[] = { + 0x80, 0x01, // Service priority is 32769 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. + 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. + 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. + 0x00, 0x10, // Addr Len field value + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q', // 3 octets long alpn-id doq + 0, 3, // SvcParamKey port + 0, 2, // SvcParamVal Len + 1 // truncated data + }; - // Create option instance. Check that constructor doesn't throw. + OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_NO_THROW(option.reset(new Option6Dnr(service_priority, adn))); - ASSERT_TRUE(option); - - // Check if member variables were correctly set by ctor. - EXPECT_EQ(Option::V6, option->getUniverse()); - EXPECT_EQ(D6O_V6_DNR, option->getType()); - EXPECT_EQ(service_priority, option->getServicePriority()); - EXPECT_EQ(20, option->getAdnLength()); - EXPECT_EQ(adn, option->getAdnAsText()); - - // This is ADN only mode, so Addr Length and SvcParams Length - // are both expected to be zero. - EXPECT_EQ(0, option->getAddrLength()); - EXPECT_EQ(0, option->getSvcParamsLength()); - - // BTW let's check if len() works ok. - // expected len: 20 (FQDN) + 2 (ADN Len) + 2 (Service priority) + 4 (headers) = 28. - EXPECT_EQ(28, option->len()); - - // BTW let's check if toText() works ok. - // toText() len does not count in headers len. - EXPECT_EQ("type=144(V6_DNR), len=24, " - "service_priority=9, adn_length=20, " - "adn='myhost.example.com.'", - option->toText()); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); + ASSERT_FALSE(option); } -// This test verifies that option constructor in ADN only mode throws -// an exception when mandatory ADN is empty. -TEST(Option6DnrTest, adnOnlyModeCtorNoFqdn) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn; // invalid empty ADN +// Test checks that exception is thrown when trying to unpack malformed wire data +// - SvcParams Key contains unknown key. +TEST(Option6DnrTest, onWireCtorSvcParamsUnknownKey) { + // Prepare data to decode with invalid SvcParams. + const uint8_t buf_data[] = { + 0x80, 0x01, // Service priority is 32769 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. + 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. + 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. + 0x00, 0x10, // Addr Len field value + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q', // 3 octets long alpn-id doq + 0, 99, // unknown SvcParamKey + 0, 2, // SvcParamVal Len + 1, 2 // random data + }; - // Create option instance. Check that constructor throws. + OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn)), InvalidOptionDnrDomainName); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } -// This test verifies option constructor where all fields -// i.e. Service priority, ADN, IP address(es) and Service params -// are provided as ctor parameters. -TEST(Option6DnrTest, allFieldsCtor) { - // Prepare example parameters - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "alpn"; +// Test checks that exception is thrown when trying to unpack malformed wire data +// - SvcParams Key contains forbidden key. +TEST(Option6DnrTest, onWireCtorSvcParamsForbiddenKey) { + // Prepare data to decode with invalid SvcParams. + const uint8_t buf_data[] = { + 0x80, 0x01, // Service priority is 32769 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. + 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. + 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. + 0x00, 0x10, // Addr Len field value + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q', // 3 octets long alpn-id doq + 0, 4, // SvcParamKey ipv4hint is forbidden + 0, 2, // SvcParamVal Len + 1, 2 // random data + }; - // Create option instance. Check that constructor doesn't throw. + OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_NO_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params))); - ASSERT_TRUE(option); - - // Check if member variables were correctly set by ctor. - EXPECT_EQ(Option::V6, option->getUniverse()); - EXPECT_EQ(D6O_V6_DNR, option->getType()); - EXPECT_EQ(service_priority, option->getServicePriority()); - EXPECT_EQ(20, option->getAdnLength()); - EXPECT_EQ(adn, option->getAdnAsText()); - EXPECT_EQ(16, option->getAddrLength()); - EXPECT_EQ(4, option->getSvcParamsLength()); - EXPECT_EQ(svc_params, option->getSvcParams()); - - // BTW let's check if len() works ok. - // expected len: 20 (FQDN) + 2 (ADN Len) + 2 (Service priority) + 4 (headers) = 28 - // + 16 (IPv6) + 2 (Addr Len) + 4 (Svc Params) = 50. - EXPECT_EQ(50, option->len()); - - // BTW let's check if toText() works ok. - // toText() len does not count in headers len. - EXPECT_EQ("type=144(V6_DNR), len=46, " - "service_priority=9, adn_length=20, " - "adn='myhost.example.com.', addr_length=16, " - "address(es): 2001:db8:1::baca, svc_params='alpn'", - option->toText()); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); + ASSERT_FALSE(option); } -// This test verifies that option constructor throws -// an exception when option fields provided via ctor are malformed -// - no IPv6 address provided. -TEST(Option6DnrTest, allFieldsCtorNoIpAddress) { - // Prepare example parameters - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - const Option6Dnr::AddressContainer addresses; // no IPv6 address in here - const std::string svc_params = "alpn"; +// Test checks that exception is thrown when trying to unpack malformed wire data +// - SvcParams Key contains unsupported key. +TEST(Option6DnrTest, onWireCtorSvcParamsUnsupportedKey) { + // Prepare data to decode with invalid SvcParams. + const uint8_t buf_data[] = { + 0x80, 0x01, // Service priority is 32769 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. + 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. + 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. + 0x00, 0x10, // Addr Len field value + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q', // 3 octets long alpn-id doq + 0, 5, // SvcParamKey ech is unsupported in DHCP DNR option + 0, 2, // SvcParamVal Len + 1, 2 // random data + }; - // Create option instance. Check that constructor throws. + OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params)), - OutOfRange); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } -// This test verifies that option constructor throws -// an exception when option fields provided via ctor are malformed -// - Svc Params key=val pair has 2 equal signs. -TEST(Option6DnrTest, svcParamsTwoEqualSignsPerParam) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "key123=val1=val2 key234"; // invalid svc param - 2 equal signs +// Test checks that exception is thrown when trying to unpack malformed wire data +// - SvcParams Key contains duplicated key. +TEST(Option6DnrTest, onWireCtorSvcParamsDuplicatedKey) { + // Prepare data to decode with invalid SvcParams. + const uint8_t buf_data[] = { + 0x80, 0x01, // Service priority is 32769 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. + 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. + 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. + 0x00, 0x10, // Addr Len field value + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 1, // SvcParamKey alpn + 0, 8, // SvcParamVal Len + 3, 'd', 'o', 't', // 3 octets long alpn-id dot + 3, 'd', 'o', 'q', // 3 octets long alpn-id doq + 0, 1, // SvcParamKey alpn is duplicated + 0, 4, // SvcParamVal Len + 3, 'd', 'o', 't' // 3 octets long alpn-id dot + }; - // Create option instance. Check that constructor throws. + OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params)), - InvalidOptionDnrSvcParams); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } -// This test verifies that option constructor throws -// an exception when option fields provided via ctor are malformed -// - Svc Params forbidden key provided. -TEST(Option6DnrTest, svcParamsForbiddenKey) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "key123=val1 ipv6hint"; // forbidden svc param key - ipv6hint +// Test checks that exception is thrown when trying to unpack malformed wire data +// - SvcParams Keys are in wrong order. +TEST(Option6DnrTest, onWireCtorSvcParamsWrongKeyOrder) { + // Prepare data to decode with invalid SvcParams. + const uint8_t buf_data[] = { + 0x80, 0x01, // Service priority is 32769 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: Myhost. + 0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // Example. + 0x03, 0x43, 0x6F, 0x6D, 0x00, // Com. + 0x00, 0x10, // Addr Len field value + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, // + 0, 3, // SvcParamKey port + 0, 2, // SvcParamVal Len + 23, 23, // 2 octets long port number + 0, 1, // SvcParamKey alpn is duplicated + 0, 4, // SvcParamVal Len + 3, 'd', 'o', 't' // 3 octets long alpn-id dot + }; - // Create option instance. Check that constructor throws. + OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); + // Create option instance. Check that constructor throws exception. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params)), - InvalidOptionDnrSvcParams); + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end())), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } // This test verifies that option constructor throws -// an exception when option fields provided via ctor are malformed -// - Svc Params key was repeated. -TEST(Option6DnrTest, svcParamsKeyRepeated) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "key123=val1 key234 key123"; // svc param key key123 repeated +// an exception when config provided via ctor is malformed +// - SvcParam key=val pair has 2 equal signs. +TEST(Option6DnrTest, fromConfigCtorSvcParamsTwoEqualSignsPerParam) { + // Prepare example config. + const std::string config = "100, dot1.example.org., 2001:db8::1 2001:db8::2, " + "alpn=dot=doq port=8530 dohpath=/q{?dns}"; + + OptionBuffer buf; + buf.assign(config.begin(), config.end()); // Create option instance. Check that constructor throws. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params)), + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end(), true)), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } // This test verifies that option constructor throws -// an exception when option fields provided via ctor are malformed -// - Svc Params key is too long. -TEST(Option6DnrTest, svcParamsKeyTooLong) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "thisisveryveryveryvery" - "veryveryveryveryveryvery" - "veryveryveryveryvlongkey"; // svc param key longer than 63 +// an exception when config provided via ctor is malformed +// - SvcParam has forbidden key. +TEST(Option6DnrTest, fromConfigCtorSvcParamsForbiddenKey) { + // Prepare example config. + const std::string config = "100, dot1.example.org., 2001:db8::1 2001:db8::2, " + "ipv6hint=something port=8530 dohpath=/q{?dns}"; + + OptionBuffer buf; + buf.assign(config.begin(), config.end()); // Create option instance. Check that constructor throws. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params)), + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end(), true)), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } // This test verifies that option constructor throws -// an exception when option fields provided via ctor are malformed -// - Svc Params key has chars that are not allowed. -TEST(Option6DnrTest, svcParamsKeyHasInvalidChar) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "alpn=h2 NOT_ALLOWED_CHARS_KEY=123"; // svc param key has forbidden chars +// an exception when config provided via ctor is malformed +// - Svc Params key was repeated. +TEST(Option6DnrTest, fromConfigCtorSvcParamsKeyRepeated) { + // Prepare example config. + const std::string config = "100, dot1.example.org., 2001:db8::1 2001:db8::2, " + "port=8530 port=1234 dohpath=/q{?dns}"; + + OptionBuffer buf; + buf.assign(config.begin(), config.end()); // Create option instance. Check that constructor throws. Option6DnrPtr option; - EXPECT_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params)), + EXPECT_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end(), true)), InvalidOptionDnrSvcParams); ASSERT_FALSE(option); } @@ -548,35 +591,38 @@ TEST(Option6DnrTest, svcParamsKeyHasInvalidChar) { // This test verifies that string representation of the option returned by // toText method is correctly formatted. TEST(Option6DnrTest, toText) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::baca")); - const std::string svc_params = "alpn"; + // Prepare example config. + const std::string config = "9, myhost.example.com., 2001:db8:1::baca, " + "alpn=h3 port=1234 dohpath=/q{?dns}"; + + OptionBuffer buf; + buf.assign(config.begin(), config.end()); // Create option instance. Check that constructor doesn't throw. Option6DnrPtr option; - EXPECT_NO_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params))); + EXPECT_NO_THROW(option.reset(new Option6Dnr(buf.begin(), buf.end(), true))); ASSERT_TRUE(option); const int indent = 4; - std::string expected = " type=144(V6_DNR), len=46, " // the indentation of 4 spaces + std::string expected = " type=144(V6_DNR), len=67, " // the indentation of 4 spaces "service_priority=9, adn_length=20, " "adn='myhost.example.com.', addr_length=16, " - "address(es): 2001:db8:1::baca, svc_params='alpn'"; + "address(es): 2001:db8:1::baca, svc_params='alpn=h3 port=1234 " + "dohpath=/q{?dns}'"; EXPECT_EQ(expected, option->toText(indent)); } // This test verifies on-wire format of the option is correctly created in ADN only mode. -TEST(Option6DnrTest, packAdnOnlyMode) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; +TEST(Option6DnrTest, fromConfigCtorPackAdnOnlyMode) { + // Prepare example config. + const std::string config = "9, myhost.example.com."; + + OptionBuffer in_buf; + in_buf.assign(config.begin(), config.end()); // Create option instance. Check that constructor doesn't throw. Option6DnrPtr option; - EXPECT_NO_THROW(option.reset(new Option6Dnr(service_priority, adn))); + EXPECT_NO_THROW(option.reset(new Option6Dnr(in_buf.begin(), in_buf.end(), true))); ASSERT_TRUE(option); // Prepare on-wire format of the option. @@ -588,7 +634,7 @@ TEST(Option6DnrTest, packAdnOnlyMode) { 0x00, D6O_V6_DNR, // Option code 0x00, 24, // Option len=24 dec 0x00, 0x09, // Service priority is 9 dec - 0x00, 0x14, // ADN Length is 20 dec + 0x00, 20, // ADN Length is 20 dec 0x06, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: myhost. 0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example. 0x03, 0x63, 0x6F, 0x6D, 0x00 // com. @@ -605,17 +651,16 @@ TEST(Option6DnrTest, packAdnOnlyMode) { // This test verifies on-wire format of the option is correctly created when // IP addresses and Svc Params are also included. TEST(Option6DnrTest, pack) { - // Prepare example parameters. - const uint16_t service_priority = 9; - const std::string adn = "myhost.example.com."; - Option6Dnr::AddressContainer addresses; - addresses.push_back(isc::asiolink::IOAddress("2001:db8:1::dead:beef")); - addresses.push_back(isc::asiolink::IOAddress("ff02::face:b00c")); - const std::string svc_params = "alpn"; + // Prepare example config. + const std::string config = "9, myhost.example.com., 2001:db8:1::dead:beef ff02::face:b00c," + " alpn=imap"; + + OptionBuffer in_buf; + in_buf.assign(config.begin(), config.end()); // Create option instance. Check that constructor doesn't throw. Option6DnrPtr option; - EXPECT_NO_THROW(option.reset(new Option6Dnr(service_priority, adn, addresses, svc_params))); + EXPECT_NO_THROW(option.reset(new Option6Dnr(in_buf.begin(), in_buf.end(), true))); ASSERT_TRUE(option); // Prepare on-wire format of the option. @@ -624,19 +669,21 @@ TEST(Option6DnrTest, pack) { // Prepare reference data. const uint8_t ref_data[] = { - 0x00, D6O_V6_DNR, // Option code - 0x00, 62, // Option len=62 dec - 0x00, 0x09, // Service priority is 9 dec - 0x00, 0x14, // ADN Length is 20 dec - 0x06, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: myhost. - 0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example. - 0x03, 0x63, 0x6F, 0x6D, 0x00, // com. - 0x00, 0x20, // Addr Len field value = 32 dec - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef - 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ff02::face:b00c - 0x00, 0x00, 0x00, 0x00, 0xfa, 0xce, 0xb0, 0x0c, - 'a', 'l', 'p', 'n' // Svc Params + 0x00, D6O_V6_DNR, // Option code + 0x00, 67, // Option len=67 dec + 0x00, 0x09, // Service priority is 9 dec + 0x00, 0x14, // ADN Length is 20 dec + 0x06, 0x6D, 0x79, 0x68, 0x6F, 0x73, 0x74, // FQDN: myhost. + 0x07, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, // example. + 0x03, 0x63, 0x6F, 0x6D, 0x00, // com. + 0x00, 0x20, // Addr Len field value = 32 dec + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, // 2001:db8:1::dead:beef + 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xff, 0x02, // + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ff02::face:b00c + 0x00, 0x00, 0x00, 0x00, 0xfa, 0xce, 0xb0, 0x0c, // + 0, 1, // SvcParamKey alpn + 0, 5, // SvcParamVal len + 4, 'i', 'm', 'a', 'p' // alpn-id }; size_t ref_data_size = sizeof(ref_data) / sizeof(ref_data[0]); |