]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5533] Introduce get[46]Any and add tests
authorFrancis Dupont <fdupont@isc.org>
Wed, 21 Feb 2018 21:46:09 +0000 (22:46 +0100)
committerFrancis Dupont <fdupont@isc.org>
Wed, 21 Feb 2018 21:46:09 +0000 (22:46 +0100)
src/lib/dhcpsrv/host_mgr.cc
src/lib/dhcpsrv/host_mgr.h
src/lib/dhcpsrv/tests/host_mgr_unittest.cc

index 5892e480f568ef99662acc94e713a9f2f7d02561..1cb45c2ddbe554f02c2dc105cb640ba2cac014f5 100644 (file)
@@ -140,10 +140,10 @@ HostMgr::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
 }
 
 ConstHostPtr
-HostMgr::get4(const SubnetID& subnet_id,
-              const Host::IdentifierType& identifier_type,
-              const uint8_t* identifier_begin,
-              const size_t identifier_len) const {
+HostMgr::get4Any(const SubnetID& subnet_id,
+                 const Host::IdentifierType& identifier_type,
+                 const uint8_t* identifier_begin,
+                 const size_t identifier_len) const {
     ConstHostPtr host = getCfgHosts()->get4(subnet_id, identifier_type,
                                             identifier_begin, identifier_len);
     if (host || alternate_sources_.empty()) {
@@ -170,10 +170,7 @@ HostMgr::get4(const SubnetID& subnet_id,
                                                identifier_len))
                 .arg((*it)->getType())
                 .arg(host->toText());
-                     
-            if (host->getNegative()) {
-                return (ConstHostPtr());
-            }
+
             return (host);
         }
     }
@@ -185,6 +182,19 @@ HostMgr::get4(const SubnetID& subnet_id,
     return (host);
 }
 
+ConstHostPtr
+HostMgr::get4(const SubnetID& subnet_id,
+              const Host::IdentifierType& identifier_type,
+              const uint8_t* identifier_begin,
+              const size_t identifier_len) const {
+    ConstHostPtr host = get4Any(subnet_id, identifier_type,
+                                identifier_begin, identifier_len);
+    if (host && host->getNegative()) {
+        return (ConstHostPtr());
+    }
+    return (host);
+}
+    
 ConstHostPtr
 HostMgr::get4(const SubnetID& subnet_id,
               const asiolink::IOAddress& address) const {
@@ -256,10 +266,10 @@ HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
 }
 
 ConstHostPtr
-HostMgr::get6(const SubnetID& subnet_id,
-              const Host::IdentifierType& identifier_type,
-              const uint8_t* identifier_begin,
-              const size_t identifier_len) const {
+HostMgr::get6Any(const SubnetID& subnet_id,
+                 const Host::IdentifierType& identifier_type,
+                 const uint8_t* identifier_begin,
+                 const size_t identifier_len) const {
     ConstHostPtr host = getCfgHosts()->get6(subnet_id, identifier_type,
                                             identifier_begin, identifier_len);
     if (host || alternate_sources_.empty()) {
@@ -288,9 +298,6 @@ HostMgr::get6(const SubnetID& subnet_id,
                     .arg((*it)->getType())
                     .arg(host->toText());
 
-                if (host->getNegative()) {
-                    return (ConstHostPtr());
-                }
                 return (host);
         }
     }
@@ -304,6 +311,19 @@ HostMgr::get6(const SubnetID& subnet_id,
     return (host);
 }
 
+ConstHostPtr
+HostMgr::get6(const SubnetID& subnet_id,
+              const Host::IdentifierType& identifier_type,
+              const uint8_t* identifier_begin,
+              const size_t identifier_len) const {
+    ConstHostPtr host = get6Any(subnet_id, identifier_type,
+                                identifier_begin, identifier_len);
+    if (host && host->getNegative()) {
+        return (ConstHostPtr());
+    }
+    return (host);
+}
+
 ConstHostPtr
 HostMgr::get6(const SubnetID& subnet_id,
               const asiolink::IOAddress& addr) const {
index dca2697efa8333b093c865739a72f0c7f125908e..fa003ac22d4d85e2f4a4f7db9e182edc486c6454 100644 (file)
@@ -170,6 +170,28 @@ public:
     get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
          const DuidPtr& duid = DuidPtr()) const;
 
+    /// @brief Returns any host connected to the IPv4 subnet.
+    ///
+    /// This method returns a single reservation for a particular host as
+    /// documented in the @c BaseHostDataSource::get4 even when the
+    /// reservation is marked as from negative caching. This allows to
+    /// overload negative caching with extra information in the user
+    /// context.
+    ///
+    /// @param subnet_id Subnet identifier.
+    /// @param identifier_type Identifier type.
+    /// @param identifier_begin Pointer to a beginning of a buffer containing
+    /// an identifier.
+    /// @param identifier_len Identifier length.
+    ///
+    /// @return Const @c Host object for which reservation has been made using
+    /// the specified identifier.
+    virtual ConstHostPtr
+    get4Any(const SubnetID& subnet_id,
+            const Host::IdentifierType& identifier_type,
+            const uint8_t* identifier_begin,
+            const size_t identifier_len) const;
+
     /// @brief Returns a host connected to the IPv4 subnet.
     ///
     /// This method returns a single reservation for a particular host as
@@ -217,6 +239,28 @@ public:
     get6(const SubnetID& subnet_id, const DuidPtr& duid,
          const HWAddrPtr& hwaddr = HWAddrPtr()) const;
 
+    /// @brief Returns any host connected to the IPv6 subnet.
+    ///
+    /// This method returns a host connected to the IPv6 subnet as described
+    /// in the @c BaseHostDataSource::get6 even when the             
+    /// reservation is marked as from negative caching. This allows to
+    /// overload negative caching with extra information in the user
+    /// context.
+    ///
+    /// @param subnet_id Subnet identifier.
+    /// @param identifier_type Identifier type.
+    /// @param identifier_begin Pointer to a beginning of a buffer containing
+    /// an identifier.
+    /// @param identifier_len Identifier length.
+    ///
+    /// @return Const @c Host object for which reservation has been made using
+    /// the specified identifier.
+    virtual ConstHostPtr
+    get6Any(const SubnetID& subnet_id,
+            const Host::IdentifierType& identifier_type,
+            const uint8_t* identifier_begin,
+            const size_t identifier_len) const;
+
     /// @brief Returns a host connected to the IPv6 subnet.
     ///
     /// This method returns a host connected to the IPv6 subnet as described
index 0a42513c02383bb872d0a2b7cb98a2b09a38d6b5..b05ea47438d308f87399e4d5957744b88e9f5981 100644 (file)
@@ -109,6 +109,10 @@ protected:
     /// from which it will be retrieved.
     void testGet4(BaseHostDataSource& data_source);
 
+    /// @brief This test verifies that it is possible to retrieve negative
+    /// cached reservation with and only with get4Any,
+    void testGet4Any();
+
     /// @brief This test verifies that it is possible to retrieve an IPv6
     /// reservation for the particular host using HostMgr.
     ///
@@ -116,6 +120,10 @@ protected:
     /// from which it will be retrieved.
     void testGet6(BaseHostDataSource& data_source);
 
+    /// @brief This test verifies that it is possible to retrieve negative
+    /// cached reservation with and only with get6Any,
+    void testGet6Any();
+
     /// @brief This test verifies that it is possible to retrieve an IPv6
     /// prefix reservation for the particular host using HostMgr.
     ///
@@ -297,6 +305,53 @@ HostMgrTest::testGet4(BaseHostDataSource& data_source) {
     EXPECT_EQ("192.0.2.5", host->getIPv4Reservation().toText());
 }
 
+void
+HostMgrTest::testGet4Any() {
+    // Initially, no host should be present.
+    ConstHostPtr host = HostMgr::instance().get4(SubnetID(1), Host::IDENT_DUID,
+                                                 &duids_[0]->getDuid()[0],
+                                                 duids_[0]->getDuid().size());
+    ASSERT_FALSE(host);
+    HostMgr::instance().get4Any(SubnetID(1), Host::IDENT_DUID,
+                                &duids_[0]->getDuid()[0],
+                                duids_[0]->getDuid().size());
+    ASSERT_FALSE(host);
+
+    // Add new host to the database.
+    HostPtr new_host(new Host(duids_[0]->toText(), "duid", SubnetID(1),
+                              SubnetID(0), IOAddress("192.0.2.5")));
+    // Abuse of the server's configuration.
+    getCfgHosts()->add(new_host);
+                           
+    CfgMgr::instance().commit();
+
+    // Retrieve the host from the database and expect that the parameters match.
+    host = HostMgr::instance().get4(SubnetID(1), Host::IDENT_DUID,
+                                    &duids_[0]->getDuid()[0],
+                                    duids_[0]->getDuid().size());
+    ASSERT_TRUE(host);
+    EXPECT_EQ(1, host->getIPv4SubnetID());
+    EXPECT_EQ("192.0.2.5", host->getIPv4Reservation().toText());
+
+    // Set the negative cache flag on the host.
+    new_host->setNegative(true);
+
+    // Get4 can't get it.
+    host = HostMgr::instance().get4(SubnetID(1), Host::IDENT_DUID,
+                                    &duids_[0]->getDuid()[0],
+                                    duids_[0]->getDuid().size());
+    EXPECT_FALSE(host);
+
+    // But Get4Any can.
+    host = HostMgr::instance().get4Any(SubnetID(1), Host::IDENT_DUID,
+                                       &duids_[0]->getDuid()[0],
+                                       duids_[0]->getDuid().size());
+    ASSERT_TRUE(host);
+    EXPECT_EQ(1, host->getIPv4SubnetID());
+    EXPECT_EQ("192.0.2.5", host->getIPv4Reservation().toText());
+    EXPECT_TRUE(host->getNegative());
+}
+
 void
 HostMgrTest::testGet6(BaseHostDataSource& data_source) {
     // Initially, no host should be present.
@@ -313,10 +368,64 @@ HostMgrTest::testGet6(BaseHostDataSource& data_source) {
                                     &duids_[0]->getDuid()[0],
                                     duids_[0]->getDuid().size());
     ASSERT_TRUE(host);
+    EXPECT_EQ(2, host->getIPv6SubnetID());
     EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
                                                IOAddress("2001:db8:1::1"))));
 }
 
+void
+HostMgrTest::testGet6Any() {
+    // Initially, no host should be present.
+    ConstHostPtr host = HostMgr::instance().get6(SubnetID(2),
+                                                 Host::IDENT_HWADDR,
+                                                 &hwaddrs_[0]->hwaddr_[0],
+                                                 hwaddrs_[0]->hwaddr_.size());
+    ASSERT_FALSE(host);
+    host = HostMgr::instance().get6Any(SubnetID(2), Host::IDENT_HWADDR,
+                                       &hwaddrs_[0]->hwaddr_[0],
+                                       hwaddrs_[0]->hwaddr_.size());
+    ASSERT_FALSE(host);
+
+    // Add new host to the database.
+    HostPtr new_host(new Host(hwaddrs_[0]->toText(false), "hw-address",
+                              SubnetID(1), SubnetID(2),
+                              IOAddress::IPV4_ZERO_ADDRESS()));
+    new_host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
+                                       IOAddress("2001:db8:1::1"), 128));
+    // Abuse of the server's configuration.
+    getCfgHosts()->add(new_host);
+
+    CfgMgr::instance().commit();
+
+    // Retrieve the host from the database and expect that the parameters match.
+    host = HostMgr::instance().get6(SubnetID(2), Host::IDENT_HWADDR,
+                                    &hwaddrs_[0]->hwaddr_[0],
+                                    hwaddrs_[0]->hwaddr_.size());
+    ASSERT_TRUE(host);
+    EXPECT_EQ(2, host->getIPv6SubnetID());
+    EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
+                                               IOAddress("2001:db8:1::1"))));
+
+    // Set the negative cache flag on the host.
+    new_host->setNegative(true);
+
+    // Get6 can't get it.
+    host = HostMgr::instance().get6(SubnetID(2), Host::IDENT_HWADDR,
+                                    &hwaddrs_[0]->hwaddr_[0],
+                                    hwaddrs_[0]->hwaddr_.size());
+    EXPECT_FALSE(host);
+
+    // But Get4Any can.
+    host = HostMgr::instance().get6Any(SubnetID(2), Host::IDENT_HWADDR,
+                                       &hwaddrs_[0]->hwaddr_[0],
+                                       hwaddrs_[0]->hwaddr_.size());
+    ASSERT_TRUE(host);
+    EXPECT_EQ(2, host->getIPv6SubnetID());
+    EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
+                                               IOAddress("2001:db8:1::1"))));
+    EXPECT_TRUE(host->getNegative());
+}
+
 void
 HostMgrTest::testGet6ByPrefix(BaseHostDataSource& data_source1,
                               BaseHostDataSource& data_source2) {
@@ -375,6 +484,11 @@ TEST_F(HostMgrTest, get4) {
     testGet4(*getCfgHosts());
 }
 
+// This test verifies handling of negative caching by get4/get4Any.
+TEST_F(HostMgrTest, get4Any) {
+    testGet4Any();
+}
+
 // This test verifies that it is possible to retrieve IPv6 reservations for
 // the particular host using HostMgr. The reservation is specified in the
 // server's configuration.
@@ -382,6 +496,11 @@ TEST_F(HostMgrTest, get6) {
     testGet6(*getCfgHosts());
 }
 
+// This test verifies handling of negative caching by get4/get4Any.
+TEST_F(HostMgrTest, get6Any) {
+    testGet6Any();
+}
+
 // This test verifies that it is possible to retrieve the reservation of the
 // particular IPv6 prefix using HostMgr.
 TEST_F(HostMgrTest, get6ByPrefix) {