BIND 10 trac3036, updated. d803eeaf3f71b0f68d26fde29802adf2a55fa31d [3036] Return instance of Option6ClientFqdn for option 39.

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jul 18 15:04:49 UTC 2013


The branch, trac3036 has been updated
       via  d803eeaf3f71b0f68d26fde29802adf2a55fa31d (commit)
      from  8b1aa00503272f26a9f0a0271cdea93aab3b3295 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d803eeaf3f71b0f68d26fde29802adf2a55fa31d
Author: Marcin Siodelski <marcin at isc.org>
Date:   Thu Jul 18 17:01:11 2013 +0200

    [3036] Return instance of Option6ClientFqdn for option 39.
    
    Also folded long lines in OptionDefinition implementation.

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dhcp/option_definition.cc                |  113 +++++++++++++++-------
 src/lib/dhcp/option_definition.h                 |    6 ++
 src/lib/dhcp/tests/libdhcp++_unittest.cc         |    4 +-
 src/lib/dhcp/tests/option_definition_unittest.cc |   19 +++-
 4 files changed, 102 insertions(+), 40 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/option_definition.cc b/src/lib/dhcp/option_definition.cc
index bf2c5fb..ac1369c 100644
--- a/src/lib/dhcp/option_definition.cc
+++ b/src/lib/dhcp/option_definition.cc
@@ -17,6 +17,7 @@
 #include <dhcp/option6_addrlst.h>
 #include <dhcp/option6_ia.h>
 #include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_client_fqdn.h>
 #include <dhcp/option_custom.h>
 #include <dhcp/option_definition.h>
 #include <dhcp/option_int.h>
@@ -101,7 +102,8 @@ OptionDefinition::addRecordField(const OptionDataType data_type) {
     if (data_type >= OPT_RECORD_TYPE ||
         data_type == OPT_ANY_ADDRESS_TYPE ||
         data_type == OPT_EMPTY_TYPE) {
-        isc_throw(isc::BadValue, "attempted to add invalid data type to the record.");
+        isc_throw(isc::BadValue,
+                  "attempted to add invalid data type to the record.");
     }
     record_fields_.push_back(data_type);
 }
@@ -127,19 +129,23 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
                     factoryInteger<int8_t>(u, type, begin, end));
 
         case OPT_UINT16_TYPE:
-            return (array_type_ ? factoryIntegerArray<uint16_t>(u, type, begin, end) :
+            return (array_type_ ?
+                    factoryIntegerArray<uint16_t>(u, type, begin, end) :
                     factoryInteger<uint16_t>(u, type, begin, end));
 
         case OPT_INT16_TYPE:
-            return (array_type_ ? factoryIntegerArray<uint16_t>(u, type, begin, end) :
+            return (array_type_ ?
+                    factoryIntegerArray<uint16_t>(u, type, begin, end) :
                     factoryInteger<int16_t>(u, type, begin, end));
 
         case OPT_UINT32_TYPE:
-            return (array_type_ ? factoryIntegerArray<uint32_t>(u, type, begin, end) :
+            return (array_type_ ?
+                    factoryIntegerArray<uint32_t>(u, type, begin, end) :
                     factoryInteger<uint32_t>(u, type, begin, end));
 
         case OPT_INT32_TYPE:
-            return (array_type_ ? factoryIntegerArray<uint32_t>(u, type, begin, end) :
+            return (array_type_ ?
+                    factoryIntegerArray<uint32_t>(u, type, begin, end) :
                     factoryInteger<int32_t>(u, type, begin, end));
 
         case OPT_IPV4_ADDRESS_TYPE:
@@ -183,6 +189,10 @@ OptionDefinition::optionFactory(Option::Universe u, uint16_t type,
                     // option only for the same reasons as described in
                     // for IA_NA and IA_PD above.
                     return (factoryIAAddr6(type, begin, end));
+                } else if (code_ == D6O_CLIENT_FQDN && haveClientFqdnFormat()) {
+                    // FQDN option requires special processing. Thus, there is
+                    // a specialized class to handle it.
+                    return (OptionPtr(new Option6ClientFqdn(begin, end)));
                 }
             }
         }
@@ -264,10 +274,12 @@ OptionDefinition::validate() const {
             // it no way to tell when other data fields begin.
             err_str << "array of strings is not a valid option definition.";
         } else if (type_ == OPT_BINARY_TYPE) {
-            err_str << "array of binary values is not a valid option definition.";
+            err_str << "array of binary values is not"
+                    << " a valid option definition.";
 
         } else if (type_ == OPT_EMPTY_TYPE) {
-            err_str << "array of empty value is not a valid option definition.";
+            err_str << "array of empty value is not"
+                    << " a valid option definition.";
 
         }
 
@@ -275,33 +287,34 @@ OptionDefinition::validate() const {
         // At least two data fields should be added to the record. Otherwise
         // non-record option definition could be used.
         if (getRecordFields().size() < 2) {
-            err_str << "invalid number of data fields: " << getRecordFields().size()
+            err_str << "invalid number of data fields: "
+                    << getRecordFields().size()
                     << " specified for the option of type 'record'. Expected at"
                     << " least 2 fields.";
 
         } else {
             // If the number of fields is valid we have to check if their order
             // is valid too. We check that string or binary data fields are not
-            // laid before other fields. But we allow that they are laid at the end of
-            // an option.
+            // laid before other fields. But we allow that they are laid at the
+            // end of an option.
             const RecordFieldsCollection& fields = getRecordFields();
             for (RecordFieldsConstIter it = fields.begin();
                  it != fields.end(); ++it) {
                 if (*it == OPT_STRING_TYPE &&
                     it < fields.end() - 1) {
-                    err_str << "string data field can't be laid before data fields"
-                            << " of other types.";
+                    err_str << "string data field can't be laid before data"
+                            << " fields of other types.";
                     break;
                 }
                 if (*it == OPT_BINARY_TYPE &&
                     it < fields.end() - 1) {
-                    err_str << "binary data field can't be laid before data fields"
-                            << " of other types.";
+                    err_str << "binary data field can't be laid before data"
+                            << " fields of other types.";
                 }
                 /// Empty type is not allowed within a record.
                 if (*it == OPT_EMPTY_TYPE) {
-                    err_str << "empty data type can't be stored as a field in an"
-                            << " option record.";
+                    err_str << "empty data type can't be stored as a field in"
+                            << " an option record.";
                     break;
                 }
             }
@@ -341,13 +354,24 @@ OptionDefinition::haveIAAddr6Format() const {
     return (haveIAx6Format(OPT_IPV6_ADDRESS_TYPE));
 }
 
+bool
+OptionDefinition::haveClientFqdnFormat() const {
+    return (haveType(OPT_RECORD_TYPE) &&
+            (record_fields_.size() == 2) &&
+            (record_fields_[0] == OPT_UINT8_TYPE) &&
+            (record_fields_[1] == OPT_FQDN_TYPE));
+}
+
 template<typename T>
-T OptionDefinition::lexicalCastWithRangeCheck(const std::string& value_str) const {
+T
+OptionDefinition::lexicalCastWithRangeCheck(const std::string& value_str)
+    const {
     // Lexical cast in case of our data types make sense only
     // for uintX_t, intX_t and bool type.
     if (!OptionDataTypeTraits<T>::integer_type &&
         OptionDataTypeTraits<T>::type != OPT_BOOLEAN_TYPE) {
-        isc_throw(BadDataTypeCast, "unable to do lexical cast to non-integer and"
+        isc_throw(BadDataTypeCast,
+                  "unable to do lexical cast to non-integer and"
                   << " non-boolean data type");
     }
     // We use the 64-bit value here because it has wider range than
@@ -364,16 +388,18 @@ T OptionDefinition::lexicalCastWithRangeCheck(const std::string& value_str) cons
         if (OptionDataTypeTraits<T>::integer_type) {
             data_type_str = "integer";
         }
-        isc_throw(BadDataTypeCast, "unable to do lexical cast to " << data_type_str
-                  << " data type for value " << value_str << ": " << ex.what());
+        isc_throw(BadDataTypeCast, "unable to do lexical cast to "
+                  << data_type_str << " data type for value "
+                  << value_str << ": " << ex.what());
     }
     // Perform range checks for integer values only (exclude bool values).
     if (OptionDataTypeTraits<T>::integer_type) {
         if (result > numeric_limits<T>::max() ||
             result < numeric_limits<T>::min()) {
             isc_throw(BadDataTypeCast, "unable to do lexical cast for value "
-                      << value_str << ". This value is expected to be in the range of "
-                      << numeric_limits<T>::min() << ".." << numeric_limits<T>::max());
+                      << value_str << ". This value is expected to be"
+                      << " in the range of " << numeric_limits<T>::min()
+                      << ".." << numeric_limits<T>::max());
         }
     }
     return (static_cast<T>(result));
@@ -395,30 +421,37 @@ OptionDefinition::writeToBuffer(const std::string& value,
         // That way we actually waste 7 bits but it seems to be the
         // simpler way to encode boolean.
         // @todo Consider if any other encode methods can be used.
-        OptionDataTypeUtil::writeBool(lexicalCastWithRangeCheck<bool>(value), buf);
+        OptionDataTypeUtil::writeBool(lexicalCastWithRangeCheck<bool>(value),
+                                      buf);
         return;
     case OPT_INT8_TYPE:
-        OptionDataTypeUtil::writeInt<uint8_t>(lexicalCastWithRangeCheck<int8_t>(value),
+        OptionDataTypeUtil::writeInt<uint8_t>
+            (lexicalCastWithRangeCheck<int8_t>(value),
                                               buf);
         return;
     case OPT_INT16_TYPE:
-        OptionDataTypeUtil::writeInt<uint16_t>(lexicalCastWithRangeCheck<int16_t>(value),
+        OptionDataTypeUtil::writeInt<uint16_t>
+            (lexicalCastWithRangeCheck<int16_t>(value),
                                                buf);
         return;
     case OPT_INT32_TYPE:
-        OptionDataTypeUtil::writeInt<uint32_t>(lexicalCastWithRangeCheck<int32_t>(value),
+        OptionDataTypeUtil::writeInt<uint32_t>
+            (lexicalCastWithRangeCheck<int32_t>(value),
                                                buf);
         return;
     case OPT_UINT8_TYPE:
-        OptionDataTypeUtil::writeInt<uint8_t>(lexicalCastWithRangeCheck<uint8_t>(value),
+        OptionDataTypeUtil::writeInt<uint8_t>
+            (lexicalCastWithRangeCheck<uint8_t>(value),
                                               buf);
         return;
     case OPT_UINT16_TYPE:
-        OptionDataTypeUtil::writeInt<uint16_t>(lexicalCastWithRangeCheck<uint16_t>(value),
+        OptionDataTypeUtil::writeInt<uint16_t>
+            (lexicalCastWithRangeCheck<uint16_t>(value),
                                                buf);
         return;
     case OPT_UINT32_TYPE:
-        OptionDataTypeUtil::writeInt<uint32_t>(lexicalCastWithRangeCheck<uint32_t>(value),
+        OptionDataTypeUtil::writeInt<uint32_t>
+            (lexicalCastWithRangeCheck<uint32_t>(value),
                                                buf);
         return;
     case OPT_IPV4_ADDRESS_TYPE:
@@ -426,7 +459,8 @@ OptionDefinition::writeToBuffer(const std::string& value,
         {
             asiolink::IOAddress address(value);
             if (!address.isV4() && !address.isV6()) {
-                isc_throw(BadDataTypeCast, "provided address " << address.toText()
+                isc_throw(BadDataTypeCast, "provided address "
+                          << address.toText()
                           << " is not a valid IPv4 or IPv6 address.");
             }
             OptionDataTypeUtil::writeAddress(address, buf);
@@ -454,7 +488,8 @@ OptionPtr
 OptionDefinition::factoryAddrList4(uint16_t type,
                                   OptionBufferConstIter begin,
                                   OptionBufferConstIter end) {
-    boost::shared_ptr<Option4AddrLst> option(new Option4AddrLst(type, begin, end));
+    boost::shared_ptr<Option4AddrLst> option(new Option4AddrLst(type, begin,
+                                                                end));
     return (option);
 }
 
@@ -462,7 +497,8 @@ OptionPtr
 OptionDefinition::factoryAddrList6(uint16_t type,
                                    OptionBufferConstIter begin,
                                    OptionBufferConstIter end) {
-    boost::shared_ptr<Option6AddrLst> option(new Option6AddrLst(type, begin, end));
+    boost::shared_ptr<Option6AddrLst> option(new Option6AddrLst(type, begin,
+                                                                end));
     return (option);
 }
 
@@ -486,8 +522,9 @@ OptionDefinition::factoryIA6(uint16_t type,
                              OptionBufferConstIter begin,
                              OptionBufferConstIter end) {
     if (std::distance(begin, end) < Option6IA::OPTION6_IA_LEN) {
-        isc_throw(isc::OutOfRange, "input option buffer has invalid size, expected "
-                  "at least " << Option6IA::OPTION6_IA_LEN << " bytes");
+        isc_throw(isc::OutOfRange, "input option buffer has invalid size,"
+                  << " expected at least " << Option6IA::OPTION6_IA_LEN
+                  << " bytes");
     }
     boost::shared_ptr<Option6IA> option(new Option6IA(type, begin, end));
     return (option);
@@ -498,10 +535,12 @@ OptionDefinition::factoryIAAddr6(uint16_t type,
                                  OptionBufferConstIter begin,
                                  OptionBufferConstIter end) {
     if (std::distance(begin, end) < Option6IAAddr::OPTION6_IAADDR_LEN) {
-        isc_throw(isc::OutOfRange, "input option buffer has invalid size, expected "
-                  " at least " << Option6IAAddr::OPTION6_IAADDR_LEN << " bytes");
+        isc_throw(isc::OutOfRange,
+                  "input option buffer has invalid size, expected at least "
+                  << Option6IAAddr::OPTION6_IAADDR_LEN << " bytes");
     }
-    boost::shared_ptr<Option6IAAddr> option(new Option6IAAddr(type, begin, end));
+    boost::shared_ptr<Option6IAAddr> option(new Option6IAAddr(type, begin,
+                                                              end));
     return (option);
 }
 
diff --git a/src/lib/dhcp/option_definition.h b/src/lib/dhcp/option_definition.h
index dcfc3c7..99a57f5 100644
--- a/src/lib/dhcp/option_definition.h
+++ b/src/lib/dhcp/option_definition.h
@@ -275,6 +275,12 @@ public:
     /// @return true if specified format is IAADDR option format.
     bool haveIAAddr6Format() const;
 
+    /// @brief Check if specified format is OPTION_CLIENT_FQDN option format.
+    ///
+    /// @return true of specified format is OPTION_CLIENT_FQDN option format,
+    /// false otherwise.
+    bool haveClientFqdnFormat() const;
+
     /// @brief Option factory.
     ///
     /// This function creates an instance of DHCP option using
diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc
index d523158..dad4ad5 100644
--- a/src/lib/dhcp/tests/libdhcp++_unittest.cc
+++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc
@@ -19,6 +19,7 @@
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option4_addrlst.h>
 #include <dhcp/option6_addrlst.h>
+#include <dhcp/option6_client_fqdn.h>
 #include <dhcp/option6_ia.h>
 #include <dhcp/option6_iaaddr.h>
 #include <dhcp/option_custom.h>
@@ -905,7 +906,8 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
                                     typeid(Option));
 
     LibDhcpTest::testStdOptionDefs6(D6O_CLIENT_FQDN, client_fqdn_buf.begin(),
-                                    client_fqdn_buf.end(), typeid(OptionCustom));
+                                    client_fqdn_buf.end(),
+                                    typeid(Option6ClientFqdn));
 
     LibDhcpTest::testStdOptionDefs6(D6O_PANA_AGENT, begin, end,
                                     typeid(Option6AddrLst));
diff --git a/src/lib/dhcp/tests/option_definition_unittest.cc b/src/lib/dhcp/tests/option_definition_unittest.cc
index f7602a6..d3b766d 100644
--- a/src/lib/dhcp/tests/option_definition_unittest.cc
+++ b/src/lib/dhcp/tests/option_definition_unittest.cc
@@ -928,7 +928,7 @@ TEST_F(OptionDefinitionTest, utf8StringTokenized) {
     // Let's create some dummy option.
     const uint16_t opt_code = 80;
     OptionDefinition opt_def("OPTION_WITH_STRING", opt_code, "string");
-    
+
     std::vector<std::string> values;
     values.push_back("Hello World");
     values.push_back("this string should not be included in the option");
@@ -960,7 +960,7 @@ TEST_F(OptionDefinitionTest, integerInvalidType) {
 // The purpose of this test is to verify that helper methods
 // haveIA6Format and haveIAAddr6Format can be used to determine
 // IA_NA  and IAADDR option formats.
-TEST_F(OptionDefinitionTest, recognizeFormat) {
+TEST_F(OptionDefinitionTest, haveIAFormat) {
     // IA_NA option format.
     OptionDefinition opt_def1("OPTION_IA_NA", D6O_IA_NA, "record");
     for (int i = 0; i < 3; ++i) {
@@ -984,4 +984,19 @@ TEST_F(OptionDefinitionTest, recognizeFormat) {
     EXPECT_FALSE(opt_def4.haveIAAddr6Format());
 }
 
+// This test verifies that haveClientFqdnFormat function recognizes that option
+// definition describes the format of DHCPv6 Client Fqdn Option Format.
+TEST_F(OptionDefinitionTest, haveClientFqdnFormat) {
+    OptionDefinition opt_def("OPTION_CLIENT_FQDN", D6O_CLIENT_FQDN, "record");
+    opt_def.addRecordField("uint8");
+    opt_def.addRecordField("fqdn");
+    EXPECT_TRUE(opt_def.haveClientFqdnFormat());
+
+    // Create option format which is not matching the Client FQDN option format
+    // to verify that tested function does dont always return true.
+    OptionDefinition opt_def_invalid("OPTION_CLIENT_FQDN", D6O_CLIENT_FQDN,
+                                     "uint8");
+    EXPECT_FALSE(opt_def_invalid.haveClientFqdnFormat());
+}
+
 } // anonymous namespace



More information about the bind10-changes mailing list