diff options
author | Francis Dupont <fdupont@isc.org> | 2024-05-31 12:30:07 +0200 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2024-06-10 09:19:53 +0200 |
commit | 91378b3ae1604244185122898f3e777b3615e34a (patch) | |
tree | 7410e150ac18d8089f20f9d27b968bc120c1d779 /src/lib/dhcpsrv/cfg_hosts.cc | |
parent | [#3375] Fixed del bug (new UT?) (diff) | |
download | kea-91378b3ae1604244185122898f3e777b3615e34a.tar.xz kea-91378b3ae1604244185122898f3e777b3615e34a.zip |
[#3375] Made update atomic and added UT
Diffstat (limited to 'src/lib/dhcpsrv/cfg_hosts.cc')
-rw-r--r-- | src/lib/dhcpsrv/cfg_hosts.cc | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/cfg_hosts.cc b/src/lib/dhcpsrv/cfg_hosts.cc index b715abf8de..e8f5887589 100644 --- a/src/lib/dhcpsrv/cfg_hosts.cc +++ b/src/lib/dhcpsrv/cfg_hosts.cc @@ -1289,6 +1289,61 @@ CfgHosts::del6(const SubnetID& subnet_id, return (erased_hosts != 0); } +void +CfgHosts::update(HostPtr const& host) { + bool deleted(false); + HostContainerIndex0& idx = hosts_.get<0>(); + std::vector<uint8_t> const& identifier(host->getIdentifier()); + auto const t = boost::make_tuple(identifier, host->getIdentifierType()); + MultiThreadingLock lock(*mutex_); + auto const& range = idx.equal_range(t); + if (host->getIPv4SubnetID() != SUBNET_ID_UNUSED) { + // inline del4. + for (auto key = range.first; key != range.second;) { + if ((*key)->getIPv4SubnetID() != host->getIPv4SubnetID()) { + ++key; + // Skip hosts from other subnets. + continue; + } + + key = idx.erase(key); + deleted = true; + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_UPDATE_DEL4) + .arg(1) + .arg(host->getIPv4SubnetID()) + .arg(host->getIdentifierAsText()); + } + } else if (host->getIPv6SubnetID() != SUBNET_ID_UNUSED) { + // inline del6. + HostContainer6Index3& idx6 = hosts6_.get<3>(); + for (auto key = range.first; key != range.second;) { + if ((*key)->getIPv6SubnetID() != host->getIPv6SubnetID()) { + ++key; + // Skip hosts from other subnets. + } + + auto host_id = (*key)->getHostId(); + key = idx.erase(key); + deleted = true; + size_t erased_reservations = idx6.erase(host_id); + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_UPDATE_DEL6) + .arg(1) + .arg(erased_reservations) + .arg(host->getIPv6SubnetID()) + .arg(host->getIdentifierAsText()); + } + } else { + isc_throw(HostNotFound, "Mandatory 'subnet-id' parameter missing."); + } + if (!deleted) { + isc_throw(HostNotFound, "Host not updated (not found)."); + } + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_UPDATE_ADD) + .arg(host->toText()); + add4(host); + add6(host); +} + bool CfgHosts::setIPReservationsUnique(const bool unique) { MultiThreadingLock lock(*mutex_); |