Except Cassandra.
static constexpr StatementTag GET_LEASE6_DUID_IAID_SUBID = "GET_LEASE6_DUID_IAID_SUBID";
static constexpr StatementTag GET_LEASE6_LIMIT = "GET_LEASE6_LIMIT";
static constexpr StatementTag GET_LEASE6_PAGE = "GET_LEASE6_PAGE";
- static constexpr StatementTag GET_LEASE6_RANGE = "GET_LEASE6_RANGE";
// @}
private:
constexpr StatementTag CqlLease6Exchange::GET_LEASE6_DUID_IAID_SUBID;
constexpr StatementTag CqlLease6Exchange::GET_LEASE6_LIMIT;
constexpr StatementTag CqlLease6Exchange::GET_LEASE6_PAGE;
-constexpr StatementTag CqlLease6Exchange::GET_LEASE6_RANGE;
StatementMap CqlLease6Exchange::tagged_statements_ = {
"FROM lease6 "
"WHERE TOKEN(address) > TOKEN(?) "
"LIMIT ? "
- "ALLOW FILTERING "}},
-
- // Get range of IPv6 leases between two addresses
- {GET_LEASE6_RANGE,
- {GET_LEASE6_RANGE,
- "SELECT "
- "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
- "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
- "hwaddr_source, state "
- "FROM lease6 "
- "WHERE address >= ? "
- "AND address <= ? "
- "ALLOW FILTERING "}},
+ "ALLOW FILTERING "}}
};
CqlLease6Exchange::CqlLease6Exchange(const CqlConnection &connection)
return (result);
}
+Lease6Collection
+CqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const {
+ isc_throw(NotImplemented, "getLeases6(lower_bound_address, upper_bound_address) "
+ "is not implemented");
+}
+
void
CqlLeaseMgr::getExpiredLeases4(Lease4Collection &expired_leases,
const size_t max_leases) const {
/// @brief Returns a range of IPv4 leases.
///
- /// Returned leases are ordered by IPv4 addresses.
- ///
/// @param lower_bound_address IPv4 address used as a lower bound for the
/// returned range. The lease for this address is included in the returned
/// range if the lease exists.
/// - If there are no leases returned it indicates that the previous page
/// was the last page.
///
- /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// @param lower_bound_address IPv6 address used as lower bound for the
/// returned range.
/// @param page_size maximum size of the page returned.
///
+ /// @warning This method is currently not implemented. Cassandra doesn't
+ /// support conversions from text to inet. Therefore, we're unable to
+ /// compare the IPv6 addresses to find the desired range. A solution for
+ /// this might be to store the IPv6 address as INET type rather than
+ /// text, but this is currently low priority.
+ ///
/// @return Lease collection (may be empty if no IPv6 lease found).
+ ///
+ /// @throw isc::NotImplemented
virtual Lease6Collection
getLeases6(const asiolink::IOAddress& lower_bound_address,
const LeasePageSize& page_size) const override;
+ /// @brief Returns a range of IPv6 leases.
+ ///
+ /// @param lower_bound_address IPv6 address used as a lower bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ /// @param upper_bound_address IPv6 address used as an upper bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const override;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
lease from the Cassandra database for a client with the specified IAID
(Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier).
-% DHCPSRV_CQL_GET_ADDR_RANGE4 obtaining all IPv4 leases with addresses in range from %1 to %2
-A debug message issued when the server is attempting to obtain leases
-with addresses in the specified range.
-
% DHCPSRV_CQL_GET_PAGE4 obtaining at most %1 IPv4 leases starting from address %2
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
+% DHCPSRV_CQL_GET_ADDR_RANGE4 obtaining all IPv4 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
% DHCPSRV_CQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1
A debug message issued when the server is attempting to obtain all IPv4
leases for a given subnet identifier from the Cassandra database.
A debug message issued when the server is attempting to obtain leases
with addresses in the specified range.
+% DHCPSRV_MEMFILE_GET_ADDR_RANGE6 obtaining all IPv6 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
% DHCPSRV_MEMFILE_GET_PAGE4 obtaining at most %1 IPv4 leases starting from address %2
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
A debug message issued when the server is attempting to obtain leases
with addresses in the specified range.
+% DHCPSRV_MYSQL_GET_ADDR_RANGE6 obtaining all IPv6 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
% DHCPSRV_MYSQL_GET_PAGE4 obtaining at most %1 IPv4 leases starting from address %2
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
A debug message issued when the server is attempting to obtain leases
with addresses in the specified range.
+% DHCPSRV_PGSQL_GET_ADDR_RANGE6 obtaining all IPv6 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
% DHCPSRV_PGSQL_GET_CLIENTID obtaining IPv4 leases for client ID %1
A debug message issued when the server is attempting to obtain a set
of IPv4 leases from the PostgreSQL database for a client with the specified
/// @brief Returns a range of IPv4 leases.
///
- /// Returned leases are ordered by IPv4 addresses.
- ///
/// @param lower_bound_address IPv4 address used as a lower bound for the
/// returned range. The lease for this address is included in the returned
/// range if the lease exists.
/// - If there are no leases returned it indicates that the previous page
/// was the last page.
///
- /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// @param lower_bound_address IPv6 address used as lower bound for the
/// returned range.
/// @param page_size maximum size of the page returned.
///
getLeases6(const asiolink::IOAddress& lower_bound_address,
const LeasePageSize& page_size) const = 0;
+ /// @brief Returns a range of IPv6 leases.
+ ///
+ /// @param lower_bound_address IPv6 address used as a lower bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ /// @param upper_bound_address IPv6 address used as an upper bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const = 0;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
return (collection);
}
+Lease6Collection
+Memfile_LeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const {
+ // Check if the range boundaries aren't swapped.
+ if (upper_bound_address < lower_bound_address) {
+ isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+ << " is lower than lower bound address " << lower_bound_address);
+ }
+
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_ADDR_RANGE6)
+ .arg(lower_bound_address.toText())
+ .arg(upper_bound_address.toText());
+
+ Lease6Collection collection;
+ const Lease6StorageAddressIndex& idx = storage6_.get<AddressIndexTag>();
+ std::pair<Lease6StorageAddressIndex::const_iterator,
+ Lease6StorageAddressIndex::const_iterator> l =
+ std::make_pair(idx.lower_bound(lower_bound_address),
+ idx.upper_bound(upper_bound_address));
+
+ for (auto lease = l.first; lease != l.second; ++lease) {
+ collection.push_back(Lease6Ptr(new Lease6(**lease)));
+ }
+
+ return (collection);
+}
+
void
Memfile_LeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const {
/// @brief Returns a range of IPv4 leases.
///
- /// Returned leases are ordered by IPv4 addresses.
- ///
/// @param lower_bound_address IPv4 address used as a lower bound for the
/// returned range. The lease for this address is included in the returned
/// range if the lease exists.
/// - If there are no leases returned it indicates that the previous page
/// was the last page.
///
- /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// @param lower_bound_address IPv6 address used as lower bound for the
/// returned range.
/// @param page_size maximum size of the page returned.
///
getLeases6(const asiolink::IOAddress& lower_bound_address,
const LeasePageSize& page_size) const;
+ /// @brief Returns a range of IPv6 leases.
+ ///
+ /// @param lower_bound_address IPv6 address used as a lower bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ /// @param upper_bound_address IPv6 address used as an upper bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
"hwaddr, hwtype, hwaddr_source, "
"state "
"FROM lease6 "
- "WHERE address >= ? AND address <= ?"},
+ "WHERE INET6_ATON(address) >= INET6_ATON(?) "
+ "AND INET6_ATON(address) <= INET6_ATON(?)"},
{MySqlLeaseMgr::GET_LEASE6_SUBID,
"SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, "
return (result);
}
+Lease6Collection
+MySqlLeaseMgr::getLeases6(const IOAddress& lower_bound_address,
+ const IOAddress& upper_bound_address) const {
+ if (upper_bound_address < lower_bound_address) {
+ isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+ << " is lower than lower bound address " << lower_bound_address);
+ }
+
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_ADDR_RANGE6)
+ .arg(lower_bound_address.toText())
+ .arg(upper_bound_address.toText());
+
+ // Prepare WHERE clause
+ MYSQL_BIND inbind[2];
+ memset(inbind, 0, sizeof(inbind));
+
+ // Bind lower bound address
+ std::string lb_address_data = lower_bound_address.toText();
+ unsigned long lb_address_data_size = lb_address_data.size();
+ inbind[0].buffer_type = MYSQL_TYPE_STRING;
+ inbind[0].buffer = const_cast<char*>(lb_address_data.c_str());
+ inbind[0].buffer_length = lb_address_data_size;
+ inbind[0].length = &lb_address_data_size;
+
+ // Bind upper bound address
+ std::string ub_address_data = upper_bound_address.toText();
+ unsigned long ub_address_data_size = ub_address_data.size();
+ inbind[1].buffer_type = MYSQL_TYPE_STRING;
+ inbind[1].buffer = const_cast<char*>(ub_address_data.c_str());
+ inbind[1].buffer_length = ub_address_data_size;
+ inbind[1].length = &ub_address_data_size;
+
+ // Get the leases
+ Lease6Collection result;
+ getLeaseCollection(GET_LEASE6_RANGE, inbind, result);
+
+ return (result);
+}
+
void
MySqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const {
/// @brief Returns a range of IPv4 leases.
///
- /// Returned leases are ordered by IPv4 addresses.
- ///
/// @param lower_bound_address IPv4 address used as a lower bound for the
/// returned range. The lease for this address is included in the returned
/// range if the lease exists.
/// - If there are no leases returned it indicates that the previous page
/// was the last page.
///
- /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// @param lower_bound_address IPv6 address used as lower bound for the
/// returned range.
/// @param page_size maximum size of the page returned.
///
getLeases6(const asiolink::IOAddress& lower_bound_address,
const LeasePageSize& page_size) const;
+ /// @brief Returns a range of IPv6 leases.
+ ///
+ /// @param lower_bound_address IPv6 address used as a lower bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ /// @param upper_bound_address IPv6 address used as an upper bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
"hwaddr, hwtype, hwaddr_source, "
"state "
"FROM lease6 "
- "WHERE address >= $1 AND address <= $2"},
+ "WHERE INET(address) >= INET($1) AND INET(address) <= INET($2)"},
// GET_LEASE6_SUBID
{ 1, { OID_INT8 },
return (result);
}
+Lease6Collection
+PgSqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const {
+ if (upper_bound_address < lower_bound_address) {
+ isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+ << " is lower than lower bound address " << lower_bound_address);
+ }
+
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_ADDR_RANGE6)
+ .arg(lower_bound_address.toText())
+ .arg(upper_bound_address.toText());
+
+ // Prepare WHERE clause
+ PsqlBindArray bind_array;
+
+ std::string lb_address_data = lower_bound_address.toText();
+ bind_array.add(lb_address_data);
+
+ std::string ub_address_data = upper_bound_address.toText();
+ bind_array.add(ub_address_data);
+
+ // Get the leases
+ Lease6Collection result;
+ getLeaseCollection(GET_LEASE6_RANGE, bind_array, result);
+
+ return (result);
+}
+
void
PgSqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const {
/// @brief Returns a range of IPv4 leases.
///
- /// Returned leases are ordered by IPv4 addresses.
- ///
/// @param lower_bound_address IPv4 address used as a lower bound for the
/// returned range. The lease for this address is included in the returned
/// range if the lease exists.
/// - If there are no leases returned it indicates that the previous page
/// was the last page.
///
- /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// @param lower_bound_address IPv6 address used as lower bound for the
/// returned range.
/// @param page_size maximum size of the page returned.
///
getLeases6(const asiolink::IOAddress& lower_bound_address,
const LeasePageSize& page_size) const;
+ /// @brief Returns a range of IPv6 leases.
+ ///
+ /// @param lower_bound_address IPv6 address used as a lower bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ /// @param upper_bound_address IPv6 address used as an upper bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const asiolink::IOAddress& upper_bound_address) const;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
}
}
+void
+GenericLeaseMgrTest::testGetLeases6Range() {
+ // Get the leases to be used for the test and add to the database.
+ vector<Lease6Ptr> leases = createLeases6();
+ for (size_t i = 0; i < leases.size(); ++i) {
+ EXPECT_TRUE(lmptr_->addLease(leases[i]));
+ }
+
+ // All addresses in the specified range should be returned.
+ Lease6Collection returned = lmptr_->getLeases6(IOAddress("2001:db8::2"),
+ IOAddress("2001:db8::6"));
+ EXPECT_EQ(5, returned.size());
+
+ // The lower bound address is below the range, so the first two addresses
+ // in the database should be returned.
+ returned = lmptr_->getLeases6(IOAddress("2001::"), IOAddress("2001:db8::1"));
+ EXPECT_EQ(2, returned.size());
+
+ // The lower bound address is the last address in the database, so only this
+ // address should be returned.
+ returned = lmptr_->getLeases6(IOAddress("2001:db8::7"), IOAddress("2001:db8::15"));
+ EXPECT_EQ(1, returned.size());
+
+ // The lower bound is below the range and the upper bound is above the range,
+ // so the whole range should be returned.
+ returned = lmptr_->getLeases6(IOAddress("2001::"), IOAddress("2001:db8::15"));
+ EXPECT_EQ(8, returned.size());
+
+ // No addresses should be returned because our desired range does not
+ // overlap with leases in the database.
+ returned = lmptr_->getLeases6(IOAddress("2001:db8::8"), IOAddress("2001:db8::15"));
+ EXPECT_TRUE(returned.empty());
+
+ // Swapping the lower bound and upper bound should cause an error.
+ EXPECT_THROW(lmptr_->getLeases6(IOAddress("2001:db8::8"), IOAddress("2001:db8::1")),
+ InvalidRange);
+}
+
void
GenericLeaseMgrTest::testGetLeases6DuidIaid() {
// Get the leases to be used for the test.
/// @brief Test method which returns range of IPv6 leases with paging.
void testGetLeases6Paged();
+ /// @brief Test method which returns range of IPv6 leases.
+ void testGetLeases6Range();
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
return (Lease6Collection());
}
+ /// @brief Returns a range of IPv6 leases.
+ ///
+ /// @param lower_bound_address IPv6 address used as a lower bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ /// @param upper_bound_address IPv6 address used as an upper bound for the
+ /// returned range. The lease for this address is included in the returned
+ /// range if the lease exists.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& /* lower_bound_address */,
+ const asiolink::IOAddress& /* upper_bound_address */) const {
+ return (Lease6Collection());
+ }
+
/// @brief Returns range of IPv6 leases using paging.
///
/// This method implements paged browsing of the lease database. The first
testGetLeases6Paged();
}
+// Test that a range of IPv6 leases is returmed.
+TEST_F(MemfileLeaseMgrTest, getLeases6Range) {
+ startBackend(V6);
+ testGetLeases6Range();
+}
+
/// @brief Basic Lease6 Checks
///
/// Checks that the addLease, getLease6 (by address) and deleteLease (with an
testGetLeases6Paged();
}
+// Test that a range of IPv6 leases is returmed.
+TEST_F(MySqlLeaseMgrTest, getLeases6Range) {
+ testGetLeases6Range();
+}
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
testGetLeases6Paged();
}
+// Test that a range of IPv6 leases is returmed.
+TEST_F(PgSqlLeaseMgrTest, getLeases6Range) {
+ testGetLeases6Range();
+}
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),