Kea 2.5.9
cfg_hosts.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 <dhcp/duid.h>
9#include <dhcp/hwaddr.h>
10#include <dhcpsrv/cfg_hosts.h>
12#include <dhcpsrv/hosts_log.h>
13#include <dhcpsrv/cfgmgr.h>
15#include <util/encode/encode.h>
16#include <boost/foreach.hpp>
17#include <ostream>
18#include <string>
19#include <vector>
20
21using namespace isc::asiolink;
22using namespace isc::data;
23using namespace std;
24
25namespace isc {
26namespace dhcp {
27
30 const uint8_t* identifier_begin,
31 const size_t identifier_len) const {
32 // Do not issue logging message here because it will be logged by
33 // the getAllInternal method.
34 ConstHostCollection collection;
35 getAllInternal<ConstHostCollection>(identifier_type, identifier_begin,
36 identifier_len, collection);
37 return (collection);
38}
39
42 const uint8_t* identifier_begin, const size_t identifier_len) {
43 // Do not issue logging message here because it will be logged by
44 // the getAllInternal method.
45 HostCollection collection;
46 getAllInternal<HostCollection>(identifier_type, identifier_begin,
47 identifier_len, collection);
48 return (collection);
49}
50
52CfgHosts::getAll4(const SubnetID& subnet_id) const {
53 // Do not issue logging message here because it will be logged by
54 // the getAllInternal4 method.
55 ConstHostCollection collection;
56 getAllInternal4<ConstHostCollection>(subnet_id, collection);
57 return (collection);
58}
59
61CfgHosts::getAll4(const SubnetID& subnet_id) {
62 // Do not issue logging message here because it will be logged by
63 // the getAllInternal4 method.
64 HostCollection collection;
65 getAllInternal4<HostCollection>(subnet_id, collection);
66 return (collection);
67}
68
70CfgHosts::getAll6(const SubnetID& subnet_id) const {
71 // Do not issue logging message here because it will be logged by
72 // the getAllInternal6 method.
73 ConstHostCollection collection;
74 getAllInternal6<ConstHostCollection>(subnet_id, collection);
75 return (collection);
76}
77
79CfgHosts::getAll6(const SubnetID& subnet_id) {
80 // Do not issue logging message here because it will be logged by
81 // the getAllInternal6 method.
82 HostCollection collection;
83 getAllInternal6<HostCollection>(subnet_id, collection);
84 return (collection);
85}
86
88CfgHosts::getAllbyHostname(const std::string& hostname) const {
89 // Do not issue logging message here because it will be logged by
90 // the getAllbyHostnameInternal method.
91 ConstHostCollection collection;
92 getAllbyHostnameInternal<ConstHostCollection>(hostname, collection);
93 return (collection);
94}
95
97CfgHosts::getAllbyHostname(const std::string& hostname) {
98 // Do not issue logging message here because it will be logged by
99 // the getAllbyHostnameInternal method.
100 HostCollection collection;
101 getAllbyHostnameInternal<HostCollection>(hostname, collection);
102 return (collection);
103}
104
106CfgHosts::getAllbyHostname4(const std::string& hostname,
107 const SubnetID& subnet_id) const {
108 // Do not issue logging message here because it will be logged by
109 // the getAllbyHostnameInternal4 method.
110 ConstHostCollection collection;
111 getAllbyHostnameInternal4<ConstHostCollection>(hostname, subnet_id, collection);
112 return (collection);
113}
114
116CfgHosts::getAllbyHostname4(const std::string& hostname,
117 const SubnetID& subnet_id) {
118 // Do not issue logging message here because it will be logged by
119 // the getAllbyHostnameInternal4 method.
120 HostCollection collection;
121 getAllbyHostnameInternal4<HostCollection>(hostname, subnet_id, collection);
122 return (collection);
123}
124
126CfgHosts::getAllbyHostname6(const std::string& hostname,
127 const SubnetID& subnet_id) const {
128 // Do not issue logging message here because it will be logged by
129 // the getAllbyHostnameInternal6 method.
130 ConstHostCollection collection;
131 getAllbyHostnameInternal6<ConstHostCollection>(hostname, subnet_id, collection);
132 return (collection);
133}
134
136CfgHosts::getAllbyHostname6(const std::string& hostname,
137 const SubnetID& subnet_id) {
138 // Do not issue logging message here because it will be logged by
139 // the getAllbyHostnameInternal6 method.
140 HostCollection collection;
141 getAllbyHostnameInternal6<HostCollection>(hostname, subnet_id, collection);
142 return (collection);
143}
144
147 size_t& /*source_index*/,
148 uint64_t lower_host_id,
149 const HostPageSize& page_size) const {
150 // Do not issue logging message here because it will be logged by
151 // the getPageInternal4 method.
152 ConstHostCollection collection;
153 getPageInternal4<ConstHostCollection>(subnet_id,
154 lower_host_id,
155 page_size,
156 collection);
157 return (collection);
158}
159
162 size_t& /*source_index*/,
163 uint64_t lower_host_id,
164 const HostPageSize& page_size) {
165 // Do not issue logging message here because it will be logged by
166 // the getPageInternal4 method.
167 HostCollection collection;
168 getPageInternal4<HostCollection>(subnet_id,
169 lower_host_id,
170 page_size,
171 collection);
172 return (collection);
173}
174
177 size_t& /*source_index*/,
178 uint64_t lower_host_id,
179 const HostPageSize& page_size) const {
180 // Do not issue logging message here because it will be logged by
181 // the getPageInternal6 method.
182 ConstHostCollection collection;
183 getPageInternal6<ConstHostCollection>(subnet_id,
184 lower_host_id,
185 page_size,
186 collection);
187 return (collection);
188}
189
192 size_t& /*source_index*/,
193 uint64_t lower_host_id,
194 const HostPageSize& page_size) {
195 // Do not issue logging message here because it will be logged by
196 // the getPageInternal6 method.
197 HostCollection collection;
198 getPageInternal6<HostCollection>(subnet_id,
199 lower_host_id,
200 page_size,
201 collection);
202 return (collection);
203}
204
206CfgHosts::getPage4(size_t& /*source_index*/,
207 uint64_t lower_host_id,
208 const HostPageSize& page_size) const {
209 // Do not issue logging message here because it will be logged by
210 // the getPageInternal method.
211 ConstHostCollection collection;
212 getPageInternal<ConstHostCollection>(lower_host_id,
213 page_size,
214 collection);
215 return (collection);
216}
217
219CfgHosts::getPage4(size_t& /*source_index*/,
220 uint64_t lower_host_id,
221 const HostPageSize& page_size) {
222 // Do not issue logging message here because it will be logged by
223 // the getPageInternal method.
224 HostCollection collection;
225 getPageInternal<HostCollection>(lower_host_id,
226 page_size,
227 collection);
228 return (collection);
229}
230
232CfgHosts::getPage6(size_t& /*source_index*/,
233 uint64_t lower_host_id,
234 const HostPageSize& page_size) const {
235 // Do not issue logging message here because it will be logged by
236 // the getPageInternal method.
237 ConstHostCollection collection;
238 getPageInternal<ConstHostCollection>(lower_host_id,
239 page_size,
240 collection);
241 return (collection);
242}
243
245CfgHosts::getPage6(size_t& /*source_index*/,
246 uint64_t lower_host_id,
247 const HostPageSize& page_size) {
248 // Do not issue logging message here because it will be logged by
249 // the getPageInternal method.
250 HostCollection collection;
251 getPageInternal<HostCollection>(lower_host_id,
252 page_size,
253 collection);
254 return (collection);
255}
256
258CfgHosts::getAll4(const IOAddress& address) const {
259 // Do not issue logging message here because it will be logged by
260 // the getAllInternal4 method.
261 ConstHostCollection collection;
262 getAllInternal4<ConstHostCollection>(address, collection);
263 return (collection);
264}
265
268 // Do not issue logging message here because it will be logged by
269 // the getAllInternal4 method.
270 HostCollection collection;
271 getAllInternal4<HostCollection>(address, collection);
272 return (collection);
273}
274
276CfgHosts::getAll6(const IOAddress& address) const {
277 // Do not issue logging message here because it will be logged by
278 // the getAllInternal6 method.
279 ConstHostCollection collection;
280 getAllInternal6<ConstHostCollection>(address, collection);
281 return (collection);
282}
283
286 // Do not issue logging message here because it will be logged by
287 // the getAllInternal6 method.
288 HostCollection collection;
289 getAllInternal6<HostCollection>(address, collection);
290 return (collection);
291}
292
293template<typename Storage>
294void
295CfgHosts::getAllInternal(const Host::IdentifierType& identifier_type,
296 const uint8_t* identifier,
297 const size_t identifier_len,
298 Storage& storage) const {
299
300 // Convert host identifier into textual format for logging purposes.
301 // This conversion is exception free.
302 std::string identifier_text = Host::getIdentifierAsText(identifier_type,
303 identifier,
304 identifier_len);
306 .arg(identifier_text);
307
308 // Use the identifier and identifier type as a composite key.
309 const HostContainerIndex0& idx = hosts_.get<0>();
310 boost::tuple<const std::vector<uint8_t>, const Host::IdentifierType> t =
311 boost::make_tuple(std::vector<uint8_t>(identifier,
312 identifier + identifier_len),
313 identifier_type);
314
315 // Append each Host object to the storage.
316 for (HostContainerIndex0::iterator host = idx.lower_bound(t);
317 host != idx.upper_bound(t);
318 ++host) {
321 .arg(identifier_text)
322 .arg((*host)->toText());
323 storage.push_back(*host);
324 }
325
326 // Log how many hosts have been found.
328 .arg(identifier_text)
329 .arg(storage.size());
330}
331
332template<typename Storage>
333void
334CfgHosts::getAllInternal4(const SubnetID& subnet_id,
335 Storage& storage) const {
336
338 .arg(subnet_id);
339
340 // Use try DHCPv4 subnet id.
341 const HostContainerIndex2& idx = hosts_.get<2>();
342
343 // Append each Host object to the storage.
344 for (HostContainerIndex2::iterator host = idx.lower_bound(subnet_id);
345 host != idx.upper_bound(subnet_id);
346 ++host) {
349 .arg(subnet_id)
350 .arg((*host)->toText());
351 storage.push_back(*host);
352 }
353
354 // Log how many hosts have been found.
356 .arg(subnet_id)
357 .arg(storage.size());
358}
359
360template<typename Storage>
361void
362CfgHosts::getAllInternal6(const SubnetID& subnet_id,
363 Storage& storage) const {
364
366 .arg(subnet_id);
367
368 // Use try DHCPv6 subnet id.
369 const HostContainerIndex3& idx = hosts_.get<3>();
370
371 // Append each Host object to the storage.
372 for (HostContainerIndex3::iterator host = idx.lower_bound(subnet_id);
373 host != idx.upper_bound(subnet_id);
374 ++host) {
377 .arg(subnet_id)
378 .arg((*host)->toText());
379 storage.push_back(*host);
380 }
381
382 // Log how many hosts have been found.
384 .arg(subnet_id)
385 .arg(storage.size());
386}
387
388template<typename Storage>
389void
390CfgHosts::getAllbyHostnameInternal(const std::string& hostname,
391 Storage& storage) const {
392
394 .arg(hostname);
395
396 // Use try hostname.
397 const HostContainerIndex5& idx = hosts_.get<5>();
398
399 // Append each Host object to the storage.
400 for (HostContainerIndex5::iterator host = idx.lower_bound(hostname);
401 host != idx.upper_bound(hostname);
402 ++host) {
405 .arg(hostname)
406 .arg((*host)->toText());
407 storage.push_back(*host);
408 }
409
410 // Log how many hosts have been found.
412 .arg(hostname)
413 .arg(storage.size());
414}
415
416template<typename Storage>
417void
418CfgHosts::getAllbyHostnameInternal4(const std::string& hostname,
419 const SubnetID& subnet_id,
420 Storage& storage) const {
421
424 .arg(hostname)
425 .arg(subnet_id);
426
427 // Use try hostname.
428 const HostContainerIndex5& idx = hosts_.get<5>();
429
430 // Append each Host object to the storage.
431 for (HostContainerIndex5::iterator host = idx.lower_bound(hostname);
432 host != idx.upper_bound(hostname);
433 ++host) {
434 if ((*host)->getIPv4SubnetID() != subnet_id) {
435 continue;
436 }
439 .arg(hostname)
440 .arg(subnet_id)
441 .arg((*host)->toText());
442 storage.push_back(*host);
443 }
444
445 // Log how many hosts have been found.
448 .arg(hostname)
449 .arg(subnet_id)
450 .arg(storage.size());
451}
452
453template<typename Storage>
454void
455CfgHosts::getAllbyHostnameInternal6(const std::string& hostname,
456 const SubnetID& subnet_id,
457 Storage& storage) const {
458
461 .arg(hostname)
462 .arg(subnet_id);
463
464 // Use try hostname.
465 const HostContainerIndex5& idx = hosts_.get<5>();
466
467 // Append each Host object to the storage.
468 for (HostContainerIndex5::iterator host = idx.lower_bound(hostname);
469 host != idx.upper_bound(hostname);
470 ++host) {
471 if ((*host)->getIPv6SubnetID() != subnet_id) {
472 continue;
473 }
476 .arg(hostname)
477 .arg(subnet_id)
478 .arg((*host)->toText());
479 storage.push_back(*host);
480 }
481
482 // Log how many hosts have been found.
485 .arg(hostname)
486 .arg(subnet_id)
487 .arg(storage.size());
488}
489
490template<typename Storage>
491void
492CfgHosts::getPageInternal(uint64_t lower_host_id,
493 const HostPageSize& page_size,
494 Storage& storage) const {
495
497
498 // Use the host id last index.
499 const HostContainerIndex4& idx = hosts_.get<4>();
500 HostContainerIndex4::const_iterator host = idx.lower_bound(lower_host_id);
501
502 // Exclude the lower bound id when it is not zero.
503 if (lower_host_id &&
504 (host != idx.end()) && ((*host)->getHostId() == lower_host_id)) {
505 ++host;
506 }
507
508 // Return hosts within the page size.
509 for (; host != idx.end(); ++host) {
512 .arg((*host)->toText());
513 storage.push_back(*host);
514 if (storage.size() >= page_size.page_size_) {
515 break;
516 }
517 }
518
519 // Log how many hosts have been found.
521 .arg(storage.size());
522}
523
524template<typename Storage>
525void
526CfgHosts::getPageInternal4(const SubnetID& subnet_id,
527 uint64_t lower_host_id,
528 const HostPageSize& page_size,
529 Storage& storage) const {
530
532 .arg(subnet_id);
533
534 // Use the host id last index.
535 const HostContainerIndex4& idx = hosts_.get<4>();
536 HostContainerIndex4::const_iterator host = idx.lower_bound(lower_host_id);
537
538 // Exclude the lower bound id when it is not zero.
539 if (lower_host_id &&
540 (host != idx.end()) && ((*host)->getHostId() == lower_host_id)) {
541 ++host;
542 }
543
544 // Return hosts in the subnet within the page size.
545 for (; host != idx.end(); ++host) {
546 if ((*host)->getIPv4SubnetID() != subnet_id) {
547 continue;
548 }
551 .arg(subnet_id)
552 .arg((*host)->toText());
553 storage.push_back(*host);
554 if (storage.size() >= page_size.page_size_) {
555 break;
556 }
557 }
558
559 // Log how many hosts have been found.
561 .arg(subnet_id)
562 .arg(storage.size());
563}
564
565template<typename Storage>
566void
567CfgHosts::getPageInternal6(const SubnetID& subnet_id,
568 uint64_t lower_host_id,
569 const HostPageSize& page_size,
570 Storage& storage) const {
571
573 .arg(subnet_id);
574
575 // Use the host id last index.
576 const HostContainerIndex4& idx = hosts_.get<4>();
577 HostContainerIndex4::const_iterator host = idx.lower_bound(lower_host_id);
578
579 // Exclude the lower bound id when it is not zero.
580 if (lower_host_id &&
581 (host != idx.end()) && ((*host)->getHostId() == lower_host_id)) {
582 ++host;
583 }
584
585 // Return hosts in the subnet within the page size.
586 for (; host != idx.end(); ++host) {
587 if ((*host)->getIPv6SubnetID() != subnet_id) {
588 continue;
589 }
592 .arg(subnet_id)
593 .arg((*host)->toText());
594 storage.push_back(*host);
595 if (storage.size() >= page_size.page_size_) {
596 break;
597 }
598 }
599
600 // Log how many hosts have been found.
602 .arg(subnet_id)
603 .arg(storage.size());
604}
605
606
607template<typename Storage>
608void
609CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
611 .arg(address.toText());
612
613 // Must not specify address other than IPv4.
614 if (!address.isV4()) {
615 isc_throw(BadHostAddress, "must specify an IPv4 address when searching"
616 " for a host, specified address was " << address);
617 }
618 // Search for the Host using the reserved IPv4 address as a key.
619 const HostContainerIndex1& idx = hosts_.get<1>();
620 HostContainerIndex1Range r = idx.equal_range(address);
621 // Append each Host object to the storage.
622 BOOST_FOREACH(auto const& host, r) {
625 .arg(address.toText())
626 .arg(host->toText());
627 storage.push_back(host);
628 }
629
631 .arg(address.toText())
632 .arg(storage.size());
633}
634
635template<typename Storage>
636void
637CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const {
639 .arg(address.toText());
640
641 // Must not specify address other than IPv6.
642 if (!address.isV6()) {
643 isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
644 " for a host, specified address was " << address);
645 }
646 // Search for the Host using the reserved IPv6 address as a key.
647 const HostContainer6Index4& idx = hosts6_.get<4>();
648 HostContainer6Index4Range r = idx.equal_range(address);
649 // Append each Host object to the storage.
650 BOOST_FOREACH(auto const& reservation, r) {
653 .arg(address.toText())
654 .arg(reservation.host_->toText());
655 storage.push_back(reservation.host_);
656 }
657
659 .arg(address.toText())
660 .arg(storage.size());
661}
662
664CfgHosts::get4(const SubnetID& subnet_id,
665 const Host::IdentifierType& identifier_type,
666 const uint8_t* identifier_begin,
667 const size_t identifier_len) const {
668 return (getHostInternal(subnet_id, false, identifier_type, identifier_begin,
669 identifier_len));
670}
671
673CfgHosts::get4(const SubnetID& subnet_id,
674 const Host::IdentifierType& identifier_type,
675 const uint8_t* identifier_begin,
676 const size_t identifier_len) {
677 return (getHostInternal(subnet_id, false, identifier_type, identifier_begin,
678 identifier_len));
679}
680
682CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
684 .arg(subnet_id).arg(address.toText());
685
686 ConstHostCollection hosts = getAll4(address);
687 for (auto const& host : hosts) {
688 if (host->getIPv4SubnetID() == subnet_id) {
691 .arg(subnet_id)
692 .arg(address.toText())
693 .arg(host->toText());
694 return (host);
695 }
696 }
697
699 .arg(subnet_id).arg(address.toText());
700 return (ConstHostPtr());
701}
702
705 const asiolink::IOAddress& address) const {
707 .arg(subnet_id).arg(address.toText());
708
710 for (auto const& host : getAll4(address)) {
711 if (host->getIPv4SubnetID() == subnet_id) {
714 .arg(subnet_id)
715 .arg(address.toText())
716 .arg(host->toText());
717 hosts.push_back(host);
718 }
719 }
721 .arg(subnet_id)
722 .arg(address.toText())
723 .arg(hosts.size());
724
725 return (hosts);
726}
727
729CfgHosts::get6(const SubnetID& subnet_id,
730 const Host::IdentifierType& identifier_type,
731 const uint8_t* identifier_begin,
732 const size_t identifier_len) const {
733 return (getHostInternal(subnet_id, true, identifier_type, identifier_begin,
734 identifier_len));
735}
736
738CfgHosts::get6(const SubnetID& subnet_id,
739 const Host::IdentifierType& identifier_type,
740 const uint8_t* identifier_begin,
741 const size_t identifier_len) {
742 return (getHostInternal(subnet_id, true, identifier_type, identifier_begin,
743 identifier_len));
744}
745
747CfgHosts::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
748 return (getHostInternal6<ConstHostPtr>(prefix, prefix_len));
749}
750
752CfgHosts::get6(const IOAddress& prefix, const uint8_t prefix_len) {
753 return (getHostInternal6<HostPtr>(prefix, prefix_len));
754}
755
757CfgHosts::get6(const SubnetID& subnet_id,
758 const asiolink::IOAddress& address) const {
759 // Do not log here because getHostInternal6 logs.
760 return (getHostInternal6<ConstHostPtr, ConstHostCollection>(subnet_id, address));
761}
762
764CfgHosts::get6(const SubnetID& subnet_id,
765 const asiolink::IOAddress& address) {
766 // Do not log here because getHostInternal6 logs.
767 return (getHostInternal6<HostPtr, HostCollection>(subnet_id, address));
768}
769
772 const asiolink::IOAddress& address) const {
774 getAllInternal6(subnet_id, address, hosts);
775 return (hosts);
776}
777
778template<typename ReturnType, typename Storage>
779ReturnType
780CfgHosts::getHostInternal6(const SubnetID& subnet_id,
781 const asiolink::IOAddress& address) const {
783 .arg(subnet_id).arg(address.toText());
784
785 Storage storage;
786 getAllInternal6<Storage>(subnet_id, address, storage);
787 switch (storage.size()) {
788 case 0:
791 .arg(subnet_id)
792 .arg(address.toText());
793 return (HostPtr());
794
795 case 1:
798 .arg(subnet_id)
799 .arg(address.toText())
800 .arg((*storage.begin())->toText());
801 return (*storage.begin());
802
803 default:
804 isc_throw(DuplicateHost, "more than one reservation found"
805 " for the host belonging to the subnet with id '"
806 << subnet_id << "' and using the address '"
807 << address.toText() << "'");
808 }
809
810}
811
812template<typename ReturnType>
813ReturnType
814CfgHosts::getHostInternal6(const asiolink::IOAddress& prefix,
815 const uint8_t prefix_len) const {
817 .arg(prefix.toText()).arg(static_cast<int>(prefix_len));
818
819 // Let's get all reservations that match subnet_id, address.
820 const HostContainer6Index0& idx = hosts6_.get<0>();
821 HostContainer6Index0Range r = make_pair(idx.lower_bound(prefix),
822 idx.upper_bound(prefix));
823 BOOST_FOREACH(auto const& resrv, r) {
824 if (resrv.resrv_.getPrefixLen() == prefix_len) {
827 .arg(prefix.toText())
828 .arg(static_cast<int>(prefix_len))
829 .arg(resrv.host_->toText());
830 return (resrv.host_);
831 }
832 }
833
836 .arg(prefix.toText())
837 .arg(static_cast<int>(prefix_len));
838 return (ReturnType());
839}
840
841template<typename Storage>
842void
843CfgHosts::getAllInternal6(const SubnetID& subnet_id,
844 const asiolink::IOAddress& address,
845 Storage& storage) const {
847 .arg(subnet_id).arg(address.toText());
848
849 // Must not specify address other than IPv6.
850 if (!address.isV6()) {
851 isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
852 " for a host, specified address was " << address);
853 }
854
855 // Let's get all reservations that match subnet_id, address.
856 const HostContainer6Index1& idx = hosts6_.get<1>();
857 HostContainer6Index1Range r = make_pair(idx.lower_bound(boost::make_tuple(subnet_id, address)),
858 idx.upper_bound(boost::make_tuple(subnet_id, address)));
859
860 // For each IPv6 reservation, add the host to the results list. Fortunately,
861 // in all sane cases, there will be only one such host. (Each host can have
862 // multiple addresses reserved, but for each (address, subnet_id) there should
863 // be at most one host reserving it).
864 BOOST_FOREACH(auto const& resrv, r) {
867 .arg(subnet_id)
868 .arg(address.toText())
869 .arg(resrv.host_->toText());
870 storage.push_back(resrv.host_);
871 }
872
875 .arg(subnet_id)
876 .arg(address.toText())
877 .arg(storage.size());
878}
879
881CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
882 const Host::IdentifierType& identifier_type,
883 const uint8_t* identifier,
884 const size_t identifier_len) const {
885
887 .arg(subnet6 ? "IPv6" : "IPv4")
888 .arg(subnet_id)
889 .arg(Host::getIdentifierAsText(identifier_type, identifier, identifier_len));
890
891 // Get all hosts for a specified identifier. This may return multiple hosts
892 // for different subnets, but the number of hosts returned should be low
893 // because one host presumably doesn't show up in many subnets.
894 HostCollection hosts;
895 getAllInternal<HostCollection>(identifier_type, identifier, identifier_len,
896 hosts);
897
898 HostPtr host;
899 // Iterate over the returned hosts and select those for which the
900 // subnet id matches.
901 for (auto const& host_it : hosts) {
902 // Check if this is IPv4 subnet or IPv6 subnet.
903 SubnetID host_subnet_id = subnet6 ? host_it->getIPv6SubnetID() :
904 host_it->getIPv4SubnetID();
905
906 if (subnet_id == host_subnet_id) {
907 // If this is the first occurrence of the host for this subnet,
908 // remember it. But, if we find that this is second @c Host object
909 // for the same client, it is a misconfiguration. Most likely,
910 // the administrator has specified one reservation for a HW
911 // address and another one for the DUID, which gives an ambiguous
912 // result, and we don't know which reservation we should choose.
913 // Therefore, throw an exception.
914 if (!host) {
915 host = host_it;
916
917 } else {
918 isc_throw(DuplicateHost, "more than one reservation found"
919 " for the host belonging to the subnet with id '"
920 << subnet_id << "' and using the identifier '"
921 << Host::getIdentifierAsText(identifier_type,
922 identifier,
923 identifier_len)
924 << "'");
925 }
926 }
927 }
928
929 if (host) {
932 .arg(subnet_id)
933 .arg(Host::getIdentifierAsText(identifier_type, identifier,
934 identifier_len))
935 .arg(host->toText());
936
937 } else {
940 .arg(subnet_id)
941 .arg(Host::getIdentifierAsText(identifier_type, identifier,
942 identifier_len));
943 }
944
945 return (host);
946}
947
948void
949CfgHosts::add(const HostPtr& host) {
951 .arg(host ? host->toText() : "(no-host)");
952
953 // Sanity check that the host is non-null.
954 if (!host) {
955 isc_throw(BadValue, "specified host object must not be NULL when it"
956 " is added to the configuration");
957 }
958
959 // At least one subnet ID must be used.
960 if (host->getIPv4SubnetID() == SUBNET_ID_UNUSED &&
961 host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
962 isc_throw(BadValue, "must not use both IPv4 and IPv6 subnet ids of"
963 " 0 when adding new host reservation");
964 }
965
966 add4(host);
967
968 add6(host);
969}
970
971void
972CfgHosts::add4(const HostPtr& host) {
973
974 HWAddrPtr hwaddr = host->getHWAddress();
975 DuidPtr duid = host->getDuid();
976
977 // Check for duplicates for the specified IPv4 subnet.
978 if (host->getIPv4SubnetID() != SUBNET_ID_UNUSED) {
979 if (hwaddr && !hwaddr->hwaddr_.empty() &&
980 get4(host->getIPv4SubnetID(), Host::IDENT_HWADDR,
981 &hwaddr->hwaddr_[0], hwaddr->hwaddr_.size())) {
982 isc_throw(DuplicateHost, "failed to add new host using the HW"
983 << " address '" << hwaddr->toText(false)
984 << "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
985 << "' as this host has already been added");
986 }
987 if (duid && !duid->getDuid().empty() &&
988 get4(host->getIPv4SubnetID(), Host::IDENT_DUID,
989 &duid->getDuid()[0], duid->getDuid().size())) {
990 isc_throw(DuplicateHost, "failed to add new host using the "
991 << "DUID '" << duid->toText()
992 << "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
993 << "' as this host has already been added");
994 }
995 // Check for duplicates for the specified IPv6 subnet.
996 } else if (host->getIPv6SubnetID() != SUBNET_ID_UNUSED) {
997 if (duid && !duid->getDuid().empty() &&
998 get6(host->getIPv6SubnetID(), Host::IDENT_DUID,
999 &duid->getDuid()[0], duid->getDuid().size())) {
1000 isc_throw(DuplicateHost, "failed to add new host using the "
1001 << "DUID '" << duid->toText()
1002 << "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
1003 << "' as this host has already been added");
1004 }
1005 if (hwaddr && !hwaddr->hwaddr_.empty() &&
1006 get6(host->getIPv6SubnetID(), Host::IDENT_HWADDR,
1007 &hwaddr->hwaddr_[0], hwaddr->hwaddr_.size())) {
1008 isc_throw(DuplicateHost, "failed to add new host using the HW"
1009 << " address '" << hwaddr->toText(false)
1010 << "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
1011 << "' as this host has already been added");
1012 }
1013 }
1014
1015 // Check if the address is already reserved for the specified IPv4 subnet.
1016 if (ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero() &&
1017 (host->getIPv4SubnetID() != SUBNET_ID_UNUSED) &&
1018 get4(host->getIPv4SubnetID(), host->getIPv4Reservation())) {
1019 isc_throw(ReservedAddress, "failed to add new host using the HW"
1020 " address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
1021 << " and DUID '" << (duid ? duid->toText() : "(null)")
1022 << "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
1023 << "' for the address " << host->getIPv4Reservation()
1024 << ": There's already a reservation for this address");
1025 }
1026
1027 // Check if the (identifier type, identifier) tuple is already used.
1028 const std::vector<uint8_t>& id = host->getIdentifier();
1029 if ((host->getIPv4SubnetID() != SUBNET_ID_UNUSED) && !id.empty()) {
1030 if (get4(host->getIPv4SubnetID(), host->getIdentifierType(), &id[0],
1031 id.size())) {
1032 isc_throw(DuplicateHost, "failed to add duplicate IPv4 host using identifier: "
1033 << Host::getIdentifierAsText(host->getIdentifierType(),
1034 &id[0], id.size()));
1035 }
1036 }
1037
1038 // This is a new instance - add it.
1039 host->setHostId(++next_host_id_);
1040 hosts_.insert(host);
1041}
1042
1043void
1044CfgHosts::add6(const HostPtr& host) {
1045
1046 if (host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
1047 // This is IPv4-only host. No need to add it to v6 tables.
1048 return;
1049 }
1050
1051 HWAddrPtr hwaddr = host->getHWAddress();
1052 DuidPtr duid = host->getDuid();
1053
1054 // Get all reservations for this host.
1055 IPv6ResrvRange reservations = host->getIPv6Reservations();
1056
1057 // Check if there are any IPv6 reservations.
1058 if (std::distance(reservations.first, reservations.second) == 0) {
1059 // If there aren't, we don't need to add this to hosts6_, which is used
1060 // for getting hosts by their IPv6 address reservations.
1061 return;
1062 }
1063
1064 // Now for each reservation, insert corresponding (address, host) tuple.
1065 BOOST_FOREACH(auto const& it, reservations) {
1066
1067 if (ip_reservations_unique_) {
1068 // If there's an entry for this (subnet-id, address), reject it.
1069 if (get6(host->getIPv6SubnetID(), it.second.getPrefix())) {
1070 isc_throw(DuplicateHost, "failed to add address reservation for "
1071 << "host using the HW address '"
1072 << (hwaddr ? hwaddr->toText(false) : "(null)")
1073 << " and DUID '" << (duid ? duid->toText() : "(null)")
1074 << "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
1075 << "' for address/prefix " << it.second.getPrefix()
1076 << ": There's already reservation for this address/prefix");
1077 }
1078 }
1079 hosts6_.insert(HostResrv6Tuple(it.second, host));
1080 }
1081}
1082
1083bool
1084CfgHosts::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) {
1085 size_t erased_hosts = 0;
1086 size_t erased_addresses = 0;
1087 if (addr.isV4()) {
1088 HostContainerIndex4& idx = hosts_.get<4>();
1089 // Delete IPv4 reservation and host.
1090 for (auto const& host : getAll4(subnet_id, addr)) {
1091 erased_hosts += idx.erase(host->getHostId());
1092 }
1093 erased_addresses = erased_hosts;
1094 } else {
1095 HostContainer6Index1& idx6 = hosts6_.get<1>();
1096 HostContainerIndex4& idx = hosts_.get<4>();
1097 // Delete IPv6 reservations.
1098 auto const& range = idx6.equal_range(boost::make_tuple(subnet_id, addr));
1099 erased_addresses = boost::distance(range);
1100 // Delete hosts.
1101 BOOST_FOREACH(auto const& key, range) {
1102 erased_hosts += idx.erase(key.host_->getHostId());
1103 }
1104 idx6.erase(range.first, range.second);
1105 }
1106
1108 .arg(erased_hosts)
1109 .arg(erased_addresses)
1110 .arg(subnet_id)
1111 .arg(addr.toText());
1112
1113 return (erased_hosts != 0);
1114}
1115
1116size_t
1117CfgHosts::delAll4(const SubnetID& subnet_id) {
1118 HostContainerIndex2& idx = hosts_.get<2>();
1119 size_t erased = idx.erase(subnet_id);
1120
1122 .arg(erased)
1123 .arg(subnet_id);
1124
1125 return (erased);
1126}
1127
1128bool
1129CfgHosts::del4(const SubnetID& subnet_id,
1130 const Host::IdentifierType& identifier_type,
1131 const uint8_t* identifier_begin,
1132 const size_t identifier_len) {
1133 HostContainerIndex0& idx = hosts_.get<0>();
1134 auto const t = boost::make_tuple(std::vector<uint8_t>(identifier_begin,
1135 identifier_begin + identifier_len),
1136 identifier_type);
1137 auto const& range = idx.equal_range(t);
1138 size_t erased = 0;
1139 for (auto key = range.first; key != range.second;) {
1140 if ((*key)->getIPv4SubnetID() != subnet_id) {
1141 ++key;
1142 // Skip hosts from other subnets.
1143 continue;
1144 }
1145
1146 key = idx.erase(key);
1147 erased++;
1148 }
1149
1151 .arg(erased)
1152 .arg(subnet_id)
1153 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin, identifier_len));
1154
1155 return (erased != 0);
1156}
1157
1158size_t
1159CfgHosts::delAll6(const SubnetID& subnet_id) {
1160 // Delete IPv6 reservations.
1161 HostContainer6Index2& idx6 = hosts6_.get<2>();
1162 size_t erased_addresses = idx6.erase(subnet_id);
1163
1164 // Delete hosts.
1165 HostContainerIndex3& idx = hosts_.get<3>();
1166 size_t erased_hosts = idx.erase(subnet_id);
1167
1169 .arg(erased_hosts)
1170 .arg(erased_addresses)
1171 .arg(subnet_id);
1172
1173 return (erased_hosts);
1174}
1175
1176bool
1177CfgHosts::del6(const SubnetID& subnet_id,
1178 const Host::IdentifierType& identifier_type,
1179 const uint8_t* identifier_begin,
1180 const size_t identifier_len) {
1181 HostContainerIndex0& idx = hosts_.get<0>();
1182 HostContainer6Index3& idx6 = hosts6_.get<3>();
1183
1184 auto const t = boost::make_tuple(std::vector<uint8_t>(identifier_begin,
1185 identifier_begin + identifier_len),
1186 identifier_type);
1187 auto const& range = idx.equal_range(t);
1188 size_t erased_hosts = 0;
1189 size_t erased_reservations = 0;
1190 for (auto key = range.first; key != range.second;) {
1191 if ((*key)->getIPv6SubnetID() != subnet_id) {
1192 ++key;
1193 // Skip hosts from other subnets.
1194 continue;
1195 }
1196
1197 // Delete host.
1198 auto host_id = (*key)->getHostId();
1199 key = idx.erase(key);
1200 erased_hosts++;
1201 // Delete reservations.
1202 erased_reservations += idx6.erase(host_id);
1203 }
1204
1206 .arg(erased_hosts)
1207 .arg(erased_reservations)
1208 .arg(subnet_id)
1209 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin, identifier_len));
1210
1211 return (erased_hosts != 0);
1212}
1213
1214bool
1216 ip_reservations_unique_ = unique;
1217 return (true);
1218}
1219
1220
1223 uint16_t family = CfgMgr::instance().getFamily();
1224 if (family == AF_INET) {
1225 return (toElement4());
1226 } else if (family == AF_INET6) {
1227 return (toElement6());
1228 } else {
1229 isc_throw(ToElementError, "CfgHosts::toElement: unknown "
1230 "address family: " << family);
1231 }
1232}
1233
1235CfgHosts::toElement4() const {
1236 CfgHostsList result;
1237 // Iterate using arbitrary the index 0
1238 const HostContainerIndex0& idx = hosts_.get<0>();
1239 for (auto const& host : idx) {
1240
1241 // Convert host to element representation
1242 ElementPtr map = host->toElement4();
1243
1244 // Push it on the list
1245 SubnetID subnet_id = host->getIPv4SubnetID();
1246 result.add(subnet_id, map);
1247 }
1248 return (result.externalize());
1249}
1250
1252CfgHosts::toElement6() const {
1253 CfgHostsList result;
1254 // Iterate using arbitrary the index 0
1255 const HostContainerIndex0& idx = hosts_.get<0>();
1256 for (auto const& host : idx) {
1257
1258 // Convert host to Element representation
1259 ElementPtr map = host->toElement6();
1260
1261 // Push it on the list
1262 SubnetID subnet_id = host->getIPv6SubnetID();
1263 result.add(subnet_id, map);
1264 }
1265 return (result.externalize());
1266}
1267
1268} // end of namespace isc::dhcp
1269} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Cannot unparse error.
Utility class to represent host reservation configurations internally as a map keyed by subnet IDs,...
void add(SubnetID id, isc::data::ElementPtr resv)
Add a host reservation to the map.
isc::data::ElementPtr externalize() const
Externalize the map to a list Element.
virtual size_t delAll4(const SubnetID &subnet_id)
Attempts to delete all hosts for a given IPv4 subnet.
Definition: cfg_hosts.cc:1117
virtual void add(const HostPtr &host)
Adds a new host to the collection.
Definition: cfg_hosts.cc:949
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: cfg_hosts.cc:176
virtual bool del4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet4-id, identifier, identifier-type)
Definition: cfg_hosts.cc:1129
virtual bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr)
Attempts to delete a hosts by address.
Definition: cfg_hosts.cc:1084
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
Definition: cfg_hosts.cc:1215
virtual size_t delAll6(const SubnetID &subnet_id)
Attempts to delete all hosts for a given IPv6 subnet.
Definition: cfg_hosts.cc:1159
virtual ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv6 subnet.
Definition: cfg_hosts.cc:729
virtual ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
Definition: cfg_hosts.cc:88
virtual bool del6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len)
Attempts to delete a host by (subnet6-id, identifier, identifier-type)
Definition: cfg_hosts.cc:1177
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: cfg_hosts.cc:146
virtual ConstHostCollection getAll4(const SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
Definition: cfg_hosts.cc:52
virtual ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv4 subnet.
Definition: cfg_hosts.cc:664
virtual ConstHostCollection getAll6(const SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
Definition: cfg_hosts.cc:70
virtual ConstHostCollection getAllbyHostname6(const std::string &hostname, const SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv6 subnet.
Definition: cfg_hosts.cc:126
isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition: cfg_hosts.cc:1222
virtual ConstHostCollection getAllbyHostname4(const std::string &hostname, const SubnetID &subnet_id) const
Return all hosts with a hostname in a DHCPv4 subnet.
Definition: cfg_hosts.cc:106
virtual ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
Definition: cfg_hosts.cc:29
uint16_t getFamily() const
Returns address family.
Definition: cfgmgr.h:280
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
Exception thrown when the duplicate Host object is detected.
Wraps value holding size of the page with host reservations.
IdentifierType
Type of the host identifier.
Definition: host.h:307
@ IDENT_HWADDR
Definition: host.h:308
std::string getIdentifierAsText() const
Returns host identifier in a textual form.
Definition: host.cc:275
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6_COUNT
const isc::log::MessageID HOSTS_CFG_DEL4
HostContainer6::nth_index< 4 >::type HostContainer6Index4
Fifth index type in the HostContainer6.
HostContainer::nth_index< 4 >::type HostContainerIndex4
Fifth index type in the HostContainer.
const isc::log::MessageID HOSTS_CFG_GET_ALL_ADDRESS4_HOST
const isc::log::MessageID HOSTS_CFG_GET_ALL_ADDRESS6_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ALL
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID6
std::pair< HostContainerIndex1::iterator, HostContainerIndex1::iterator > HostContainerIndex1Range
Results range returned using the HostContainerIndex1.
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID4_HOST
isc::log::Logger hosts_logger("hosts")
Logger for the HostMgr and the code it calls.
Definition: hosts_log.h:51
const isc::log::MessageID HOSTS_CFG_GET_ALL_IDENTIFIER_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOST
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4
const isc::log::MessageID HOSTS_CFG_GET_ALL_IDENTIFIER
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS4_HOST
const isc::log::MessageID HOSTS_CFG_ADD_HOST
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS4
std::pair< HostContainer6Index1::iterator, HostContainer6Index1::iterator > HostContainer6Index1Range
Results range returned using the HostContainer6Index1.
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
Definition: host.h:807
HostContainer6::nth_index< 3 >::type HostContainer6Index3
Fourth index type in the HostContainer6.
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4_NULL
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Definition: host.h:813
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID6_HOST
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:136
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID6_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID6
HostContainer6::nth_index< 0 >::type HostContainer6Index0
First index type in the HostContainer6.
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID4
std::pair< HostContainer6Index4::iterator, HostContainer6Index4::iterator > HostContainer6Index4Range
Results range returned using the HostContainer6Index4.
const isc::log::MessageID HOSTS_CFG_GET_ONE_PREFIX_NULL
const isc::log::MessageID HOSTS_CFG_GET_ALL_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID4_HOST
const isc::log::MessageID HOSTS_CFG_GET_ALL_ADDRESS6
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
Definition: host.h:243
const isc::log::MessageID HOSTS_CFG_GET_ALL_IDENTIFIER_HOST
HostContainer6::nth_index< 1 >::type HostContainer6Index1
Second index type in the HostContainer6.
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Definition: host.h:816
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
const isc::log::MessageID HOSTS_CFG_GET_ONE_PREFIX_HOST
const isc::log::MessageID HOSTS_CFG_DEL6
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_HOST
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID6_HOST
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER_HOST
HostContainer::nth_index< 1 >::type HostContainerIndex1
Second index type in the HostContainer.
HostContainer6::nth_index< 2 >::type HostContainer6Index2
Third index type in the HostContainer6.
HostContainer::nth_index< 3 >::type HostContainerIndex3
Forth index type in the HostContainer.
const int HOSTS_DBG_TRACE
Logging levels for the host reservations management.
Definition: hosts_log.h:27
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6
const isc::log::MessageID HOSTS_CFG_GET_ALL_ADDRESS4
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER_NULL
std::pair< HostContainer6Index0::iterator, HostContainer6Index0::iterator > HostContainer6Index0Range
Results range returned using the HostContainer6Index0.
const isc::log::MessageID HOSTS_CFG_GET_ONE_PREFIX
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition: host.h:810
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4_HOST
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6_HOST
HostContainer::nth_index< 0 >::type HostContainerIndex0
First index type in the HostContainer.
const isc::log::MessageID HOSTS_CFG_GET_ALL_ADDRESS4_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6_HOST
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID4_COUNT
const int HOSTS_DBG_TRACE_DETAIL_DATA
Records detailed results of lookups.
Definition: hosts_log.h:43
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID4
const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET6
const int HOSTS_DBG_RESULTS
Records the results of the lookups.
Definition: hosts_log.h:33
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID6_COUNT
const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET4
HostContainer::nth_index< 5 >::type HostContainerIndex5
Sixth index type in the HostContainer.
const isc::log::MessageID HOSTS_CFG_GET_ALL_ADDRESS6_HOST
HostContainer::nth_index< 2 >::type HostContainerIndex2
Third index type in the HostContainer.
const isc::log::MessageID HOSTS_CFG_DEL
const isc::log::MessageID HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6_NULL
const isc::log::MessageID HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID4_COUNT
const isc::log::MessageID HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS4_COUNT
Defines the logger used by the top-level component of kea-lfc.