summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/testutils/memory_host_data_source.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcpsrv/testutils/memory_host_data_source.cc')
-rw-r--r--src/lib/dhcpsrv/testutils/memory_host_data_source.cc390
1 files changed, 390 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/testutils/memory_host_data_source.cc b/src/lib/dhcpsrv/testutils/memory_host_data_source.cc
new file mode 100644
index 0000000..3ea2b83
--- /dev/null
+++ b/src/lib/dhcpsrv/testutils/memory_host_data_source.cc
@@ -0,0 +1,390 @@
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <dhcpsrv/testutils/memory_host_data_source.h>
+
+using namespace isc::db;
+using namespace std;
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+ConstHostCollection
+MemHostDataSource::getAll(const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) const {
+ vector<uint8_t> ident(identifier_begin, identifier_begin + identifier_len);
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // If identifier type do not match, it's not for us
+ if ((*h)->getIdentifierType() != identifier_type) {
+ continue;
+ }
+ // If the identifier matches, we found one!
+ if ((*h)->getIdentifier() == ident) {
+ hosts.push_back(*h);
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getAll4(const SubnetID& subnet_id) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Keep it when subnet_id matches.
+ if ((*h)->getIPv4SubnetID() == subnet_id) {
+ hosts.push_back(*h);
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getAll6(const SubnetID& subnet_id) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Keep it when subnet_id matches.
+ if ((*h)->getIPv6SubnetID() == subnet_id) {
+ hosts.push_back(*h);
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getAllbyHostname(const std::string& hostname) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Keep it when hostname matches.
+ if ((*h)->getLowerHostname() == hostname) {
+ hosts.push_back(*h);
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getAllbyHostname4(const std::string& hostname,
+ const SubnetID& subnet_id) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Keep it when hostname and subnet_id match.
+ if (((*h)->getLowerHostname() == hostname) &&
+ ((*h)->getIPv4SubnetID() == subnet_id)) {
+ hosts.push_back(*h);
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getAllbyHostname6(const std::string& hostname,
+ const SubnetID& subnet_id) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Keep it when hostname and subnet_id match.
+ if (((*h)->getLowerHostname() == hostname) &&
+ ((*h)->getIPv6SubnetID() == subnet_id)) {
+ hosts.push_back(*h);
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getPage4(const SubnetID& subnet_id,
+ size_t& /*source_index*/,
+ uint64_t lower_host_id,
+ const HostPageSize& page_size) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Skip it when subnet_id does not match.
+ if ((*h)->getIPv4SubnetID() != subnet_id) {
+ continue;
+ }
+ if (lower_host_id && ((*h)->getHostId() <= lower_host_id)) {
+ continue;
+ }
+ hosts.push_back(*h);
+ if (hosts.size() == page_size.page_size_) {
+ break;
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getPage6(const SubnetID& subnet_id,
+ size_t& /*source_index*/,
+ uint64_t lower_host_id,
+ const HostPageSize& page_size) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // Skip it when subnet_id does not match.
+ if ((*h)->getIPv6SubnetID() != subnet_id) {
+ continue;
+ }
+ if (lower_host_id && ((*h)->getHostId() <= lower_host_id)) {
+ continue;
+ }
+ hosts.push_back(*h);
+ if (hosts.size() == page_size.page_size_) {
+ break;
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getPage4(size_t& /*source_index*/,
+ uint64_t lower_host_id,
+ const HostPageSize& page_size) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ if (lower_host_id && ((*h)->getHostId() <= lower_host_id)) {
+ continue;
+ }
+ hosts.push_back(*h);
+ if (hosts.size() == page_size.page_size_) {
+ break;
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getPage6(size_t& /*source_index*/,
+ uint64_t lower_host_id,
+ const HostPageSize& page_size) const {
+ ConstHostCollection hosts;
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ if (lower_host_id && ((*h)->getHostId() <= lower_host_id)) {
+ continue;
+ }
+ hosts.push_back(*h);
+ if (hosts.size() == page_size.page_size_) {
+ break;
+ }
+ }
+ return (hosts);
+}
+
+ConstHostCollection
+MemHostDataSource::getAll4(const asiolink::IOAddress& /*address*/) const {
+ return (ConstHostCollection());
+}
+
+ConstHostPtr
+MemHostDataSource::get4(const SubnetID& subnet_id,
+ const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) const {
+ vector<uint8_t> ident(identifier_begin, identifier_begin + identifier_len);
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // If either subnet-id or identifier type do not match,
+ // it's not our host
+ if (((*h)->getIPv4SubnetID() != subnet_id) ||
+ ((*h)->getIdentifierType() != identifier_type)) {
+ continue;
+ }
+ // If the identifier matches, we found it!
+ if ((*h)->getIdentifier() == ident) {
+ return (*h);
+ }
+ }
+
+ // Nothing found
+ return (ConstHostPtr());
+}
+
+ConstHostPtr
+MemHostDataSource::get6(const SubnetID& subnet_id,
+ const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) const {
+ vector<uint8_t> ident(identifier_begin, identifier_begin + identifier_len);
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // If either subnet-id or identifier type do not match,
+ // it's not our host
+ if (((*h)->getIPv6SubnetID() != subnet_id) ||
+ ((*h)->getIdentifierType() != identifier_type)) {
+ continue;
+ }
+ // If the identifier matches, we found it!
+ if ((*h)->getIdentifier() == ident) {
+ return (*h);
+ }
+ }
+
+ return (ConstHostPtr());
+}
+
+ConstHostPtr
+MemHostDataSource::get4(const SubnetID& subnet_id,
+ const asiolink::IOAddress& address) const {
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ if ((*h)->getIPv4SubnetID() == subnet_id &&
+ (*h)->getIPv4Reservation() == address) {
+ return (*h);
+ }
+ }
+
+ return (ConstHostPtr());
+}
+
+ConstHostCollection
+MemHostDataSource::getAll4(const SubnetID& subnet_id,
+ const asiolink::IOAddress& address) const {
+ ConstHostCollection hosts;
+ auto host = get4(subnet_id, address);
+ if (host) {
+ hosts.push_back(host);
+ }
+ return (hosts);
+}
+
+ConstHostPtr
+MemHostDataSource::get6(const asiolink::IOAddress& /*prefix*/,
+ const uint8_t /*prefix_len*/) const {
+ return (ConstHostPtr());
+}
+
+ConstHostPtr
+MemHostDataSource::get6(const SubnetID& subnet_id,
+ const asiolink::IOAddress& address) const {
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+
+ // Naive approach: check hosts one by one
+
+ // First check: subnet-id must match.
+ if ((*h)->getIPv6SubnetID() != subnet_id) {
+ // wrong subnet-id? ok, skip this one
+ continue;
+ }
+
+ // Second check: the v6 reservation must much. This is very simple
+ // as we ignore the reservation type.
+ auto resrvs = (*h)->getIPv6Reservations();
+ for (auto r = resrvs.first; r != resrvs.second; ++r) {
+ if ((*r).second.getPrefix() == address) {
+ return (*h);
+ }
+ }
+ }
+
+ return (ConstHostPtr());
+}
+
+ConstHostCollection
+MemHostDataSource::getAll6(const SubnetID& subnet_id,
+ const asiolink::IOAddress& address) const {
+ ConstHostCollection hosts;
+ auto host = get6(subnet_id, address);
+ if (host) {
+ hosts.push_back(host);
+ }
+ return (hosts);
+}
+
+void
+MemHostDataSource::add(const HostPtr& host) {
+ host->setHostId(++next_host_id_);
+ store_.push_back(host);
+}
+
+bool
+MemHostDataSource::del(const SubnetID& subnet_id,
+ const asiolink::IOAddress& addr) {
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ if (addr.isV4()) {
+ if ((*h)->getIPv4SubnetID() == subnet_id &&
+ (*h)->getIPv4Reservation() == addr) {
+ store_.erase(h);
+ return (true);
+ }
+ } else {
+
+ if ((*h)->getIPv6SubnetID() != subnet_id) {
+ continue;
+ }
+
+ // Second check: the v6 reservation must much. This is very simple
+ // as we ignore the reservation type.
+ auto resrvs = (*h)->getIPv6Reservations();
+ for (auto r = resrvs.first; r != resrvs.second; ++r) {
+ if ((*r).second.getPrefix() == addr) {
+ store_.erase(h);
+ return (true);
+ }
+ }
+ }
+ }
+
+ return (false);
+}
+
+bool
+MemHostDataSource::del4(const SubnetID& subnet_id,
+ const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) {
+ vector<uint8_t> ident(identifier_begin, identifier_begin + identifier_len);
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // If either subnet-id or identifier type do not match,
+ // it's not our host
+ if (((*h)->getIPv4SubnetID() != subnet_id) ||
+ ((*h)->getIdentifierType() != identifier_type)) {
+ continue;
+ }
+ // If the identifier matches, we found it!
+ if ((*h)->getIdentifier() == ident) {
+ store_.erase(h);
+ return (true);
+ }
+ }
+
+ return (false);
+}
+
+bool
+MemHostDataSource::del6(const SubnetID& subnet_id,
+ const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) {
+ vector<uint8_t> ident(identifier_begin, identifier_begin + identifier_len);
+ for (auto h = store_.begin(); h != store_.end(); ++h) {
+ // If either subnet-id or identifier type do not match,
+ // it's not our host
+ if (((*h)->getIPv6SubnetID() != subnet_id) ||
+ ((*h)->getIdentifierType() != identifier_type)) {
+ continue;
+ }
+ // If the identifier matches, we found it!
+ if ((*h)->getIdentifier() == ident) {
+ store_.erase(h);
+ return (true);
+ }
+ }
+ return (false);
+}
+
+size_t
+MemHostDataSource::size() const {
+ return (store_.size());
+}
+
+HostDataSourcePtr
+memFactory(const DatabaseConnection::ParameterMap& /*parameters*/) {
+ return (HostDataSourcePtr(new MemHostDataSource()));
+}
+
+} // namespace isc::dhcp::test
+} // namespace isc::dhcp
+} // namespace isc