Browse Source

[3203] Client classes in packets added.

Tomek Mrugalski 11 years ago
parent
commit
e1f810f294

+ 12 - 0
src/lib/dhcp/pkt4.cc

@@ -463,6 +463,18 @@ Pkt4::updateTimestamp() {
     timestamp_ = boost::posix_time::microsec_clock::universal_time();
     timestamp_ = boost::posix_time::microsec_clock::universal_time();
 }
 }
 
 
+bool
+Pkt4::inClass(const std::string& client_class) {
+    return (classes_.find(client_class) != classes_.end());
+}
+
+void
+Pkt4::addClass(const std::string& client_class) {
+    if (classes_.find(client_class) == classes_.end()) {
+        classes_.insert(client_class);
+    }
+}
+
 } // end of namespace isc::dhcp
 } // end of namespace isc::dhcp
 
 
 } // end of namespace isc
 } // end of namespace isc

+ 25 - 0
src/lib/dhcp/pkt4.h

@@ -26,6 +26,7 @@
 
 
 #include <iostream>
 #include <iostream>
 #include <vector>
 #include <vector>
+#include <set>
 
 
 #include <time.h>
 #include <time.h>
 
 
@@ -52,6 +53,9 @@ public:
     /// to check whether client requested broadcast response.
     /// to check whether client requested broadcast response.
     const static uint16_t FLAG_BROADCAST_MASK = 0x8000;
     const static uint16_t FLAG_BROADCAST_MASK = 0x8000;
 
 
+    /// Container for storing client classes
+    typedef std::set<std::string> Classes;
+
     /// Constructor, used in replying to a message.
     /// Constructor, used in replying to a message.
     ///
     ///
     /// @param msg_type type of message (e.g. DHCPDISOVER=1)
     /// @param msg_type type of message (e.g. DHCPDISOVER=1)
@@ -532,6 +536,27 @@ public:
     /// performance).
     /// performance).
     std::vector<uint8_t> data_;
     std::vector<uint8_t> data_;
 
 
+    /// @brief Checks whether a client belongs to a given class
+    ///
+    /// @param client_class name of the class
+    /// @return true if belongs
+    bool inClass(const std::string& client_class);
+
+    /// @brief Adds packet to a specified class
+    ///
+    /// A packet can be added to the same class repeatedly. Any additional
+    /// attempts to add to a class the packet already belongs to, will be
+    /// ignored silently.
+    ///
+    /// @param client_class name of the class to be added
+    void addClass(const std::string& client_class);
+
+    /// @brief Classes this packet belongs to.
+    ///
+    /// This field is public, so code can iterate over existing classes.
+    /// Having it public also solves the problem of returned reference lifetime.
+    Classes classes_;
+
 private:
 private:
 
 
     /// @brief Generic method that validates and sets HW address.
     /// @brief Generic method that validates and sets HW address.

+ 11 - 0
src/lib/dhcp/pkt6.cc

@@ -586,6 +586,17 @@ void Pkt6::copyRelayInfo(const Pkt6Ptr& question) {
     }
     }
 }
 }
 
 
+bool
+Pkt6::inClass(const std::string& client_class) {
+    return (classes_.find(client_class) != classes_.end());
+}
+
+void
+Pkt6::addClass(const std::string& client_class) {
+    if (classes_.find(client_class) == classes_.end()) {
+        classes_.insert(client_class);
+    }
+}
 
 
 } // end of isc::dhcp namespace
 } // end of isc::dhcp namespace
 } // end of isc namespace
 } // end of isc namespace

+ 25 - 0
src/lib/dhcp/pkt6.h

@@ -23,6 +23,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 
 
 #include <iostream>
 #include <iostream>
+#include <set>
 
 
 #include <time.h>
 #include <time.h>
 
 
@@ -47,6 +48,9 @@ public:
         TCP = 1  // there are TCP DHCPv6 packets (bulk leasequery, failover)
         TCP = 1  // there are TCP DHCPv6 packets (bulk leasequery, failover)
     };
     };
 
 
+    /// Container for storing client classes
+    typedef std::set<std::string> Classes;
+
     /// @brief defines relay search pattern
     /// @brief defines relay search pattern
     ///
     ///
     /// Defines order in which options are searched in a message that
     /// Defines order in which options are searched in a message that
@@ -426,6 +430,27 @@ public:
     /// data format change etc.
     /// data format change etc.
     OptionBuffer data_;
     OptionBuffer data_;
 
 
+    /// @brief Checks whether a client belongs to a given class
+    ///
+    /// @param client_class name of the class
+    /// @return true if belongs
+    bool inClass(const std::string& client_class);
+
+    /// @brief Adds packet to a specified class
+    ///
+    /// A packet can be added to the same class repeatedly. Any additional
+    /// attempts to add to a class the packet already belongs to, will be
+    /// ignored silently.
+    ///
+    /// @param client_class name of the class to be added
+    void addClass(const std::string& client_class);
+
+    /// @brief Classes this packet belongs to.
+    ///
+    /// This field is public, so code can iterate over existing classes.
+    /// Having it public also solves the problem of returned reference lifetime.
+    Classes classes_;
+
 protected:
 protected:
     /// Builds on wire packet for TCP transmission.
     /// Builds on wire packet for TCP transmission.
     ///
     ///

+ 27 - 0
src/lib/dhcp/tests/pkt4_unittest.cc

@@ -798,4 +798,31 @@ TEST_F(Pkt4Test, hwaddrSrcRemote) {
                            remote_addr->hwaddr_.begin()));
                            remote_addr->hwaddr_.begin()));
 }
 }
 
 
+// Tests whether a packet can be assigned to a class and later
+// checked if it belongs to a given class
+TEST_F(Pkt4Test, clientClasses) {
+    Pkt4 pkt(DHCPOFFER, 1234);
+
+    // Default values (do not belong to any class)
+    EXPECT_FALSE(pkt.inClass("eRouter1.0"));
+    EXPECT_FALSE(pkt.inClass("docsis3.0"));
+    EXPECT_TRUE(pkt.classes_.empty());
+
+    // Add to the first class
+    pkt.addClass("eRouter1.0");
+    EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+    EXPECT_FALSE(pkt.inClass("docsis3.0"));
+    ASSERT_FALSE(pkt.classes_.empty());
+
+    // Add to a second class
+    pkt.addClass("docsis3.0");
+    EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+    EXPECT_TRUE(pkt.inClass("docsis3.0"));
+
+    // Check that it's ok to add to the same class repeatedly
+    EXPECT_NO_THROW(pkt.addClass("foo"));
+    EXPECT_NO_THROW(pkt.addClass("foo"));
+    EXPECT_NO_THROW(pkt.addClass("foo"));
+}
+
 } // end of anonymous namespace
 } // end of anonymous namespace

+ 27 - 0
src/lib/dhcp/tests/pkt6_unittest.cc

@@ -779,4 +779,31 @@ TEST_F(Pkt6Test, getAnyRelayOption) {
     EXPECT_FALSE(opt);
     EXPECT_FALSE(opt);
 }
 }
 
 
+// Tests whether a packet can be assigned to a class and later
+// checked if it belongs to a given class
+TEST_F(Pkt6Test, clientClasses) {
+    Pkt6 pkt(DHCPV6_ADVERTISE, 1234);
+
+    // Default values (do not belong to any class)
+    EXPECT_FALSE(pkt.inClass("eRouter1.0"));
+    EXPECT_FALSE(pkt.inClass("docsis3.0"));
+    EXPECT_TRUE(pkt.classes_.empty());
+
+    // Add to the first class
+    pkt.addClass("eRouter1.0");
+    EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+    EXPECT_FALSE(pkt.inClass("docsis3.0"));
+    ASSERT_FALSE(pkt.classes_.empty());
+
+    // Add to a second class
+    pkt.addClass("docsis3.0");
+    EXPECT_TRUE(pkt.inClass("eRouter1.0"));
+    EXPECT_TRUE(pkt.inClass("docsis3.0"));
+
+    // Check that it's ok to add to the same class repeatedly
+    EXPECT_NO_THROW(pkt.addClass("foo"));
+    EXPECT_NO_THROW(pkt.addClass("foo"));
+    EXPECT_NO_THROW(pkt.addClass("foo"));
+}
+
 }
 }