Kea 2.7.5
host_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2024 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
14namespace {
15
23isc::dhcp::CfgHostsPtr getCfgHostsForEdit() {
24 return (isc::dhcp::CfgMgr::instance().getCurrentCfg()->getCfgHosts());
25}
26
33isc::dhcp::ConstCfgHostsPtr getCfgHosts() {
34 return (getCfgHostsForEdit());
35}
36
37} // end of anonymous namespace
38
39namespace isc {
40namespace dhcp {
41
42using namespace isc::asiolink;
43using namespace isc::db;
44
45boost::scoped_ptr<HostMgr>&
46HostMgr::getHostMgrPtr() {
47 static boost::scoped_ptr<HostMgr> host_mgr_ptr;
48 return (host_mgr_ptr);
49}
50
51void
53 getHostMgrPtr().reset(new HostMgr());
54}
55
56void
57HostMgr::addBackend(const std::string& access) {
58 HostDataSourceFactory::add(getHostMgrPtr()->alternate_sources_, access);
59}
60
61bool
62HostMgr::delBackend(const std::string& db_type) {
63 if (getHostMgrPtr()->cache_ptr_ &&
64 getHostMgrPtr()->cache_ptr_->getType() == db_type) {
65 getHostMgrPtr()->cache_ptr_.reset();
66 }
67 return (HostDataSourceFactory::del(getHostMgrPtr()->alternate_sources_,
68 db_type));
69}
70
71bool
72HostMgr::delBackend(const std::string& db_type, const std::string& access,
73 bool if_unusable) {
74 return (HostDataSourceFactory::del(getHostMgrPtr()->alternate_sources_,
75 db_type, access, if_unusable));
76}
77
78void
80 getHostMgrPtr()->alternate_sources_.clear();
81}
82
85 if (alternate_sources_.empty()) {
86 return (HostDataSourcePtr());
87 }
88 return (alternate_sources_[0]);
89}
90
91bool
93 if (getHostMgrPtr()->cache_ptr_) {
94 return (true);
95 }
96 HostDataSourceList& sources = getHostMgrPtr()->alternate_sources_;
97 if (sources.empty()) {
98 return (false);
99 }
100 CacheHostDataSourcePtr cache_ptr =
101 boost::dynamic_pointer_cast<CacheHostDataSource>(sources[0]);
102 if (cache_ptr) {
103 getHostMgrPtr()->cache_ptr_ = cache_ptr;
104 if (logging) {
106 .arg(cache_ptr->getType());
107 }
108 return (true);
109 }
110 return (false);
111}
112
113HostMgr&
115 boost::scoped_ptr<HostMgr>& host_mgr_ptr = getHostMgrPtr();
116 if (!host_mgr_ptr) {
117 create();
118 }
119 return (*host_mgr_ptr);
120}
121
124 const uint8_t* identifier_begin,
125 const size_t identifier_len,
126 const HostMgrOperationTarget target) const {
129 hosts = getCfgHosts()->getAll(identifier_type, identifier_begin,
130 identifier_len);
131 }
133 for (auto const& source : alternate_sources_) {
134 ConstHostCollection hosts_plus =
135 source->getAll(identifier_type, identifier_begin, identifier_len);
136 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
137 }
138 }
139 return (hosts);
140}
141
144 const uint8_t* identifier_begin,
145 const size_t identifier_len) const {
146 return getAll(identifier_type, identifier_begin, identifier_len,
148}
149
151HostMgr::getAll4(const SubnetID& subnet_id, const HostMgrOperationTarget target) const {
154 hosts = getCfgHosts()->getAll4(subnet_id);
155 }
157 for (auto const& source : alternate_sources_) {
158 ConstHostCollection hosts_plus = source->getAll4(subnet_id);
159 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
160 }
161 }
162 return (hosts);
163}
164
166HostMgr::getAll4(const SubnetID& subnet_id) const {
168}
169
171HostMgr::getAll6(const SubnetID& subnet_id, const HostMgrOperationTarget target) const {
174 hosts = getCfgHosts()->getAll6(subnet_id);
175 }
177 for (auto const& source : alternate_sources_) {
178 ConstHostCollection hosts_plus = source->getAll6(subnet_id);
179 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
180 }
181 }
182 return (hosts);
183}
184
186HostMgr::getAll6(const SubnetID& subnet_id) const {
188}
189
191HostMgr::getAllbyHostname(const std::string& hostname, const HostMgrOperationTarget target) const {
194 hosts = getCfgHosts()->getAllbyHostname(hostname);
195 }
197 for (auto const& source : alternate_sources_) {
198 ConstHostCollection hosts_plus = source->getAllbyHostname(hostname);
199 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
200 }
201 }
202 return (hosts);
203}
204
206HostMgr::getAllbyHostname(const std::string& hostname) const {
208}
209
211HostMgr::getAllbyHostname4(const std::string& hostname,
212 const SubnetID& subnet_id,
213 const HostMgrOperationTarget target) const {
216 hosts = getCfgHosts()->getAllbyHostname4(hostname, subnet_id);
217 }
219 for (auto const& source : alternate_sources_) {
220 ConstHostCollection hosts_plus = source->getAllbyHostname4(hostname,
221 subnet_id);
222 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
223 }
224 }
225 return (hosts);
226}
227
229HostMgr::getAllbyHostname4(const std::string& hostname,
230 const SubnetID& subnet_id) const {
231 return getAllbyHostname4(hostname, subnet_id, HostMgrOperationTarget::ALL_SOURCES);
232}
233
235HostMgr::getAllbyHostname6(const std::string& hostname,
236 const SubnetID& subnet_id,
237 const HostMgrOperationTarget target) const {
240 hosts = getCfgHosts()->getAllbyHostname6(hostname, subnet_id);
241 }
243 for (auto const& source : alternate_sources_) {
244 ConstHostCollection hosts_plus = source->getAllbyHostname6(hostname,
245 subnet_id);
246 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
247 }
248 }
249 return (hosts);
250}
251
253HostMgr::getAllbyHostname6(const std::string& hostname,
254 const SubnetID& subnet_id) const {
255 return getAllbyHostname6(hostname, subnet_id, HostMgrOperationTarget::ALL_SOURCES);
256}
257
260 size_t& source_index,
261 uint64_t lower_host_id,
262 const HostPageSize& page_size) const {
263 // Return empty if (and only if) sources are exhausted.
264 if (source_index > alternate_sources_.size()) {
265 return (ConstHostCollection());
266 }
267
269 // Source index 0 means config file.
270 if (source_index == 0) {
271 hosts = getCfgHosts()->
272 getPage4(subnet_id, source_index, lower_host_id, page_size);
273 } else {
274 hosts = alternate_sources_[source_index - 1]->
275 getPage4(subnet_id, source_index, lower_host_id, page_size);
276 }
277
278 // When got something return it.
279 if (!hosts.empty()) {
280 return (hosts);
281 }
282
283 // Nothing from this source: try the next one.
284 // Note the recursion is limited to the number of sources in all cases.
285 ++source_index;
286 return (getPage4(subnet_id, source_index, 0UL, page_size));
287}
288
291 size_t& source_index,
292 uint64_t lower_host_id,
293 const HostPageSize& page_size) const {
294 // Return empty if (and only if) sources are exhausted.
295 if (source_index > alternate_sources_.size()) {
296 return (ConstHostCollection());
297 }
298
300 // Source index 0 means config file.
301 if (source_index == 0) {
302 hosts = getCfgHosts()->
303 getPage6(subnet_id, source_index, lower_host_id, page_size);
304 } else {
305 hosts = alternate_sources_[source_index - 1]->
306 getPage6(subnet_id, source_index, lower_host_id, page_size);
307 }
308
309 // When got something return it.
310 if (!hosts.empty()) {
311 return (hosts);
312 }
313
314 // Nothing from this source: try the next one.
315 // Note the recursion is limited to the number of sources in all cases.
316 ++source_index;
317 return (getPage6(subnet_id, source_index, 0UL, page_size));
318}
319
321HostMgr::getPage4(size_t& source_index,
322 uint64_t lower_host_id,
323 const HostPageSize& page_size) const {
324 // Return empty if (and only if) sources are exhausted.
325 if (source_index > alternate_sources_.size()) {
326 return (ConstHostCollection());
327 }
328
330 // Source index 0 means config file.
331 if (source_index == 0) {
332 hosts = getCfgHosts()->
333 getPage4(source_index, lower_host_id, page_size);
334 } else {
335 hosts = alternate_sources_[source_index - 1]->
336 getPage4(source_index, lower_host_id, page_size);
337 }
338
339 // When got something return it.
340 if (!hosts.empty()) {
341 return (hosts);
342 }
343
344 // Nothing from this source: try the next one.
345 // Note the recursion is limited to the number of sources in all cases.
346 ++source_index;
347 return (getPage4(source_index, 0UL, page_size));
348}
349
351HostMgr::getPage6(size_t& source_index,
352 uint64_t lower_host_id,
353 const HostPageSize& page_size) const {
354 // Return empty if (and only if) sources are exhausted.
355 if (source_index > alternate_sources_.size()) {
356 return (ConstHostCollection());
357 }
358
360 // Source index 0 means config file.
361 if (source_index == 0) {
362 hosts = getCfgHosts()->
363 getPage6(source_index, lower_host_id, page_size);
364 } else {
365 hosts = alternate_sources_[source_index - 1]->
366 getPage6(source_index, lower_host_id, page_size);
367 }
368
369 // When got something return it.
370 if (!hosts.empty()) {
371 return (hosts);
372 }
373
374 // Nothing from this source: try the next one.
375 // Note the recursion is limited to the number of sources in all cases.
376 ++source_index;
377 return (getPage6(source_index, 0UL, page_size));
378}
379
381HostMgr::getAll4(const IOAddress& address, const HostMgrOperationTarget target) const {
384 hosts = getCfgHosts()->getAll4(address);
385 }
387 for (auto const& source : alternate_sources_) {
388 ConstHostCollection hosts_plus = source->getAll4(address);
389 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
390 }
391 }
392 return (hosts);
393}
394
396HostMgr::getAll4(const IOAddress& address) const {
398}
399
401HostMgr::get4Any(const SubnetID& subnet_id,
402 const Host::IdentifierType& identifier_type,
403 const uint8_t* identifier_begin,
404 const size_t identifier_len,
405 const HostMgrOperationTarget target) const {
406 ConstHostPtr host;
408 host = getCfgHosts()->get4(subnet_id, identifier_type,
409 identifier_begin, identifier_len);
410 }
411
412 // Found it in the config file, there are no backends configured, or
413 // querying them is disabled?
414 // Then we're done here.
415 if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
416 return (host);
417 }
418
421 .arg(subnet_id)
422 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
423 identifier_len));
424
425 // Try to find a host in each configured backend. We return as soon
426 // as we find first hit.
427 for (auto const& source : alternate_sources_) {
428 host = source->get4(subnet_id, identifier_type,
429 identifier_begin, identifier_len);
430
431 if (host) {
434 .arg(subnet_id)
435 .arg(Host::getIdentifierAsText(identifier_type,
436 identifier_begin,
437 identifier_len))
438 .arg(source->getType())
439 .arg(host->toText());
440
441 if (source != cache_ptr_) {
442 cache(host);
443 }
444 return (host);
445 }
446 }
449 .arg(subnet_id)
450 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
451 identifier_len));
452 return (ConstHostPtr());
453}
454
456HostMgr::get4Any(const SubnetID& subnet_id,
457 const Host::IdentifierType& identifier_type,
458 const uint8_t* identifier_begin,
459 const size_t identifier_len) const {
460 return get4Any(subnet_id, identifier_type, identifier_begin, identifier_len,
462}
463
465HostMgr::get4(const SubnetID& subnet_id,
466 const Host::IdentifierType& identifier_type,
467 const uint8_t* identifier_begin,
468 const size_t identifier_len,
469 const HostMgrOperationTarget target) const {
470 ConstHostPtr host = get4Any(subnet_id, identifier_type,
471 identifier_begin, identifier_len, target);
472 if (host && host->getNegative()) {
473 return (ConstHostPtr());
474 } else if (!host && negative_caching_) {
475 cacheNegative(subnet_id, SubnetID(SUBNET_ID_UNUSED),
476 identifier_type, identifier_begin, identifier_len);
477 }
478 return (host);
479}
480
482HostMgr::get4(const SubnetID& subnet_id,
483 const Host::IdentifierType& identifier_type,
484 const uint8_t* identifier_begin,
485 const size_t identifier_len) const {
486 return get4(subnet_id, identifier_type, identifier_begin, identifier_len,
488}
489
491HostMgr::get4(const SubnetID& subnet_id,
492 const asiolink::IOAddress& address,
493 const HostMgrOperationTarget target) const {
494 ConstHostPtr host;
496 host = getCfgHosts()->get4(subnet_id, address);
497 }
498
499 if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
500 return (host);
501 }
504 .arg(subnet_id)
505 .arg(address.toText());
506 for (auto const& source : alternate_sources_) {
507 host = source->get4(subnet_id, address);
508 if (host && host->getNegative()) {
509 return (ConstHostPtr());
510 }
511 if (host && source != cache_ptr_) {
512 cache(host);
513 }
514 if (host) {
515 return (host);
516 }
517 }
518 return (ConstHostPtr());
519}
520
522HostMgr::get4(const SubnetID& subnet_id,
523 const asiolink::IOAddress& address) const {
524 return get4(subnet_id, address, HostMgrOperationTarget::ALL_SOURCES);
525}
526
528HostMgr::getAll4(const SubnetID& subnet_id,
529 const asiolink::IOAddress& address,
530 const HostMgrOperationTarget target) const {
533 hosts = getCfgHosts()->getAll4(subnet_id, address);
534 }
535
539 .arg(subnet_id)
540 .arg(address.toText());
541
542 for (auto const& source : alternate_sources_) {
543 auto hosts_plus = source->getAll4(subnet_id, address);
544 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
545 }
546 }
547 return (hosts);
548}
549
551HostMgr::getAll4(const SubnetID& subnet_id,
552 const asiolink::IOAddress& address) const {
553 return getAll4(subnet_id, address, HostMgrOperationTarget::ALL_SOURCES);
554}
555
557HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len,
558 const HostMgrOperationTarget target) const {
559 ConstHostPtr host;
561 host = getCfgHosts()->get6(prefix, prefix_len);
562 }
563 if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
564 return (host);
565 }
567 .arg(prefix.toText())
568 .arg(static_cast<int>(prefix_len));
569 for (auto const& source : alternate_sources_) {
570 host = source->get6(prefix, prefix_len);
571 if (host && host->getNegative()) {
572 return (ConstHostPtr());
573 }
574 if (host && source != cache_ptr_) {
575 cache(host);
576 }
577 if (host) {
578 return (host);
579 }
580 }
581 return (ConstHostPtr());
582}
583
585HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
586 return get6(prefix, prefix_len, HostMgrOperationTarget::ALL_SOURCES);
587}
588
590HostMgr::get6Any(const SubnetID& subnet_id,
591 const Host::IdentifierType& identifier_type,
592 const uint8_t* identifier_begin,
593 const size_t identifier_len,
594 const HostMgrOperationTarget target) const {
595 ConstHostPtr host;
597 host = getCfgHosts()->get6(subnet_id, identifier_type,
598 identifier_begin, identifier_len);
599 }
600 if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
601 return (host);
602 }
603
606 .arg(subnet_id)
607 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
608 identifier_len));
609
610 for (auto const& source : alternate_sources_) {
611 host = source->get6(subnet_id, identifier_type,
612 identifier_begin, identifier_len);
613
614 if (host) {
617 .arg(subnet_id)
618 .arg(Host::getIdentifierAsText(identifier_type,
619 identifier_begin,
620 identifier_len))
621 .arg(source->getType())
622 .arg(host->toText());
623
624 if (source != cache_ptr_) {
625 cache(host);
626 }
627 return (host);
628 }
629 }
630
633 .arg(subnet_id)
634 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin,
635 identifier_len));
636
637 return (ConstHostPtr());
638}
639
641HostMgr::get6Any(const SubnetID& subnet_id,
642 const Host::IdentifierType& identifier_type,
643 const uint8_t* identifier_begin,
644 const size_t identifier_len) const {
645 return get6Any(subnet_id, identifier_type, identifier_begin, identifier_len,
647}
648
650HostMgr::get6(const SubnetID& subnet_id,
651 const Host::IdentifierType& identifier_type,
652 const uint8_t* identifier_begin,
653 const size_t identifier_len,
654 const HostMgrOperationTarget target) const {
655 ConstHostPtr host = get6Any(subnet_id, identifier_type,
656 identifier_begin, identifier_len, target);
657 if (host && host->getNegative()) {
658 return (ConstHostPtr());
659 } else if (!host && negative_caching_) {
660 cacheNegative(SubnetID(SUBNET_ID_UNUSED), subnet_id,
661 identifier_type, identifier_begin, identifier_len);
662 }
663 return (host);
664}
665
667HostMgr::get6(const SubnetID& subnet_id,
668 const Host::IdentifierType& identifier_type,
669 const uint8_t* identifier_begin,
670 const size_t identifier_len) const {
671 return get6(subnet_id, identifier_type, identifier_begin, identifier_len,
673}
674
676HostMgr::get6(const SubnetID& subnet_id,
677 const asiolink::IOAddress& addr,
678 const HostMgrOperationTarget target) const {
679 ConstHostPtr host;
681 host = getCfgHosts()->get6(subnet_id, addr);
682 }
683 if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
684 return (host);
685 }
688 .arg(subnet_id)
689 .arg(addr.toText());
690 for (auto const& source : alternate_sources_) {
691 host = source->get6(subnet_id, addr);
692 if (host && host->getNegative()) {
693 return (ConstHostPtr());
694 }
695 if (host && source != cache_ptr_) {
696 cache(host);
697 }
698 if (host) {
699 return (host);
700 }
701 }
702 return (ConstHostPtr());
703}
704
706HostMgr::get6(const SubnetID& subnet_id,
707 const asiolink::IOAddress& addr) const {
708 return get6(subnet_id, addr, HostMgrOperationTarget::ALL_SOURCES);
709}
710
712HostMgr::getAll6(const SubnetID& subnet_id,
713 const asiolink::IOAddress& address,
714 const HostMgrOperationTarget target) const {
716
718 hosts = getCfgHosts()->getAll6(subnet_id, address);
719 }
720
724 .arg(subnet_id)
725 .arg(address.toText());
726
727 for (auto const& source : alternate_sources_) {
728 auto hosts_plus = source->getAll6(subnet_id, address);
729 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
730 }
731 }
732 return (hosts);
733}
734
736HostMgr::getAll6(const SubnetID& subnet_id,
737 const asiolink::IOAddress& address) const {
738 return getAll6(subnet_id, address, HostMgrOperationTarget::ALL_SOURCES);
739}
740
742HostMgr::getAll6(const IOAddress& address) const {
744}
745
747HostMgr::getAll6(const IOAddress& address, const HostMgrOperationTarget target) const {
750 hosts = getCfgHosts()->getAll6(address);
751 }
752
754 for (auto const& source : alternate_sources_) {
755 ConstHostCollection hosts_plus = source->getAll6(address);
756 hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
757 }
758 }
759
760 return (hosts);
761}
762
763void
764HostMgr::add(const HostPtr& host, const HostMgrOperationTarget target) {
766 getCfgHostsForEdit()->add(host);
767 }
768
770 // Don't throw if all targets were selected.
771 if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
772 isc_throw(NoHostDataSourceManager, "Unable to add new host because there is "
773 "no hosts-database configured.");
774
775 }
776
777 for (auto const& source : alternate_sources_) {
778 source->add(host);
779 }
780 }
781
782 // If no backend throws the host should be cached.
783 if (cache_ptr_) {
784 cache(host);
785 }
786}
787
788void
792
793bool
794HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr,
795 const HostMgrOperationTarget target) {
796 size_t erased = false;
797
799 erased = getCfgHostsForEdit()->del(subnet_id, addr);
800 }
801
803 // Don't throw if all targets were selected.
804 if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
805 isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
806 "no hosts-database configured.");
807 }
808
809 for (auto const& source : alternate_sources_) {
810 bool alternate_erased = source->del(subnet_id, addr);
811 erased = alternate_erased || erased;
812 }
813 }
814
815 return (erased);
816}
817
818bool
819HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) {
820 return del(subnet_id, addr, HostMgrOperationTarget::ALTERNATE_SOURCES);
821}
822
823bool
824HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
825 const uint8_t* identifier_begin, const size_t identifier_len,
826 const HostMgrOperationTarget target) {
827 bool success = false;
828
830 if (getCfgHostsForEdit()->del4(subnet_id, identifier_type,
831 identifier_begin, identifier_len)) {
832 success = true;
833 }
834 }
835
837 // Don't throw if all targets were selected.
838 if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
839 isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
840 "no hosts-database configured.");
841 }
842
843 for (auto const& source : alternate_sources_) {
844 if (source->del4(subnet_id, identifier_type,
845 identifier_begin, identifier_len)) {
846 success = true;
847 }
848 }
849 }
850 return (success);
851}
852
853bool
854HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
855 const uint8_t* identifier_begin, const size_t identifier_len) {
856 return del4(subnet_id, identifier_type, identifier_begin, identifier_len,
858}
859
860bool
861HostMgr::del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
862 const uint8_t* identifier_begin, const size_t identifier_len,
863 const HostMgrOperationTarget target) {
864 bool success = false;
865
867 if (getCfgHostsForEdit()->del6(subnet_id, identifier_type,
868 identifier_begin, identifier_len)) {
869 success = true;
870 }
871 }
872
874 // Don't throw if all targets were selected.
875 if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
876 isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
877 "no hosts-database configured.");
878 }
879
880 for (auto const& source : alternate_sources_) {
881 if (source->del6(subnet_id, identifier_type,
882 identifier_begin, identifier_len)) {
883 success = true;
884 }
885 }
886 }
887 return (success);
888}
889
890bool
891HostMgr::del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
892 const uint8_t* identifier_begin, const size_t identifier_len) {
893 return del6(subnet_id, identifier_type, identifier_begin, identifier_len,
895}
896
897void
900 getCfgHostsForEdit()->update(host);
901 }
902
904 // Don't throw if all targets were selected.
905 if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::PRIMARY_SOURCE)) {
907 "Unable to update existing host because there is no hosts-database configured.");
908 }
909
910 for (HostDataSourcePtr const& source : alternate_sources_) {
911 source->update(host);
912 }
913 }
914
915 // If no backend throws the host should be cached.
916 if (cache_ptr_) {
917 cache(host);
918 }
919}
920
921void
925
926void
928 if (cache_ptr_) {
929 // Need a real host.
930 if (!host || host->getNegative()) {
931 return;
932 }
933 // Replace any existing value.
934 // Don't check the result as it does not matter?
935 cache_ptr_->insert(host, true);
936 }
937}
938
939void
940HostMgr::cacheNegative(const SubnetID& ipv4_subnet_id,
941 const SubnetID& ipv6_subnet_id,
942 const Host::IdentifierType& identifier_type,
943 const uint8_t* identifier_begin,
944 const size_t identifier_len) const {
945 if (cache_ptr_ && negative_caching_) {
946 HostPtr host(new Host(identifier_begin, identifier_len,
947 identifier_type,
948 ipv4_subnet_id, ipv6_subnet_id,
950 host->setNegative(true);
951 // Don't replace any existing value.
952 // nor matter if it fails.
953 cache_ptr_->insert(host, false);
954 }
955}
956
957bool
959 // Iterate over the alternate sources first, because they may include those
960 // for which the new setting is not supported.
961 for (auto const& source : alternate_sources_) {
962 if (!source->setIPReservationsUnique(unique)) {
963 // One of the sources does not support this new mode of operation.
964 // Let's log a warning and back off the changes to the default
965 // setting which should always be supported.
966 ip_reservations_unique_ = true;
968 .arg(source->getType());
969 for (auto const& src : alternate_sources_) {
970 src->setIPReservationsUnique(true);
971 }
972 return (false);
973 }
974 }
975 // Successfully configured the HostMgr to use the new setting.
976 // Remember this setting so we can return it via the
977 // getIPReservationsUnique.
978 ip_reservations_unique_ = unique;
979 return (true);
980}
981
982} // end of isc::dhcp namespace
983} // 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:171
ConstHostCollection getAll4(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv4 subnet.
Definition host_mgr.cc:151
static void delAllBackends()
Delete all alternate backends.
Definition host_mgr.cc:79
static void create()
Creates new instance of the HostMgr.
Definition host_mgr.cc:52
bool negative_caching_
The negative caching flag.
Definition host_mgr.h:842
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:940
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:290
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
Definition host_mgr.cc:958
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:590
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:211
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:824
virtual void cache(ConstHostPtr host) const
Cache an answer.
Definition host_mgr.cc:927
static bool delBackend(const std::string &db_type)
Delete an alternate host backend (aka host data source).
Definition host_mgr.cc:62
static void addBackend(const std::string &access)
Add an alternate host backend (aka host data source).
Definition host_mgr.cc:57
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:123
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:401
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:861
void add(const HostPtr &host, const HostMgrOperationTarget target)
Adds a new host to the alternate data source.
Definition host_mgr.cc:764
bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr, const HostMgrOperationTarget target)
Attempts to delete hosts by address.
Definition host_mgr.cc:794
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:235
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:259
HostDataSourcePtr getHostDataSource() const
Returns the first host data source.
Definition host_mgr.cc:84
static bool checkCacheBackend(bool logging=false)
Check for the cache host backend.
Definition host_mgr.cc:92
static HostMgr & instance()
Returns a sole instance of the HostMgr.
Definition host_mgr.cc:114
void update(HostPtr const &host, const HostMgrOperationTarget target)
Implements BaseHostDataSource::update() for alternate sources.
Definition host_mgr.cc:898
ConstHostCollection getAllbyHostname(const std::string &hostname, const HostMgrOperationTarget target) const
Return all hosts with a hostname.
Definition host_mgr.cc:191
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:465
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:650
Wraps value holding size of the page with host reservations.
Represents a device with IPv4 and/or IPv6 reservations.
Definition host.h:327
IdentifierType
Type of the host identifier.
Definition host.h:337
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Definition host.cc:312
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:976
const isc::log::MessageID HOSTS_MGR_ALTERNATE_GET6_PREFIX
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
Definition host.h:837
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Definition host.h:843
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:973
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition host.h:840
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.