Kea  2.5.2
host_mgr.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 #include <dhcpsrv/cfg_hosts.h>
9 #include <dhcpsrv/cfgmgr.h>
10 #include <dhcpsrv/host_mgr.h>
11 #include <dhcpsrv/hosts_log.h>
13 
14 namespace {
15 
23 isc::dhcp::CfgHostsPtr getCfgHostsForEdit() {
24  return (isc::dhcp::CfgMgr::instance().getCurrentCfg()->getCfgHosts());
25 }
26 
33 isc::dhcp::ConstCfgHostsPtr getCfgHosts() {
34  return (getCfgHostsForEdit());
35 }
36 
37 } // end of anonymous namespace
38 
39 namespace isc {
40 namespace dhcp {
41 
42 using namespace isc::asiolink;
43 using namespace isc::db;
44 
45 IOServicePtr HostMgr::io_service_ = IOServicePtr();
46 
47 boost::scoped_ptr<HostMgr>&
48 HostMgr::getHostMgrPtr() {
49  static boost::scoped_ptr<HostMgr> host_mgr_ptr;
50  return (host_mgr_ptr);
51 }
52 
53 void
55  getHostMgrPtr().reset(new HostMgr());
56 }
57 
58 void
59 HostMgr::addBackend(const std::string& access) {
60  HostDataSourceFactory::add(getHostMgrPtr()->alternate_sources_, access);
61 }
62 
63 bool
64 HostMgr::delBackend(const std::string& db_type) {
65  if (getHostMgrPtr()->cache_ptr_ &&
66  getHostMgrPtr()->cache_ptr_->getType() == db_type) {
67  getHostMgrPtr()->cache_ptr_.reset();
68  }
69  return (HostDataSourceFactory::del(getHostMgrPtr()->alternate_sources_,
70  db_type));
71 }
72 
73 bool
74 HostMgr::delBackend(const std::string& db_type, const std::string& access,
75  bool if_unusable) {
76  return (HostDataSourceFactory::del(getHostMgrPtr()->alternate_sources_,
77  db_type, access, if_unusable));
78 }
79 
80 void
82  getHostMgrPtr()->alternate_sources_.clear();
83 }
84 
87  if (alternate_sources_.empty()) {
88  return (HostDataSourcePtr());
89  }
90  return (alternate_sources_[0]);
91 }
92 
93 bool
95  if (getHostMgrPtr()->cache_ptr_) {
96  return (true);
97  }
98  HostDataSourceList& sources = getHostMgrPtr()->alternate_sources_;
99  if (sources.empty()) {
100  return (false);
101  }
102  CacheHostDataSourcePtr cache_ptr =
103  boost::dynamic_pointer_cast<CacheHostDataSource>(sources[0]);
104  if (cache_ptr) {
105  getHostMgrPtr()->cache_ptr_ = cache_ptr;
106  if (logging) {
108  .arg(cache_ptr->getType());
109  }
110  return (true);
111  }
112  return (false);
113 }
114 
115 HostMgr&
117  boost::scoped_ptr<HostMgr>& host_mgr_ptr = getHostMgrPtr();
118  if (!host_mgr_ptr) {
119  create();
120  }
121  return (*host_mgr_ptr);
122 }
123 
125 HostMgr::getAll(const Host::IdentifierType& identifier_type,
126  const uint8_t* identifier_begin,
127  const size_t identifier_len,
128  const HostMgrOperationTarget target) const {
129  ConstHostCollection hosts;
131  hosts = getCfgHosts()->getAll(identifier_type, identifier_begin,
132  identifier_len);
133  }
135  for (auto source : alternate_sources_) {
136  ConstHostCollection hosts_plus =
137  source->getAll(identifier_type, identifier_begin, identifier_len);
138  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
139  }
140  }
141  return (hosts);
142 }
143 
145 HostMgr::getAll(const Host::IdentifierType& identifier_type,
146  const uint8_t* identifier_begin,
147  const size_t identifier_len) const {
148  return getAll(identifier_type, identifier_begin, identifier_len,
150 }
151 
153 HostMgr::getAll4(const SubnetID& subnet_id, const HostMgrOperationTarget target) const {
154  ConstHostCollection hosts;
156  hosts = getCfgHosts()->getAll4(subnet_id);
157  }
159  for (auto source : alternate_sources_) {
160  ConstHostCollection hosts_plus = source->getAll4(subnet_id);
161  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
162  }
163  }
164  return (hosts);
165 }
166 
168 HostMgr::getAll4(const SubnetID& subnet_id) const {
169  return getAll4(subnet_id, HostMgrOperationTarget::ALL_SOURCES);
170 }
171 
173 HostMgr::getAll6(const SubnetID& subnet_id, const HostMgrOperationTarget target) const {
174  ConstHostCollection hosts;
176  hosts = getCfgHosts()->getAll6(subnet_id);
177  }
179  for (auto source : alternate_sources_) {
180  ConstHostCollection hosts_plus = source->getAll6(subnet_id);
181  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
182  }
183  }
184  return (hosts);
185 }
186 
188 HostMgr::getAll6(const SubnetID& subnet_id) const {
189  return getAll6(subnet_id, HostMgrOperationTarget::ALL_SOURCES);
190 }
191 
193 HostMgr::getAllbyHostname(const std::string& hostname, const HostMgrOperationTarget target) const {
194  ConstHostCollection hosts;
196  hosts = getCfgHosts()->getAllbyHostname(hostname);
197  }
199  for (auto source : alternate_sources_) {
200  ConstHostCollection hosts_plus = source->getAllbyHostname(hostname);
201  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
202  }
203  }
204  return (hosts);
205 }
206 
208 HostMgr::getAllbyHostname(const std::string& hostname) const {
209  return getAllbyHostname(hostname, HostMgrOperationTarget::ALL_SOURCES);
210 }
211 
213 HostMgr::getAllbyHostname4(const std::string& hostname,
214  const SubnetID& subnet_id,
215  const HostMgrOperationTarget target) const {
216  ConstHostCollection hosts;
218  hosts = getCfgHosts()->getAllbyHostname4(hostname, subnet_id);
219  }
221  for (auto source : alternate_sources_) {
222  ConstHostCollection hosts_plus = source->getAllbyHostname4(hostname,
223  subnet_id);
224  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
225  }
226  }
227  return (hosts);
228 }
229 
231 HostMgr::getAllbyHostname4(const std::string& hostname,
232  const SubnetID& subnet_id) const {
233  return getAllbyHostname4(hostname, subnet_id, HostMgrOperationTarget::ALL_SOURCES);
234 }
235 
237 HostMgr::getAllbyHostname6(const std::string& hostname,
238  const SubnetID& subnet_id,
239  const HostMgrOperationTarget target) const {
240  ConstHostCollection hosts;
242  hosts = getCfgHosts()->getAllbyHostname6(hostname, subnet_id);
243  }
245  for (auto source : alternate_sources_) {
246  ConstHostCollection hosts_plus = source->getAllbyHostname6(hostname,
247  subnet_id);
248  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
249  }
250  }
251  return (hosts);
252 }
253 
255 HostMgr::getAllbyHostname6(const std::string& hostname,
256  const SubnetID& subnet_id) const {
257  return getAllbyHostname6(hostname, subnet_id, HostMgrOperationTarget::ALL_SOURCES);
258 }
259 
261 HostMgr::getPage4(const SubnetID& subnet_id,
262  size_t& source_index,
263  uint64_t lower_host_id,
264  const HostPageSize& page_size) const {
265  // Return empty if (and only if) sources are exhausted.
266  if (source_index > alternate_sources_.size()) {
267  return (ConstHostCollection());
268  }
269 
270  ConstHostCollection hosts;
271  // Source index 0 means config file.
272  if (source_index == 0) {
273  hosts = getCfgHosts()->
274  getPage4(subnet_id, source_index, lower_host_id, page_size);
275  } else {
276  hosts = alternate_sources_[source_index - 1]->
277  getPage4(subnet_id, source_index, lower_host_id, page_size);
278  }
279 
280  // When got something return it.
281  if (!hosts.empty()) {
282  return (hosts);
283  }
284 
285  // Nothing from this source: try the next one.
286  // Note the recursion is limited to the number of sources in all cases.
287  ++source_index;
288  return (getPage4(subnet_id, source_index, 0UL, page_size));
289 }
290 
292 HostMgr::getPage6(const SubnetID& subnet_id,
293  size_t& source_index,
294  uint64_t lower_host_id,
295  const HostPageSize& page_size) const {
296  // Return empty if (and only if) sources are exhausted.
297  if (source_index > alternate_sources_.size()) {
298  return (ConstHostCollection());
299  }
300 
301  ConstHostCollection hosts;
302  // Source index 0 means config file.
303  if (source_index == 0) {
304  hosts = getCfgHosts()->
305  getPage6(subnet_id, source_index, lower_host_id, page_size);
306  } else {
307  hosts = alternate_sources_[source_index - 1]->
308  getPage6(subnet_id, source_index, lower_host_id, page_size);
309  }
310 
311  // When got something return it.
312  if (!hosts.empty()) {
313  return (hosts);
314  }
315 
316  // Nothing from this source: try the next one.
317  // Note the recursion is limited to the number of sources in all cases.
318  ++source_index;
319  return (getPage6(subnet_id, source_index, 0UL, page_size));
320 }
321 
323 HostMgr::getPage4(size_t& source_index,
324  uint64_t lower_host_id,
325  const HostPageSize& page_size) const {
326  // Return empty if (and only if) sources are exhausted.
327  if (source_index > alternate_sources_.size()) {
328  return (ConstHostCollection());
329  }
330 
331  ConstHostCollection hosts;
332  // Source index 0 means config file.
333  if (source_index == 0) {
334  hosts = getCfgHosts()->
335  getPage4(source_index, lower_host_id, page_size);
336  } else {
337  hosts = alternate_sources_[source_index - 1]->
338  getPage4(source_index, lower_host_id, page_size);
339  }
340 
341  // When got something return it.
342  if (!hosts.empty()) {
343  return (hosts);
344  }
345 
346  // Nothing from this source: try the next one.
347  // Note the recursion is limited to the number of sources in all cases.
348  ++source_index;
349  return (getPage4(source_index, 0UL, page_size));
350 }
351 
353 HostMgr::getPage6(size_t& source_index,
354  uint64_t lower_host_id,
355  const HostPageSize& page_size) const {
356  // Return empty if (and only if) sources are exhausted.
357  if (source_index > alternate_sources_.size()) {
358  return (ConstHostCollection());
359  }
360 
361  ConstHostCollection hosts;
362  // Source index 0 means config file.
363  if (source_index == 0) {
364  hosts = getCfgHosts()->
365  getPage6(source_index, lower_host_id, page_size);
366  } else {
367  hosts = alternate_sources_[source_index - 1]->
368  getPage6(source_index, lower_host_id, page_size);
369  }
370 
371  // When got something return it.
372  if (!hosts.empty()) {
373  return (hosts);
374  }
375 
376  // Nothing from this source: try the next one.
377  // Note the recursion is limited to the number of sources in all cases.
378  ++source_index;
379  return (getPage6(source_index, 0UL, page_size));
380 }
381 
383 HostMgr::getAll4(const IOAddress& address, const HostMgrOperationTarget target) const {
384  ConstHostCollection hosts;
386  hosts = getCfgHosts()->getAll4(address);
387  }
389  for (auto source : alternate_sources_) {
390  ConstHostCollection hosts_plus = source->getAll4(address);
391  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
392  }
393  }
394  return (hosts);
395 }
396 
398 HostMgr::getAll4(const IOAddress& address) const {
399  return getAll4(address, HostMgrOperationTarget::ALL_SOURCES);
400 }
401 
403 HostMgr::get4Any(const SubnetID& subnet_id,
404  const Host::IdentifierType& identifier_type,
405  const uint8_t* identifier_begin,
406  const size_t identifier_len,
407  const HostMgrOperationTarget target) const {
408  ConstHostPtr host;
410  host = getCfgHosts()->get4(subnet_id, identifier_type,
411  identifier_begin, identifier_len);
412  }
413 
414  // Found it in the config file, there are no backends configured, or
415  // querying them is disabled?
416  // Then we're done here.
417  if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
418  return (host);
419  }
420 
423  .arg(subnet_id)
424  .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
425  identifier_len));
426 
427  // Try to find a host in each configured backend. We return as soon
428  // as we find first hit.
429  for (auto source : alternate_sources_) {
430  host = source->get4(subnet_id, identifier_type,
431  identifier_begin, identifier_len);
432 
433  if (host) {
436  .arg(subnet_id)
437  .arg(Host::getIdentifierAsText(identifier_type,
438  identifier_begin,
439  identifier_len))
440  .arg(source->getType())
441  .arg(host->toText());
442 
443  if (source != cache_ptr_) {
444  cache(host);
445  }
446  return (host);
447  }
448  }
451  .arg(subnet_id)
452  .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
453  identifier_len));
454  return (ConstHostPtr());
455 }
456 
458 HostMgr::get4Any(const SubnetID& subnet_id,
459  const Host::IdentifierType& identifier_type,
460  const uint8_t* identifier_begin,
461  const size_t identifier_len) const {
462  return get4Any(subnet_id, identifier_type, identifier_begin, identifier_len,
464 }
465 
467 HostMgr::get4(const SubnetID& subnet_id,
468  const Host::IdentifierType& identifier_type,
469  const uint8_t* identifier_begin,
470  const size_t identifier_len,
471  const HostMgrOperationTarget target) const {
472  ConstHostPtr host = get4Any(subnet_id, identifier_type,
473  identifier_begin, identifier_len, target);
474  if (host && host->getNegative()) {
475  return (ConstHostPtr());
476  } else if (!host && negative_caching_) {
477  cacheNegative(subnet_id, SubnetID(SUBNET_ID_UNUSED),
478  identifier_type, identifier_begin, identifier_len);
479  }
480  return (host);
481 }
482 
484 HostMgr::get4(const SubnetID& subnet_id,
485  const Host::IdentifierType& identifier_type,
486  const uint8_t* identifier_begin,
487  const size_t identifier_len) const {
488  return get4(subnet_id, identifier_type, identifier_begin, identifier_len,
490 }
491 
493 HostMgr::get4(const SubnetID& subnet_id,
494  const asiolink::IOAddress& address,
495  const HostMgrOperationTarget target) const {
496  ConstHostPtr host;
498  host = getCfgHosts()->get4(subnet_id, address);
499  }
500 
501  if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
502  return (host);
503  }
506  .arg(subnet_id)
507  .arg(address.toText());
508  for (auto source : alternate_sources_) {
509  host = source->get4(subnet_id, address);
510  if (host && host->getNegative()) {
511  return (ConstHostPtr());
512  }
513  if (host && source != cache_ptr_) {
514  cache(host);
515  }
516  if (host) {
517  return (host);
518  }
519  }
520  return (ConstHostPtr());
521 }
522 
524 HostMgr::get4(const SubnetID& subnet_id,
525  const asiolink::IOAddress& address) const {
526  return get4(subnet_id, address, HostMgrOperationTarget::ALL_SOURCES);
527 }
528 
530 HostMgr::getAll4(const SubnetID& subnet_id,
531  const asiolink::IOAddress& address,
532  const HostMgrOperationTarget target) const {
533  ConstHostCollection hosts;
535  hosts = getCfgHosts()->getAll4(subnet_id, address);
536  }
537 
541  .arg(subnet_id)
542  .arg(address.toText());
543 
544  for (auto source : alternate_sources_) {
545  auto hosts_plus = source->getAll4(subnet_id, address);
546  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
547  }
548  }
549  return (hosts);
550 }
551 
553 HostMgr::getAll4(const SubnetID& subnet_id,
554  const asiolink::IOAddress& address) const {
555  return getAll4(subnet_id, address, HostMgrOperationTarget::ALL_SOURCES);
556 }
557 
559 HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len,
560  const HostMgrOperationTarget target) const {
561  ConstHostPtr host;
563  host = getCfgHosts()->get6(prefix, prefix_len);
564  }
565  if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
566  return (host);
567  }
569  .arg(prefix.toText())
570  .arg(static_cast<int>(prefix_len));
571  for (auto source : alternate_sources_) {
572  host = source->get6(prefix, prefix_len);
573  if (host && host->getNegative()) {
574  return (ConstHostPtr());
575  }
576  if (host && source != cache_ptr_) {
577  cache(host);
578  }
579  if (host) {
580  return (host);
581  }
582  }
583  return (ConstHostPtr());
584 }
585 
587 HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
588  return get6(prefix, prefix_len, HostMgrOperationTarget::ALL_SOURCES);
589 }
590 
592 HostMgr::get6Any(const SubnetID& subnet_id,
593  const Host::IdentifierType& identifier_type,
594  const uint8_t* identifier_begin,
595  const size_t identifier_len,
596  const HostMgrOperationTarget target) const {
597  ConstHostPtr host;
599  host = getCfgHosts()->get6(subnet_id, identifier_type,
600  identifier_begin, identifier_len);
601  }
602  if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
603  return (host);
604  }
605 
608  .arg(subnet_id)
609  .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
610  identifier_len));
611 
612  for (auto source : alternate_sources_) {
613  host = source->get6(subnet_id, identifier_type,
614  identifier_begin, identifier_len);
615 
616  if (host) {
619  .arg(subnet_id)
620  .arg(Host::getIdentifierAsText(identifier_type,
621  identifier_begin,
622  identifier_len))
623  .arg(source->getType())
624  .arg(host->toText());
625 
626  if (source != cache_ptr_) {
627  cache(host);
628  }
629  return (host);
630  }
631  }
632 
635  .arg(subnet_id)
636  .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
637  identifier_len));
638 
639  return (ConstHostPtr());
640 }
641 
643 HostMgr::get6Any(const SubnetID& subnet_id,
644  const Host::IdentifierType& identifier_type,
645  const uint8_t* identifier_begin,
646  const size_t identifier_len) const {
647  return get6Any(subnet_id, identifier_type, identifier_begin, identifier_len,
649 }
650 
652 HostMgr::get6(const SubnetID& subnet_id,
653  const Host::IdentifierType& identifier_type,
654  const uint8_t* identifier_begin,
655  const size_t identifier_len,
656  const HostMgrOperationTarget target) const {
657  ConstHostPtr host = get6Any(subnet_id, identifier_type,
658  identifier_begin, identifier_len, target);
659  if (host && host->getNegative()) {
660  return (ConstHostPtr());
661  } else if (!host && negative_caching_) {
662  cacheNegative(SubnetID(SUBNET_ID_UNUSED), subnet_id,
663  identifier_type, identifier_begin, identifier_len);
664  }
665  return (host);
666 }
667 
669 HostMgr::get6(const SubnetID& subnet_id,
670  const Host::IdentifierType& identifier_type,
671  const uint8_t* identifier_begin,
672  const size_t identifier_len) const {
673  return get6(subnet_id, identifier_type, identifier_begin, identifier_len,
675 }
676 
678 HostMgr::get6(const SubnetID& subnet_id,
679  const asiolink::IOAddress& addr,
680  const HostMgrOperationTarget target) const {
681  ConstHostPtr host;
683  host = getCfgHosts()->get6(subnet_id, addr);
684  }
685  if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
686  return (host);
687  }
690  .arg(subnet_id)
691  .arg(addr.toText());
692  for (auto source : alternate_sources_) {
693  host = source->get6(subnet_id, addr);
694  if (host && host->getNegative()) {
695  return (ConstHostPtr());
696  }
697  if (host && source != cache_ptr_) {
698  cache(host);
699  }
700  if (host) {
701  return (host);
702  }
703  }
704  return (ConstHostPtr());
705 }
706 
708 HostMgr::get6(const SubnetID& subnet_id,
709  const asiolink::IOAddress& addr) const {
710  return get6(subnet_id, addr, HostMgrOperationTarget::ALL_SOURCES);
711 }
712 
714 HostMgr::getAll6(const SubnetID& subnet_id,
715  const asiolink::IOAddress& address,
716  const HostMgrOperationTarget target) const {
717  ConstHostCollection hosts;
718 
720  hosts = getCfgHosts()->getAll6(subnet_id, address);
721  }
722 
726  .arg(subnet_id)
727  .arg(address.toText());
728 
729  for (auto source : alternate_sources_) {
730  auto hosts_plus = source->getAll6(subnet_id, address);
731  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
732  }
733  }
734  return (hosts);
735 }
736 
738 HostMgr::getAll6(const SubnetID& subnet_id,
739  const asiolink::IOAddress& address) const {
740  return getAll6(subnet_id, address, HostMgrOperationTarget::ALL_SOURCES);
741 }
742 
744 HostMgr::getAll6(const IOAddress& address) const {
745  return (getAll6(address, HostMgrOperationTarget::ALL_SOURCES));
746 }
747 
749 HostMgr::getAll6(const IOAddress& address, const HostMgrOperationTarget target) const {
750  ConstHostCollection hosts;
752  hosts = getCfgHosts()->getAll6(address);
753  }
754 
756  for (auto source : alternate_sources_) {
757  ConstHostCollection hosts_plus = source->getAll6(address);
758  hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
759  }
760  }
761 
762  return (hosts);
763 }
764 
765 void
766 HostMgr::add(const HostPtr& host, const HostMgrOperationTarget target) {
768  getCfgHostsForEdit()->add(host);
769  }
770 
772  // Don't throw if all targets were selected.
773  if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
774  isc_throw(NoHostDataSourceManager, "Unable to add new host because there is "
775  "no hosts-database configured.");
776 
777  }
778 
779  for (auto source : alternate_sources_) {
780  source->add(host);
781  }
782  }
783 
784  // If no backend throws the host should be cached.
785  if (cache_ptr_) {
786  cache(host);
787  }
788 }
789 
790 void
791 HostMgr::add(const HostPtr& host) {
793 }
794 
795 bool
796 HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr,
797  const HostMgrOperationTarget target) {
798  size_t erased = false;
799 
801  erased = getCfgHostsForEdit()->del(subnet_id, addr);
802  }
803 
805  // Don't throw if all targets were selected.
806  if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
807  isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
808  "no hosts-database configured.");
809  }
810 
811  for (auto source : alternate_sources_) {
812  bool alternate_erased = source->del(subnet_id, addr);
813  erased = alternate_erased || erased;
814  }
815  }
816 
817  return (erased);
818 }
819 
820 bool
821 HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) {
822  return del(subnet_id, addr, HostMgrOperationTarget::ALTERNATE_SOURCES);
823 }
824 
825 bool
826 HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
827  const uint8_t* identifier_begin, const size_t identifier_len,
828  const HostMgrOperationTarget target) {
829  bool success = false;
830 
832  if (getCfgHostsForEdit()->del4(subnet_id, identifier_type,
833  identifier_begin, identifier_len)) {
834  success = true;
835  }
836  }
837 
839  // Don't throw if all targets were selected.
840  if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
841  isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
842  "no hosts-database configured.");
843  }
844 
845  for (auto source : alternate_sources_) {
846  if (source->del4(subnet_id, identifier_type,
847  identifier_begin, identifier_len)) {
848  success = true;
849  }
850  }
851  }
852  return (success);
853 }
854 
855 bool
856 HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
857  const uint8_t* identifier_begin, const size_t identifier_len) {
858  return del4(subnet_id, identifier_type, identifier_begin, identifier_len,
860 }
861 
862 bool
863 HostMgr::del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
864  const uint8_t* identifier_begin, const size_t identifier_len,
865  const HostMgrOperationTarget target) {
866  bool success = false;
867 
869  if (getCfgHostsForEdit()->del6(subnet_id, identifier_type,
870  identifier_begin, identifier_len)) {
871  success = true;
872  }
873  }
874 
876  // Don't throw if all targets were selected.
877  if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
878  isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
879  "no hosts-database configured.");
880  }
881 
882  for (auto source : alternate_sources_) {
883  if (source->del6(subnet_id, identifier_type,
884  identifier_begin, identifier_len)) {
885  success = true;
886  }
887  }
888  }
889  return (success);
890 }
891 
892 bool
893 HostMgr::del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
894  const uint8_t* identifier_begin, const size_t identifier_len) {
895  return del6(subnet_id, identifier_type, identifier_begin, identifier_len,
897 }
898 
899 void
900 HostMgr::update(HostPtr const& host, const HostMgrOperationTarget target) {
902  getCfgHostsForEdit()->update(host);
903  }
904 
906  // Don't throw if all targets were selected.
907  if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
909  "Unable to update existing host because there is no hosts-database configured.");
910  }
911 
912  for (HostDataSourcePtr const& source : alternate_sources_) {
913  source->update(host);
914  }
915  }
916 
917  // If no backend throws the host should be cached.
918  if (cache_ptr_) {
919  cache(host);
920  }
921 }
922 
923 void
924 HostMgr::update(HostPtr const& host) {
926 }
927 
928 void
930  if (cache_ptr_) {
931  // Need a real host.
932  if (!host || host->getNegative()) {
933  return;
934  }
935  // Replace any existing value.
936  // Don't check the result as it does not matter?
937  cache_ptr_->insert(host, true);
938  }
939 }
940 
941 void
942 HostMgr::cacheNegative(const SubnetID& ipv4_subnet_id,
943  const SubnetID& ipv6_subnet_id,
944  const Host::IdentifierType& identifier_type,
945  const uint8_t* identifier_begin,
946  const size_t identifier_len) const {
947  if (cache_ptr_ && negative_caching_) {
948  HostPtr host(new Host(identifier_begin, identifier_len,
949  identifier_type,
950  ipv4_subnet_id, ipv6_subnet_id,
952  host->setNegative(true);
953  // Don't replace any existing value.
954  // nor matter if it fails.
955  cache_ptr_->insert(host, false);
956  }
957 }
958 
959 bool
961  // Iterate over the alternate sources first, because they may include those
962  // for which the new setting is not supported.
963  for (auto source : alternate_sources_) {
964  if (!source->setIPReservationsUnique(unique)) {
965  // One of the sources does not support this new mode of operation.
966  // Let's log a warning and back off the changes to the default
967  // setting which should always be supported.
968  ip_reservations_unique_ = true;
970  .arg(source->getType());
971  for (auto source : alternate_sources_) {
972  source->setIPReservationsUnique(true);
973  }
974  return (false);
975  }
976  }
977  // Successfully configured the HostMgr to use the new setting.
978  // Remember this setting so we can return it via the
979  // getIPReservationsUnique.
980  ip_reservations_unique_ = unique;
981  return (true);
982 }
983 
984 } // end of isc::dhcp namespace
985 } // end of isc namespace
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
static void add(HostDataSourceList &sources, const std::string &dbaccess)
Create and add an instance of a host data source.
static bool del(HostDataSourceList &sources, const std::string &db_type)
Delete a host data source.
Host Manager.
Definition: host_mgr.h:68
ConstHostCollection getAll6(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv6 subnet.
Definition: host_mgr.cc:173
ConstHostCollection getAll4(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv4 subnet.
Definition: host_mgr.cc:153
static void delAllBackends()
Delete all alternate backends.
Definition: host_mgr.cc:81
static void create()
Creates new instance of the HostMgr.
Definition: host_mgr.cc:54
virtual void cacheNegative(const SubnetID &ipv4_subnet_id, const SubnetID &ipv6_subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Cache a negative answer.
Definition: host_mgr.cc:942
virtual ConstHostCollection getPage6(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv6 subnet.
Definition: host_mgr.cc:292
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
Definition: host_mgr.cc:960
ConstHostPtr get6Any(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns any host connected to the IPv6 subnet.
Definition: host_mgr.cc:592
ConstHostCollection getAllbyHostname4(const std::string &hostname, const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts with a hostname in a DHCPv4 subnet.
Definition: host_mgr.cc:213
bool del4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target)
Attempts to delete a host by (subnet4-id, identifier, identifier-type, operation-target)
Definition: host_mgr.cc:826
virtual void cache(ConstHostPtr host) const
Cache an answer.
Definition: host_mgr.cc:929
virtual ConstHostCollection getPage6(size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts.
Definition: host_mgr.cc:353
static bool delBackend(const std::string &db_type)
Delete an alternate host backend (aka host data source).
Definition: host_mgr.cc:64
static void addBackend(const std::string &access)
Add an alternate host backend (aka host data source).
Definition: host_mgr.cc:59
ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
Definition: host_mgr.cc:125
ConstHostPtr get4Any(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns any host connected to the IPv4 subnet.
Definition: host_mgr.cc:403
bool del6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target)
Attempts to delete a host by (subnet6-id, identifier, identifier-type, operation-target)
Definition: host_mgr.cc:863
void add(const HostPtr &host, const HostMgrOperationTarget target)
Adds a new host to the alternate data source.
Definition: host_mgr.cc:766
bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr, const HostMgrOperationTarget target)
Attempts to delete hosts by address.
Definition: host_mgr.cc:796
ConstHostCollection getAllbyHostname6(const std::string &hostname, const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts with a hostname in a DHCPv6 subnet.
Definition: host_mgr.cc:237
virtual ConstHostCollection getPage4(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv4 subnet.
Definition: host_mgr.cc:261
HostDataSourcePtr getHostDataSource() const
Returns the first host data source.
Definition: host_mgr.cc:86
static bool checkCacheBackend(bool logging=false)
Check for the cache host backend.
Definition: host_mgr.cc:94
static HostMgr & instance()
Returns a sole instance of the HostMgr.
Definition: host_mgr.cc:116
void update(HostPtr const &host, const HostMgrOperationTarget target)
Implements BaseHostDataSource::update() for alternate sources.
Definition: host_mgr.cc:900
ConstHostCollection getAllbyHostname(const std::string &hostname, const HostMgrOperationTarget target) const
Return all hosts with a hostname.
Definition: host_mgr.cc:193
ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv4 subnet.
Definition: host_mgr.cc:467
ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv6 subnet.
Definition: host_mgr.cc:652
Wraps value holding size of the page with host reservations.
Represents a device with IPv4 and/or IPv6 reservations.
Definition: host.h:297
IdentifierType
Type of the host identifier.
Definition: host.h:307
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Definition: host.cc:274
No host data source instance exception.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
boost::shared_ptr< BaseHostDataSource > HostDataSourcePtr
HostDataSource pointer.
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET6_SUBNET_ID_IDENTIFIER_NULL
isc::log::Logger hosts_logger("hosts")
Logger for the HostMgr and the code it calls.
Definition: hosts_log.h:51
boost::shared_ptr< const CfgHosts > ConstCfgHostsPtr
Const pointer.
Definition: cfg_hosts.h:944
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET6_PREFIX
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
Definition: host.h:807
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Definition: host.h:813
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET6_SUBNET_ID_ADDRESS6
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_IDENTIFIER_HOST
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET6_SUBNET_ID_IDENTIFIER_HOST
std::vector< HostDataSourcePtr > HostDataSourceList
HostDataSource list.
const isc::log::MessageID HOSTS_CFG_CACHE_HOST_DATA_SOURCE
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_ADDRESS4
const int HOSTS_DBG_TRACE
Logging levels for the host reservations management.
Definition: hosts_log.h:27
boost::shared_ptr< CacheHostDataSource > CacheHostDataSourcePtr
CacheHostDataSource pointer.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
const isc::log::MessageID HOSTS_MGR_NON_UNIQUE_IP_UNSUPPORTED
boost::shared_ptr< CfgHosts > CfgHostsPtr
Non-const pointer.
Definition: cfg_hosts.h:941
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition: host.h:810
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_IDENTIFIER
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET_ALL_SUBNET_ID_ADDRESS4
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET_ALL_SUBNET_ID_ADDRESS6
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_IDENTIFIER_NULL
const int HOSTS_DBG_RESULTS
Records the results of the lookups.
Definition: hosts_log.h:33
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET6_SUBNET_ID_IDENTIFIER
HostMgrOperationTarget
Definition: host_mgr.h:25
@ PRIMARY_SOURCE
Definition: host_mgr.h:29
@ ALTERNATE_SOURCES
Definition: host_mgr.h:31
@ ALL_SOURCES
Definition: host_mgr.h:33
Defines the logger used by the top-level component of kea-lfc.