]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4565] Checkpoint: extended to IA6
authorFrancis Dupont <fdupont@isc.org>
Mon, 8 Jun 2026 23:08:14 +0000 (01:08 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 16 Jun 2026 13:53:38 +0000 (15:53 +0200)
src/lib/dhcp/option6_ia.cc
src/lib/dhcp/option6_ia.h
src/lib/dhcp/option_custom.cc
src/lib/dhcp/option_custom.h
src/lib/dhcp/option_definition.cc
src/lib/dhcp/option_definition.h

index 7186399d70a3dbbb852a9062d821dfe9c5f4a859..5ec9f9cd7376b6946538e64a885676a9d2a40c36 100644 (file)
@@ -35,7 +35,7 @@ Option6IA::Option6IA(uint16_t type, uint32_t iaid)
 }
 
 Option6IA::Option6IA(uint16_t type, OptionBufferConstIter begin,
-                     OptionBufferConstIter end)
+                     OptionBufferConstIter end, size_t rec_level)
     :Option(Option::V6, type) {
 
     // IA_TA has different layout than IA_NA and IA_PD. We can't use this class
@@ -46,7 +46,7 @@ Option6IA::Option6IA(uint16_t type, OptionBufferConstIter begin,
 
     setEncapsulatedSpace(DHCP6_OPTION_SPACE);
 
-    unpack(begin, end);
+    unpack(begin, end, rec_level);
 }
 
 OptionPtr
@@ -66,6 +66,12 @@ void Option6IA::pack(isc::util::OutputBuffer& buf, bool) const {
 
 void Option6IA::unpack(OptionBufferConstIter begin,
                        OptionBufferConstIter end) {
+    unpack(begin, end, 0);
+}
+
+void Option6IA::unpack(OptionBufferConstIter begin,
+                       OptionBufferConstIter end,
+                       size_t rec_level) {
     // IA_NA and IA_PD have 12 bytes content (iaid, t1, t2 fields)
     // followed by 0 or more sub-options.
     if (static_cast<size_t>(distance(begin, end)) < OPTION6_IA_LEN) {
@@ -79,7 +85,7 @@ void Option6IA::unpack(OptionBufferConstIter begin,
     t2_ = readUint32(&(*begin), distance(begin, end));
     begin += sizeof(uint32_t);
 
-    unpackOptions(OptionBuffer(begin, end));
+    unpackOptions(OptionBuffer(begin, end), rec_level);
 }
 
 std::string Option6IA::toText(int indent) const {
index 9ea7c3e4c24d13a4390b451a7e25e2cd26168b9e..ca1bb4223cef3ba1cda2d4a4879486c353a197ab 100644 (file)
@@ -36,8 +36,9 @@ public:
     /// @param type option type (usually 4 for IA_NA, 25 for IA_PD)
     /// @param begin iterator to first byte of option data
     /// @param end iterator to end of option data (first byte after option end)
+    /// @param rec_level recursion level.
     Option6IA(uint16_t type, OptionBuffer::const_iterator begin,
-              OptionBuffer::const_iterator end);
+              OptionBuffer::const_iterator end, size_t rec_level = 0);
 
     /// @brief Copies this option and returns a pointer to the copy.
     virtual OptionPtr clone() const;
@@ -58,6 +59,14 @@ public:
     /// @param end iterator to end of option data (first byte after option end)
     virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end);
 
+    /// @brief Parses received buffer with limited recursion.
+    ///
+    /// @param begin iterator to first byte of option data
+    /// @param end iterator to end of option data (first byte after option end)
+    /// @param rec_level recursion level.
+    void unpack(OptionBufferConstIter begin, OptionBufferConstIter end,
+                size_t rec_level);
+
     /// Provides human readable text representation
     ///
     /// @param indent number of leading space characters
index 2aaf0880f639f92255c3631a20b37f23bad2bb2a..db5eb69741536814c96bc7d3cfc8feae4b77e8cd 100644 (file)
@@ -35,16 +35,6 @@ OptionCustom::OptionCustom(const OptionDefinition& def,
     createBuffers(getData());
 }
 
-OptionCustom::OptionCustom(const OptionDefinition& def,
-                           Universe u,
-                           OptionBufferConstIter first,
-                           OptionBufferConstIter last)
-    : Option(u, def.getCode(), first, last),
-      definition_(def) {
-    setEncapsulatedSpace(def.getEncapsulatedSpace());
-    createBuffers(getData());
-}
-
 OptionCustom::OptionCustom(const OptionDefinition& def,
                            Universe u,
                            OptionBufferConstIter first,
index 61c143befc36ce181dff803aec663f74bd2f5474..45197aecbfc35417ec18fc9fb6435e965d581b71 100644 (file)
@@ -59,7 +59,7 @@ public:
     /// @todo list all exceptions thrown by ctor.
     OptionCustom(const OptionDefinition& def, Universe u, const OptionBuffer& data);
 
-    /// @brief Constructor, used for received options.
+    /// @brief Constructor, used for received options with limited recursion.
     ///
     /// This constructor creates an instance an option from the portion
     /// of the buffer specified by iterators. This is mainly useful when
@@ -73,20 +73,6 @@ public:
     /// @param first iterator to the first element that should be copied.
     /// @param last iterator to the next element after the last one
     /// to be copied.
-    ///
-    /// @throw OutOfRange if option buffer is truncated.
-    ///
-    /// @todo list all exceptions thrown by ctor.
-    OptionCustom(const OptionDefinition& def, Universe u,
-                 OptionBufferConstIter first, OptionBufferConstIter last);
-
-    /// @brief Constructor, used for received options with limited recursion.
-    ///
-    /// @param def option definition.
-    /// @param u specifies universe (V4 or V6).
-    /// @param first iterator to the first element that should be copied.
-    /// @param last iterator to the next element after the last one
-    /// to be copied.
     /// @param rec_level recursion level.
     ///
     /// @throw OutOfRange if option buffer is truncated.
@@ -94,7 +80,7 @@ public:
     /// @todo list all exceptions thrown by ctor.
     OptionCustom(const OptionDefinition& def, Universe u,
                  OptionBufferConstIter first, OptionBufferConstIter last,
-                 size_t rec_level);
+                 size_t rec_level = 0);
 
     /// @brief Copies this option and returns a pointer to the copy.
     virtual OptionPtr clone() const;
index 29d47af5fa13a1625970e1081c116cb560b10a7d..bcf3a75a0ef2d87963bb941ddae3d0ad74d29292 100644 (file)
@@ -197,7 +197,9 @@ OptionDefinition::optionFactory(Option::Universe u,
         // type to be returned. Therefore, we first check that if we are dealing
         // with such an option. If the instance is returned we just exit at this
         // point. If not, we will search for a generic option type to return.
-        OptionPtr option = factorySpecialFormatOption(u, begin, end, convenient_notation);
+        OptionPtr option = factorySpecialFormatOption(u, begin, end,
+                                                      convenient_notation,
+                                                      rec_level);
         if (option) {
             return (option);
         }
@@ -773,13 +775,14 @@ OptionDefinition::factoryGeneric(Option::Universe u, uint16_t type,
 OptionPtr
 OptionDefinition::factoryIA6(uint16_t type,
                              OptionBufferConstIter begin,
-                             OptionBufferConstIter end) {
+                             OptionBufferConstIter end,
+                             size_t rec_level) {
     if (static_cast<size_t>(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");
     }
-    boost::shared_ptr<Option6IA> option(new Option6IA(type, begin, end));
+    boost::shared_ptr<Option6IA> option(new Option6IA(type, begin, end, rec_level));
     return (option);
 }
 
@@ -874,13 +877,14 @@ OptionPtr
 OptionDefinition::factorySpecialFormatOption(Option::Universe u,
                                              OptionBufferConstIter begin,
                                              OptionBufferConstIter end,
-                                             bool convenient_notation) const {
+                                             bool convenient_notation,
+                                             size_t rec_level) const {
     if ((u == Option::V6) && haveSpace(DHCP6_OPTION_SPACE)) {
         switch (getCode()) {
         case D6O_IA_NA:
         case D6O_IA_PD:
             // Record of 3 uint32, no array.
-            return (factoryIA6(getCode(), begin, end));
+            return (factoryIA6(getCode(), begin, end, rec_level));
 
         case D6O_IAADDR:
             // Record of an IPv6 address followed by 2 uint32, no array.
index 3bbede8deebe9523a1940cb9731574b278dc2e12..c9c8f8c419f666d14ccea03174bbf485739f9447 100644 (file)
@@ -543,12 +543,14 @@ public:
     /// @param type option type.
     /// @param begin iterator pointing to the beginning of the buffer.
     /// @param end iterator pointing to the end of the buffer.
+    /// @param rec_level recursion level.
     ///
     /// @throw isc::OutOfRange if provided option buffer is too short or
     /// too long. Expected size is 12 bytes.
     static OptionPtr factoryIA6(uint16_t type,
                                 OptionBufferConstIter begin,
-                                OptionBufferConstIter end);
+                                OptionBufferConstIter end,
+                                size_t rec_level = 0);
 
     /// @brief Factory for IAADDR-type of option.
     ///
@@ -682,6 +684,7 @@ private:
     ///                            as a string formatted in user-friendly, convenient way.
     ///                            The flag is propagated to the option constructor, so that
     ///                            the data could be parsed properly. Defaults to false.
+    /// @param rec_level recursion level.
     ///
     /// @return An instance of the option having special format or NULL if
     /// such an option can't be created because an option with the given
@@ -689,7 +692,8 @@ private:
     OptionPtr factorySpecialFormatOption(Option::Universe u,
                                          OptionBufferConstIter begin,
                                          OptionBufferConstIter end,
-                                         bool convenient_notation = false) const;
+                                         bool convenient_notation = false,
+                                         size_t rec_level = 0) const;
 
     /// @brief Check if specified type matches option definition type.
     ///