]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#939] Refactor Length Field Type evaluation for tuples
authorPiotrek Zadroga <piotrek@isc.org>
Wed, 15 Mar 2023 22:34:15 +0000 (23:34 +0100)
committerPiotrek Zadroga <piotrek@isc.org>
Thu, 23 Mar 2023 13:51:23 +0000 (14:51 +0100)
src/lib/dhcp/option_custom.cc
src/lib/dhcp/option_data_types.cc
src/lib/dhcp/option_data_types.h
src/lib/dhcp/option_definition.cc
src/lib/dhcp/option_opaque_data_tuples.h
src/lib/dhcp/option_vendor_class.cc
src/lib/dhcp/option_vendor_class.h

index 301e883efbd6774e5ef0ebf17d9577b78cb94398..b10aeb17b6b9e23af99a650e88b7e4fdbdf9efb9 100644 (file)
@@ -69,8 +69,7 @@ void
 OptionCustom::addArrayDataField(const std::string& value) {
     checkArrayType();
 
-    OpaqueDataTuple::LengthFieldType lft = getUniverse() == Option::V4 ?
-        OpaqueDataTuple::LENGTH_1_BYTE : OpaqueDataTuple::LENGTH_2_BYTES;
+    OpaqueDataTuple::LengthFieldType lft = OptionDataTypeUtil::getTupleLenFieldType(getUniverse());
     OptionBuffer buf;
     OptionDataTypeUtil::writeTuple(value, lft, buf);
     buffers_.push_back(buf);
@@ -256,9 +255,7 @@ OptionCustom::bufferLength(const OptionDataType data_type, bool in_array,
             data_size = sizeof(uint8_t) + (prefix.first.asUint8() + 7) / 8;
         } else if (data_type == OPT_TUPLE_TYPE) {
             OpaqueDataTuple::LengthFieldType lft =
-                getUniverse() == Option::V4 ?
-                OpaqueDataTuple::LENGTH_1_BYTE :
-                OpaqueDataTuple::LENGTH_2_BYTES;
+                OptionDataTypeUtil::getTupleLenFieldType(getUniverse());
             std::string value =
                 OptionDataTypeUtil::readTuple(OptionBuffer(begin, end), lft);
             data_size = value.size();
@@ -528,8 +525,7 @@ OptionCustom::writeBinary(const OptionBuffer& buf,
 std::string
 OptionCustom::readTuple(const uint32_t index) const {
     checkIndex(index);
-    OpaqueDataTuple::LengthFieldType lft = getUniverse() == Option::V4 ?
-        OpaqueDataTuple::LENGTH_1_BYTE : OpaqueDataTuple::LENGTH_2_BYTES;
+    OpaqueDataTuple::LengthFieldType lft = OptionDataTypeUtil::getTupleLenFieldType(getUniverse());
     return (OptionDataTypeUtil::readTuple(buffers_[index], lft));
 }
 
@@ -545,8 +541,7 @@ OptionCustom::writeTuple(const std::string& value, const uint32_t index) {
     checkIndex(index);
 
     buffers_[index].clear();
-    OpaqueDataTuple::LengthFieldType lft = getUniverse() == Option::V4 ?
-        OpaqueDataTuple::LENGTH_1_BYTE : OpaqueDataTuple::LENGTH_2_BYTES;
+    OpaqueDataTuple::LengthFieldType lft = OptionDataTypeUtil::getTupleLenFieldType(getUniverse());
     OptionDataTypeUtil::writeTuple(value, lft, buffers_[index]);
 }
 
index 7d843bc7d671503592b971ce283f8d61c31bf7bb..31308b00d0da41c751730bad463fde6833331bc7 100644 (file)
@@ -190,6 +190,14 @@ OptionDataTypeUtil::writeBinary(const std::string& hex_str,
     buf.insert(buf.end(), binary.begin(), binary.end());
 }
 
+OpaqueDataTuple::LengthFieldType
+OptionDataTypeUtil::getTupleLenFieldType(Option::Universe u) {
+    if (u == Option::V4) {
+        return OpaqueDataTuple::LENGTH_1_BYTE;
+    }
+    return OpaqueDataTuple::LENGTH_2_BYTES;
+}
+
 std::string
 OptionDataTypeUtil::readTuple(const std::vector<uint8_t>& buf,
                               OpaqueDataTuple::LengthFieldType lengthfieldtype) {
index 3b35dea5d59308344df53b7c93d32768c1bc3805..7d506e1e67baac913fb584eceec2c13842e26e65 100644 (file)
@@ -419,6 +419,16 @@ public:
     static void writeTuple(const OpaqueDataTuple& tuple,
                            std::vector<uint8_t>& buf);
 
+    /// @brief Returns Length Field Type for a tuple.
+    ///
+    /// Returns Length Field Type for a tuple basing on the given
+    /// Option v4/v6 Universe.
+    ///
+    /// @param u specifies universe (V4 or V6)
+    /// @return By default 1 octet Length Field Type for V4 option
+    /// or 2 octets Length Field Type for V6 option
+    static OpaqueDataTuple::LengthFieldType getTupleLenFieldType(Option::Universe u);
+
     /// @brief Read boolean value from a buffer.
     ///
     /// @param buf input buffer.
index a9a6929eab1af08c24caa5afafcfd373abfeeec8..2dd86cbbe92fa0ec30db59165ee567b61012be2b 100644 (file)
@@ -669,8 +669,12 @@ OptionDefinition::writeToBuffer(Option::Universe u,
         return;
     case OPT_TUPLE_TYPE:
     {
-        OpaqueDataTuple::LengthFieldType lft = u == Option::V4 ?
-            OpaqueDataTuple::LENGTH_1_BYTE : OpaqueDataTuple::LENGTH_2_BYTES;
+        OpaqueDataTuple::LengthFieldType lft;
+        if (getCode() == DHO_V4_SZTP_REDIRECT) {
+            lft = OpaqueDataTuple::LENGTH_2_BYTES;
+        } else {
+            lft = OptionDataTypeUtil::getTupleLenFieldType(u);
+        }
         OptionDataTypeUtil::writeTuple(value, lft, buf);
         return;
     }
index 6e6f37cd1cb7aa5a048467b51720406bcd374939..7d817359ab9791c56c82ae0b23439c61187ac5b7 100644 (file)
@@ -13,6 +13,7 @@
 #include <dhcp/option.h>
 #include <util/buffer.h>
 #include <boost/shared_ptr.hpp>
+#include "option_data_types.h"
 #include <stdint.h>
 
 namespace isc {
@@ -174,8 +175,7 @@ private:
         if (prefLenFieldType_ != OpaqueDataTuple::LENGTH_EMPTY) {
             return (prefLenFieldType_);
         }
-        return (universe_ == Option::V6 ? OpaqueDataTuple::LENGTH_2_BYTES :
-                OpaqueDataTuple::LENGTH_1_BYTE);
+        return (OptionDataTypeUtil::getTupleLenFieldType(getUniverse()));
     }
 
     /// @brief Returns minimal length of the option for the given universe.
index 4236f4c2630ea657f105a5af3d6b9519e286d1ce..df4cf1cb345f005ff72926dc419f2c68210e2e2e 100644 (file)
@@ -70,7 +70,8 @@ OptionVendorClass::unpack(OptionBufferConstIter begin,
     size_t offset = 0;
     while (offset < std::distance(begin, end)) {
         // Parse a tuple.
-        OpaqueDataTuple tuple(getLengthFieldType(), begin + offset, end);
+        OpaqueDataTuple tuple(OptionDataTypeUtil::getTupleLenFieldType(getUniverse()),
+                              begin + offset, end);
         addTuple(tuple);
         // The tuple has been parsed correctly which implies that it is safe to
         // advance the offset by its total length.
@@ -105,7 +106,7 @@ OptionVendorClass::unpack(OptionBufferConstIter begin,
 
 void
 OptionVendorClass::addTuple(const OpaqueDataTuple& tuple) {
-    if (tuple.getLengthFieldType() != getLengthFieldType()) {
+    if (tuple.getLengthFieldType() != OptionDataTypeUtil::getTupleLenFieldType(getUniverse())) {
         isc_throw(isc::BadValue, "attempted to add opaque data tuple having"
                   " invalid size of the length field "
                   << tuple.getDataFieldSize() << " to Vendor Class option");
@@ -122,7 +123,7 @@ OptionVendorClass::setTuple(const size_t at, const OpaqueDataTuple& tuple) {
                   " vendor option at position " << at << " which is out of"
                   " range");
 
-    } else if (tuple.getLengthFieldType() != getLengthFieldType()) {
+    } else if (tuple.getLengthFieldType() != OptionDataTypeUtil::getTupleLenFieldType(getUniverse())) {
         isc_throw(isc::BadValue, "attempted to set opaque data tuple having"
                   " invalid size of the length field "
                   << tuple.getDataFieldSize() << " to Vendor Class option");
index 6a56d26b904c29be537847d56f13f42e9adfd7e5..71a73e99329f7ca8989926f49e04ed48187d35e2 100644 (file)
@@ -13,6 +13,7 @@
 #include <dhcp/option.h>
 #include <util/buffer.h>
 #include <boost/shared_ptr.hpp>
+#include "option_data_types.h"
 #include <stdint.h>
 
 namespace isc {
@@ -164,17 +165,6 @@ private:
         }
     }
 
-    /// @brief Returns the tuple length field type for the given universe.
-    ///
-    /// This function returns the length field type which should be used
-    /// for the opaque data tuples being added to this option.
-    ///
-    /// @return Tuple length field type for the universe this option belongs to.
-    OpaqueDataTuple::LengthFieldType getLengthFieldType() const {
-        return (getUniverse() == V4 ? OpaqueDataTuple::LENGTH_1_BYTE :
-                OpaqueDataTuple::LENGTH_2_BYTES);
-    }
-
     /// @brief Returns minimal length of the option for the given universe.
     ///
     /// For DHCPv6, The Vendor Class option mandates a 2-byte