Kea 2.5.5
cfg_hosts.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 <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/hex.h>
16#include <ostream>
17#include <string>
18#include <vector>
19
20using namespace isc::asiolink;
21using namespace isc::data;
22using namespace std;
23
24namespace isc {
25namespace dhcp {
26
29 const uint8_t* identifier_begin,
30 const size_t identifier_len) const {
31 // Do not issue logging message here because it will be logged by
32 // the getAllInternal method.
33 ConstHostCollection collection;
34 getAllInternal<ConstHostCollection>(identifier_type, identifier_begin,
35 identifier_len, collection);
36 return (collection);
37}
38
41 const uint8_t* identifier_begin, const size_t identifier_len) {
42 // Do not issue logging message here because it will be logged by
43 // the getAllInternal method.
44 HostCollection collection;
45 getAllInternal<HostCollection>(identifier_type, identifier_begin,
46 identifier_len, collection);
47 return (collection);
48}
49
51CfgHosts::getAll4(const SubnetID& subnet_id) const {
52 // Do not issue logging message here because it will be logged by
53 // the getAllInternal4 method.
54 ConstHostCollection collection;
55 getAllInternal4<ConstHostCollection>(subnet_id, collection);
56 return (collection);
57}
58
60CfgHosts::getAll4(const SubnetID& subnet_id) {
61 // Do not issue logging message here because it will be logged by
62 // the getAllInternal4 method.
63 HostCollection collection;
64 getAllInternal4<HostCollection>(subnet_id, collection);
65 return (collection);
66}
67
69CfgHosts::getAll6(const SubnetID& subnet_id) const {
70 // Do not issue logging message here because it will be logged by
71 // the getAllInternal6 method.
72 ConstHostCollection collection;
73 getAllInternal6<ConstHostCollection>(subnet_id, collection);
74 return (collection);
75}
76
78CfgHosts::getAll6(const SubnetID& subnet_id) {
79 // Do not issue logging message here because it will be logged by
80 // the getAllInternal6 method.
81 HostCollection collection;
82 getAllInternal6<HostCollection>(subnet_id, collection);
83 return (collection);
84}
85
87CfgHosts::getAllbyHostname(const std::string& hostname) const {
88 // Do not issue logging message here because it will be logged by
89 // the getAllbyHostnameInternal method.
90 ConstHostCollection collection;
91 getAllbyHostnameInternal<ConstHostCollection>(hostname, collection);
92 return (collection);
93}
94
96CfgHosts::getAllbyHostname(const std::string& hostname) {
97 // Do not issue logging message here because it will be logged by
98 // the getAllbyHostnameInternal method.
99 HostCollection collection;
100 getAllbyHostnameInternal<HostCollection>(hostname, collection);
101 return (collection);
102}
103
105CfgHosts::getAllbyHostname4(const std::string& hostname,
106 const SubnetID& subnet_id) const {
107 // Do not issue logging message here because it will be logged by
108 // the getAllbyHostnameInternal4 method.
109 ConstHostCollection collection;
110 getAllbyHostnameInternal4<ConstHostCollection>(hostname, subnet_id, collection);
111 return (collection);
112}
113
115CfgHosts::getAllbyHostname4(const std::string& hostname,
116 const SubnetID& subnet_id) {
117 // Do not issue logging message here because it will be logged by
118 // the getAllbyHostnameInternal4 method.
119 HostCollection collection;
120 getAllbyHostnameInternal4<HostCollection>(hostname, subnet_id, collection);
121 return (collection);
122}
123
125CfgHosts::getAllbyHostname6(const std::string& hostname,
126 const SubnetID& subnet_id) const {
127 // Do not issue logging message here because it will be logged by
128 // the getAllbyHostnameInternal6 method.
129 ConstHostCollection collection;
130 getAllbyHostnameInternal6<ConstHostCollection>(hostname, subnet_id, collection);
131 return (collection);
132}
133
135CfgHosts::getAllbyHostname6(const std::string& hostname,
136 const SubnetID& subnet_id) {
137 // Do not issue logging message here because it will be logged by
138 // the getAllbyHostnameInternal6 method.
139 HostCollection collection;
140 getAllbyHostnameInternal6<HostCollection>(hostname, subnet_id, collection);
141 return (collection);
142}
143
146 size_t& /*source_index*/,
147 uint64_t lower_host_id,
148 const HostPageSize& page_size) const {
149 // Do not issue logging message here because it will be logged by
150 // the getPageInternal4 method.
151 ConstHostCollection collection;
152 getPageInternal4<ConstHostCollection>(subnet_id,
153 lower_host_id,
154 page_size,
155 collection);
156 return (collection);
157}
158
161 size_t& /*source_index*/,
162 uint64_t lower_host_id,
163 const HostPageSize& page_size) {
164 // Do not issue logging message here because it will be logged by
165 // the getPageInternal4 method.
166 HostCollection collection;
167 getPageInternal4<HostCollection>(subnet_id,
168 lower_host_id,
169 page_size,
170 collection);
171 return (collection);
172}
173
176 size_t& /*source_index*/,
177 uint64_t lower_host_id,
178 const HostPageSize& page_size) const {
179 // Do not issue logging message here because it will be logged by
180 // the getPageInternal6 method.
181 ConstHostCollection collection;
182 getPageInternal6<ConstHostCollection>(subnet_id,
183 lower_host_id,
184 page_size,
185 collection);
186 return (collection);
187}
188
191 size_t& /*source_index*/,
192 uint64_t lower_host_id,
193 const HostPageSize& page_size) {
194 // Do not issue logging message here because it will be logged by
195 // the getPageInternal6 method.
196 HostCollection collection;
197 getPageInternal6<HostCollection>(subnet_id,
198 lower_host_id,
199 page_size,
200 collection);
201 return (collection);
202}
203
205CfgHosts::getPage4(size_t& /*source_index*/,
206 uint64_t lower_host_id,
207 const HostPageSize& page_size) const {
208 // Do not issue logging message here because it will be logged by
209 // the getPageInternal method.
210 ConstHostCollection collection;
211 getPageInternal<ConstHostCollection>(lower_host_id,
212 page_size,
213 collection);
214 return (collection);
215}
216
218CfgHosts::getPage4(size_t& /*source_index*/,
219 uint64_t lower_host_id,
220 const HostPageSize& page_size) {
221 // Do not issue logging message here because it will be logged by
222 // the getPageInternal method.
223 HostCollection collection;
224 getPageInternal<HostCollection>(lower_host_id,
225 page_size,
226 collection);
227 return (collection);
228}
229
231CfgHosts::getPage6(size_t& /*source_index*/,
232 uint64_t lower_host_id,
233 const HostPageSize& page_size) const {
234 // Do not issue logging message here because it will be logged by
235 // the getPageInternal method.
236 ConstHostCollection collection;
237 getPageInternal<ConstHostCollection>(lower_host_id,
238 page_size,
239 collection);
240 return (collection);
241}
242
244CfgHosts::getPage6(size_t& /*source_index*/,
245 uint64_t lower_host_id,
246 const HostPageSize& page_size) {
247 // Do not issue logging message here because it will be logged by
248 // the getPageInternal method.
249 HostCollection collection;
250 getPageInternal<HostCollection>(lower_host_id,
251 page_size,
252 collection);
253 return (collection);
254}
255
257CfgHosts::getAll4(const IOAddress& address) const {
258 // Do not issue logging message here because it will be logged by
259 // the getAllInternal4 method.
260 ConstHostCollection collection;
261 getAllInternal4<ConstHostCollection>(address, collection);
262 return (collection);
263}
264
267 // Do not issue logging message here because it will be logged by
268 // the getAllInternal4 method.
269 HostCollection collection;
270 getAllInternal4<HostCollection>(address, collection);
271 return (collection);
272}
273
275CfgHosts::getAll6(const IOAddress& address) const {
276 // Do not issue logging message here because it will be logged by
277 // the getAllInternal6 method.
278 ConstHostCollection collection;
279 getAllInternal6<ConstHostCollection>(address, collection);
280 return (collection);
281}
282
285 // Do not issue logging message here because it will be logged by
286 // the getAllInternal6 method.
287 HostCollection collection;
288 getAllInternal6<HostCollection>(address, collection);
289 return (collection);
290}
291
292template<typename Storage>
293void
294CfgHosts::getAllInternal(const Host::IdentifierType& identifier_type,
295 const uint8_t* identifier,
296 const size_t identifier_len,
297 Storage& storage) const {
298
299 // Convert host identifier into textual format for logging purposes.
300 // This conversion is exception free.
301 std::string identifier_text = Host::getIdentifierAsText(identifier_type,
302 identifier,
303 identifier_len);
305 .arg(identifier_text);
306
307 // Use the identifier and identifier type as a composite key.
308 const HostContainerIndex0& idx = hosts_.get<0>();
309 boost::tuple<const std::vector<uint8_t>, const Host::IdentifierType> t =
310 boost::make_tuple(std::vector<uint8_t>(identifier,
311 identifier + identifier_len),
312 identifier_type);
313
314 // Append each Host object to the storage.
315 for (HostContainerIndex0::iterator host = idx.lower_bound(t);
316 host != idx.upper_bound(t);
317 ++host) {
320 .arg(identifier_text)
321 .arg((*host)->toText());
322 storage.push_back(*host);
323 }
324
325 // Log how many hosts have been found.
327 .arg(identifier_text)
328 .arg(storage.size());
329}
330
331template<typename Storage>
332void
333CfgHosts::getAllInternal4(const SubnetID& subnet_id,
334 Storage& storage) const {
335
337 .arg(subnet_id);
338
339 // Use try DHCPv4 subnet id.
340 const HostContainerIndex2& idx = hosts_.get<2>();
341
342 // Append each Host object to the storage.
343 for (HostContainerIndex2::iterator host = idx.lower_bound(subnet_id);
344 host != idx.upper_bound(subnet_id);
345 ++host) {
348 .arg(subnet_id)
349 .arg((*host)->toText());
350 storage.push_back(*host);
351 }
352
353 // Log how many hosts have been found.
355 .arg(subnet_id)
356 .arg(storage.size());
357}
358
359template<typename Storage>
360void
361CfgHosts::getAllInternal6(const SubnetID& subnet_id,
362 Storage& storage) const {
363
365 .arg(subnet_id);
366
367 // Use try DHCPv6 subnet id.
368 const HostContainerIndex3& idx = hosts_.get<3>();
369
370 // Append each Host object to the storage.
371 for (HostContainerIndex3::iterator host = idx.lower_bound(subnet_id);
372 host != idx.upper_bound(subnet_id);
373 ++host) {
376 .arg(subnet_id)
377 .arg((*host)->toText());
378 storage.push_back(*host);
379 }
380
381 // Log how many hosts have been found.
383 .arg(subnet_id)
384 .arg(storage.size());
385}
386
387template<typename Storage>
388void
389CfgHosts::getAllbyHostnameInternal(const std::string& hostname,
390 Storage& storage) const {
391
393 .arg(hostname);
394
395 // Use try hostname.
396 const HostContainerIndex5& idx = hosts_.get<5>();
397
398 // Append each Host object to the storage.
399 for (HostContainerIndex5::iterator host = idx.lower_bound(hostname);
400 host != idx.upper_bound(hostname);
401 ++host) {
404 .arg(hostname)
405 .arg((*host)->toText());
406 storage.push_back(*host);
407 }
408
409 // Log how many hosts have been found.
411 .arg(hostname)
412 .arg(storage.size());
413}
414
415template<typename Storage>
416void
417CfgHosts::getAllbyHostnameInternal4(const std::string& hostname,
418 const SubnetID& subnet_id,
419 Storage& storage) const {
420
423 .arg(hostname)
424 .arg(subnet_id);
425
426 // Use try hostname.
427 const HostContainerIndex5& idx = hosts_.get<5>();
428
429 // Append each Host object to the storage.
430 for (HostContainerIndex5::iterator host = idx.lower_bound(hostname);
431 host != idx.upper_bound(hostname);
432 ++host) {
433 if ((*host)->getIPv4SubnetID() != subnet_id) {
434 continue;
435 }
438 .arg(hostname)
439 .arg(subnet_id)
440 .arg((*host)->toText());
441 storage.push_back(*host);
442 }
443
444 // Log how many hosts have been found.
447 .arg(hostname)
448 .arg(subnet_id)
449 .arg(storage.size());
450}
451
452template<typename Storage>
453void
454CfgHosts::getAllbyHostnameInternal6(const std::string& hostname,
455 const SubnetID& subnet_id,
456 Storage& storage) const {
457
460 .arg(hostname)
461 .arg(subnet_id);
462
463 // Use try hostname.
464 const HostContainerIndex5& idx = hosts_.get<5>();
465
466 // Append each Host object to the storage.
467 for (HostContainerIndex5::iterator host = idx.lower_bound(hostname);
468 host != idx.upper_bound(hostname);
469 ++host) {
470 if ((*host)->getIPv6SubnetID() != subnet_id) {
471 continue;
472 }
475 .arg(hostname)
476 .arg(subnet_id)
477 .arg((*host)->toText());
478 storage.push_back(*host);
479 }
480
481 // Log how many hosts have been found.
484 .arg(hostname)
485 .arg(subnet_id)
486 .arg(storage.size());
487}
488
489template<typename Storage>
490void
491CfgHosts::getPageInternal(uint64_t lower_host_id,
492 const HostPageSize& page_size,
493 Storage& storage) const {
494
496
497 // Use the host id last index.
498 const HostContainerIndex4& idx = hosts_.get<4>();
499 HostContainerIndex4::const_iterator host = idx.lower_bound(lower_host_id);
500
501 // Exclude the lower bound id when it is not zero.
502 if (lower_host_id &&
503 (host != idx.end()) && ((*host)->getHostId() == lower_host_id)) {
504 ++host;
505 }
506
507 // Return hosts within the page size.
508 for (; host != idx.end(); ++host) {
511 .arg((*host)->toText());
512 storage.push_back(*host);
513 if (storage.size() >= page_size.page_size_) {
514 break;
515 }
516 }
517
518 // Log how many hosts have been found.
520 .arg(storage.size());
521}
522
523template<typename Storage>
524void
525CfgHosts::getPageInternal4(const SubnetID& subnet_id,
526 uint64_t lower_host_id,
527 const HostPageSize& page_size,
528 Storage& storage) const {
529
531 .arg(subnet_id);
532
533 // Use the host id last index.
534 const HostContainerIndex4& idx = hosts_.get<4>();
535 HostContainerIndex4::const_iterator host = idx.lower_bound(lower_host_id);
536
537 // Exclude the lower bound id when it is not zero.
538 if (lower_host_id &&
539 (host != idx.end()) && ((*host)->getHostId() == lower_host_id)) {
540 ++host;
541 }
542
543 // Return hosts in the subnet within the page size.
544 for (; host != idx.end(); ++host) {
545 if ((*host)->getIPv4SubnetID() != subnet_id) {
546 continue;
547 }
550 .arg(subnet_id)
551 .arg((*host)->toText());
552 storage.push_back(*host);
553 if (storage.size() >= page_size.page_size_) {
554 break;
555 }
556 }
557
558 // Log how many hosts have been found.
560 .arg(subnet_id)
561 .arg(storage.size());
562}
563
564template<typename Storage>
565void
566CfgHosts::getPageInternal6(const SubnetID& subnet_id,
567 uint64_t lower_host_id,
568 const HostPageSize& page_size,
569 Storage& storage) const {
570
572 .arg(subnet_id);
573
574 // Use the host id last index.
575 const HostContainerIndex4& idx = hosts_.get<4>();
576 HostContainerIndex4::const_iterator host = idx.lower_bound(lower_host_id);
577
578 // Exclude the lower bound id when it is not zero.
579 if (lower_host_id &&
580 (host != idx.end()) && ((*host)->getHostId() == lower_host_id)) {
581 ++host;
582 }
583
584 // Return hosts in the subnet within the page size.
585 for (; host != idx.end(); ++host) {
586 if ((*host)->getIPv6SubnetID() != subnet_id) {
587 continue;
588 }
591 .arg(subnet_id)
592 .arg((*host)->toText());
593 storage.push_back(*host);
594 if (storage.size() >= page_size.page_size_) {
595 break;
596 }
597 }
598
599 // Log how many hosts have been found.
601 .arg(subnet_id)
602 .arg(storage.size());
603}
604
605
606template<typename Storage>
607void
608CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
610 .arg(address.toText());
611
612 // Must not specify address other than IPv4.
613 if (!address.isV4()) {
614 isc_throw(BadHostAddress, "must specify an IPv4 address when searching"
615 " for a host, specified address was " << address);
616 }
617 // Search for the Host using the reserved IPv4 address as a key.
618 const HostContainerIndex1& idx = hosts_.get<1>();
619 HostContainerIndex1Range r = idx.equal_range(address);
620 // Append each Host object to the storage.
621 for (HostContainerIndex1::iterator host = r.first; host != r.second;
622 ++host) {
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 for (HostContainer6Index4::iterator reservation = r.first; reservation != r.second;
651 ++reservation) {
654 .arg(address.toText())
655 .arg(reservation->host_->toText());
656 storage.push_back(reservation->host_);
657 }
658
660 .arg(address.toText())
661 .arg(storage.size());
662}
663
665CfgHosts::get4(const SubnetID& subnet_id,
666 const Host::IdentifierType& identifier_type,
667 const uint8_t* identifier_begin,
668 const size_t identifier_len) const {
669 return (getHostInternal(subnet_id, false, identifier_type, identifier_begin,
670 identifier_len));
671}
672
674CfgHosts::get4(const SubnetID& subnet_id,
675 const Host::IdentifierType& identifier_type,
676 const uint8_t* identifier_begin,
677 const size_t identifier_len) {
678 return (getHostInternal(subnet_id, false, identifier_type, identifier_begin,
679 identifier_len));
680}
681
683CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
685 .arg(subnet_id).arg(address.toText());
686
687 ConstHostCollection hosts = getAll4(address);
688 for (ConstHostCollection::const_iterator host = hosts.begin();
689 host != hosts.end(); ++host) {
690 if ((*host)->getIPv4SubnetID() == subnet_id) {
693 .arg(subnet_id)
694 .arg(address.toText())
695 .arg((*host)->toText());
696 return (*host);
697 }
698 }
699
701 .arg(subnet_id).arg(address.toText());
702 return (ConstHostPtr());
703}
704
707 const asiolink::IOAddress& address) const {
709 .arg(subnet_id).arg(address.toText());
710
712 for (auto host : getAll4(address)) {
713 if (host->getIPv4SubnetID() == subnet_id) {
716 .arg(subnet_id)
717 .arg(address.toText())
718 .arg(host->toText());
719 hosts.push_back(host);
720 }
721 }
723 .arg(subnet_id)
724 .arg(address.toText())
725 .arg(hosts.size());
726
727 return (hosts);
728}
729
731CfgHosts::get6(const SubnetID& subnet_id,
732 const Host::IdentifierType& identifier_type,
733 const uint8_t* identifier_begin,
734 const size_t identifier_len) const {
735 return (getHostInternal(subnet_id, true, identifier_type, identifier_begin,
736 identifier_len));
737}
738
740CfgHosts::get6(const SubnetID& subnet_id,
741 const Host::IdentifierType& identifier_type,
742 const uint8_t* identifier_begin,
743 const size_t identifier_len) {
744 return (getHostInternal(subnet_id, true, identifier_type, identifier_begin,
745 identifier_len));
746}
747
749CfgHosts::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
750 return (getHostInternal6<ConstHostPtr>(prefix, prefix_len));
751}
752
754CfgHosts::get6(const IOAddress& prefix, const uint8_t prefix_len) {
755 return (getHostInternal6<HostPtr>(prefix, prefix_len));
756}
757
759CfgHosts::get6(const SubnetID& subnet_id,
760 const asiolink::IOAddress& address) const {
761 // Do not log here because getHostInternal6 logs.
762 return (getHostInternal6<ConstHostPtr, ConstHostCollection>(subnet_id, address));
763}
764
766CfgHosts::get6(const SubnetID& subnet_id,
767 const asiolink::IOAddress& address) {
768 // Do not log here because getHostInternal6 logs.
769 return (getHostInternal6<HostPtr, HostCollection>(subnet_id, address));
770}
771
774 const asiolink::IOAddress& address) const {
776 getAllInternal6(subnet_id, address, hosts);
777 return (hosts);
778}
779
780template<typename ReturnType, typename Storage>
781ReturnType
782CfgHosts::getHostInternal6(const SubnetID& subnet_id,
783 const asiolink::IOAddress& address) const {
785 .arg(subnet_id).arg(address.toText());
786
787 Storage storage;
788 getAllInternal6<Storage>(subnet_id, address, storage);
789 switch (storage.size()) {
790 case 0:
793 .arg(subnet_id)
794 .arg(address.toText());
795 return (HostPtr());
796
797 case 1:
800 .arg(subnet_id)
801 .arg(address.toText())
802 .arg((*storage.begin())->toText());
803 return (*storage.begin());
804
805 default:
806 isc_throw(DuplicateHost, "more than one reservation found"
807 " for the host belonging to the subnet with id '"
808 << subnet_id << "' and using the address '"
809 << address.toText() << "'");
810 }
811
812}
813
814template<typename ReturnType>
815ReturnType
816CfgHosts::getHostInternal6(const asiolink::IOAddress& prefix,
817 const uint8_t prefix_len) const {
819 .arg(prefix.toText()).arg(static_cast<int>(prefix_len));
820
821 // Let's get all reservations that match subnet_id, address.
822 const HostContainer6Index0& idx = hosts6_.get<0>();
823 HostContainer6Index0Range r = make_pair(idx.lower_bound(prefix),
824 idx.upper_bound(prefix));
825 for (HostContainer6Index0::iterator resrv = r.first; resrv != r.second;
826 ++resrv) {
827 if (resrv->resrv_.getPrefixLen() == prefix_len) {
830 .arg(prefix.toText())
831 .arg(static_cast<int>(prefix_len))
832 .arg(resrv->host_->toText());
833 return (resrv->host_);
834 }
835 }
836
839 .arg(prefix.toText())
840 .arg(static_cast<int>(prefix_len));
841 return (ReturnType());
842}
843
844template<typename Storage>
845void
846CfgHosts::getAllInternal6(const SubnetID& subnet_id,
847 const asiolink::IOAddress& address,
848 Storage& storage) const {
850 .arg(subnet_id).arg(address.toText());
851
852 // Must not specify address other than IPv6.
853 if (!address.isV6()) {
854 isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
855 " for a host, specified address was " << address);
856 }
857
858 // Let's get all reservations that match subnet_id, address.
859 const HostContainer6Index1& idx = hosts6_.get<1>();
860 HostContainer6Index1Range r = make_pair(idx.lower_bound(boost::make_tuple(subnet_id, address)),
861 idx.upper_bound(boost::make_tuple(subnet_id, address)));
862
863 // For each IPv6 reservation, add the host to the results list. Fortunately,
864 // in all sane cases, there will be only one such host. (Each host can have
865 // multiple addresses reserved, but for each (address, subnet_id) there should
866 // be at most one host reserving it).
867 for(HostContainer6Index1::iterator resrv = r.first; resrv != r.second; ++resrv) {
870 .arg(subnet_id)
871 .arg(address.toText())
872 .arg(resrv->host_->toText());
873 storage.push_back(resrv->host_);
874 }
875
878 .arg(subnet_id)
879 .arg(address.toText())
880 .arg(storage.size());
881}
882
884CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
885 const Host::IdentifierType& identifier_type,
886 const uint8_t* identifier,
887 const size_t identifier_len) const {
888
890 .arg(subnet6 ? "IPv6" : "IPv4")
891 .arg(subnet_id)
892 .arg(Host::getIdentifierAsText(identifier_type, identifier, identifier_len));
893
894 // Get all hosts for a specified identifier. This may return multiple hosts
895 // for different subnets, but the number of hosts returned should be low
896 // because one host presumably doesn't show up in many subnets.
897 HostCollection hosts;
898 getAllInternal<HostCollection>(identifier_type, identifier, identifier_len,
899 hosts);
900
901 HostPtr host;
902 // Iterate over the returned hosts and select those for which the
903 // subnet id matches.
904 for (HostCollection::const_iterator host_it = hosts.begin();
905 host_it != hosts.end(); ++host_it) {
906 // Check if this is IPv4 subnet or IPv6 subnet.
907 SubnetID host_subnet_id = subnet6 ? (*host_it)->getIPv6SubnetID() :
908 (*host_it)->getIPv4SubnetID();
909
910 if (subnet_id == host_subnet_id) {
911 // If this is the first occurrence of the host for this subnet,
912 // remember it. But, if we find that this is second @c Host object
913 // for the same client, it is a misconfiguration. Most likely,
914 // the administrator has specified one reservation for a HW
915 // address and another one for the DUID, which gives an ambiguous
916 // result, and we don't know which reservation we should choose.
917 // Therefore, throw an exception.
918 if (!host) {
919 host = *host_it;
920
921 } else {
922 isc_throw(DuplicateHost, "more than one reservation found"
923 " for the host belonging to the subnet with id '"
924 << subnet_id << "' and using the identifier '"
925 << Host::getIdentifierAsText(identifier_type,
926 identifier,
927 identifier_len)
928 << "'");
929 }
930 }
931 }
932
933 if (host) {
936 .arg(subnet_id)
937 .arg(Host::getIdentifierAsText(identifier_type, identifier,
938 identifier_len))
939 .arg(host->toText());
940
941 } else {
944 .arg(subnet_id)
945 .arg(Host::getIdentifierAsText(identifier_type, identifier,
946 identifier_len));
947 }
948
949 return (host);
950}
951
952void
953CfgHosts::add(const HostPtr& host) {
955 .arg(host ? host->toText() : "(no-host)");
956
957 // Sanity check that the host is non-null.
958 if (!host) {
959 isc_throw(BadValue, "specified host object must not be NULL when it"
960 " is added to the configuration");
961 }
962
963 // At least one subnet ID must be used.
964 if (host->getIPv4SubnetID() == SUBNET_ID_UNUSED &&
965 host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
966 isc_throw(BadValue, "must not use both IPv4 and IPv6 subnet ids of"
967 " 0 when adding new host reservation");
968 }
969
970 add4(host);
971
972 add6(host);
973}
974
975void
976CfgHosts::add4(const HostPtr& host) {
977
978 HWAddrPtr hwaddr = host->getHWAddress();
979 DuidPtr duid = host->getDuid();
980
981 // Check for duplicates for the specified IPv4 subnet.
982 if (host->getIPv4SubnetID() != SUBNET_ID_UNUSED) {
983 if (hwaddr && !hwaddr->hwaddr_.empty() &&
984 get4(host->getIPv4SubnetID(), Host::IDENT_HWADDR,
985 &hwaddr->hwaddr_[0], hwaddr->hwaddr_.size())) {
986 isc_throw(DuplicateHost, "failed to add new host using the HW"
987 << " address '" << hwaddr->toText(false)
988 << "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
989 << "' as this host has already been added");
990 }
991 if (duid && !duid->getDuid().empty() &&
992 get4(host->getIPv4SubnetID(), Host::IDENT_DUID,
993 &duid->getDuid()[0], duid->getDuid().size())) {
994 isc_throw(DuplicateHost, "failed to add new host using the "
995 << "DUID '" << duid->toText()
996 << "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
997 << "' as this host has already been added");
998 }
999 // Check for duplicates for the specified IPv6 subnet.
1000 } else if (host->getIPv6SubnetID() != SUBNET_ID_UNUSED) {
1001 if (duid && !duid->getDuid().empty() &&
1002 get6(host->getIPv6SubnetID(), Host::IDENT_DUID,
1003 &duid->getDuid()[0], duid->getDuid().size())) {
1004 isc_throw(DuplicateHost, "failed to add new host using the "
1005 << "DUID '" << duid->toText()
1006 << "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
1007 << "' as this host has already been added");
1008 }
1009 if (hwaddr && !hwaddr->hwaddr_.empty() &&
1010 get6(host->getIPv6SubnetID(), Host::IDENT_HWADDR,
1011 &hwaddr->hwaddr_[0], hwaddr->hwaddr_.size())) {
1012 isc_throw(DuplicateHost, "failed to add new host using the HW"
1013 << " address '" << hwaddr->toText(false)
1014 << "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
1015 << "' as this host has already been added");
1016 }
1017 }
1018
1019 // Check if the address is already reserved for the specified IPv4 subnet.
1020 if (ip_reservations_unique_ && !host->getIPv4Reservation().isV4Zero() &&
1021 (host->getIPv4SubnetID() != SUBNET_ID_UNUSED) &&
1022 get4(host->getIPv4SubnetID(), host->getIPv4Reservation())) {
1023 isc_throw(ReservedAddress, "failed to add new host using the HW"
1024 " address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
1025 << " and DUID '" << (duid ? duid->toText() : "(null)")
1026 << "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
1027 << "' for the address " << host->getIPv4Reservation()
1028 << ": There's already a reservation for this address");
1029 }
1030
1031 // Check if the (identifier type, identifier) tuple is already used.
1032 const std::vector<uint8_t>& id = host->getIdentifier();
1033 if ((host->getIPv4SubnetID() != SUBNET_ID_UNUSED) && !id.empty()) {
1034 if (get4(host->getIPv4SubnetID(), host->getIdentifierType(), &id[0],
1035 id.size())) {
1036 isc_throw(DuplicateHost, "failed to add duplicate IPv4 host using identifier: "
1037 << Host::getIdentifierAsText(host->getIdentifierType(),
1038 &id[0], id.size()));
1039 }
1040 }
1041
1042 // This is a new instance - add it.
1043 host->setHostId(++next_host_id_);
1044 hosts_.insert(host);
1045}
1046
1047void
1048CfgHosts::add6(const HostPtr& host) {
1049
1050 if (host->getIPv6SubnetID() == SUBNET_ID_UNUSED) {
1051 // This is IPv4-only host. No need to add it to v6 tables.
1052 return;
1053 }
1054
1055 HWAddrPtr hwaddr = host->getHWAddress();
1056 DuidPtr duid = host->getDuid();
1057
1058 // Get all reservations for this host.
1059 IPv6ResrvRange reservations = host->getIPv6Reservations();
1060
1061 // Check if there are any IPv6 reservations.
1062 if (std::distance(reservations.first, reservations.second) == 0) {
1063 // If there aren't, we don't need to add this to hosts6_, which is used
1064 // for getting hosts by their IPv6 address reservations.
1065 return;
1066 }
1067
1068 // Now for each reservation, insert corresponding (address, host) tuple.
1069 for (IPv6ResrvIterator it = reservations.first; it != reservations.second;
1070 ++it) {
1071
1072 if (ip_reservations_unique_) {
1073 // If there's an entry for this (subnet-id, address), reject it.
1074 if (get6(host->getIPv6SubnetID(), it->second.getPrefix())) {
1075 isc_throw(DuplicateHost, "failed to add address reservation for "
1076 << "host using the HW address '"
1077 << (hwaddr ? hwaddr->toText(false) : "(null)")
1078 << " and DUID '" << (duid ? duid->toText() : "(null)")
1079 << "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
1080 << "' for address/prefix " << it->second.getPrefix()
1081 << ": There's already reservation for this address/prefix");
1082 }
1083 }
1084 hosts6_.insert(HostResrv6Tuple(it->second, host));
1085 }
1086}
1087
1088bool
1089CfgHosts::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) {
1090 size_t erased_hosts = 0;
1091 size_t erased_addresses = 0;
1092 if (addr.isV4()) {
1093 HostContainerIndex4& idx = hosts_.get<4>();
1094 // Delete IPv4 reservation and host.
1095 for (auto host : getAll4(subnet_id, addr)) {
1096 erased_hosts += idx.erase(host->getHostId());
1097 }
1098 erased_addresses = erased_hosts;
1099 } else {
1100 HostContainer6Index1& idx6 = hosts6_.get<1>();
1101 HostContainerIndex4& idx = hosts_.get<4>();
1102 // Delete IPv6 reservations.
1103 const auto& range = idx6.equal_range(boost::make_tuple(subnet_id, addr));
1104 erased_addresses = boost::distance(range);
1105 // Delete hosts.
1106 for (auto key = range.first; key != range.second; ++key) {
1107 erased_hosts += idx.erase(key->host_->getHostId());
1108 }
1109 idx6.erase(range.first, range.second);
1110 }
1111
1113 .arg(erased_hosts)
1114 .arg(erased_addresses)
1115 .arg(subnet_id)
1116 .arg(addr.toText());
1117
1118 return (erased_hosts != 0);
1119}
1120
1121size_t
1122CfgHosts::delAll4(const SubnetID& subnet_id) {
1123 HostContainerIndex2& idx = hosts_.get<2>();
1124 size_t erased = idx.erase(subnet_id);
1125
1127 .arg(erased)
1128 .arg(subnet_id);
1129
1130 return (erased);
1131}
1132
1133bool
1134CfgHosts::del4(const SubnetID& subnet_id,
1135 const Host::IdentifierType& identifier_type,
1136 const uint8_t* identifier_begin,
1137 const size_t identifier_len) {
1138 HostContainerIndex0& idx = hosts_.get<0>();
1139 const auto t = boost::make_tuple(std::vector<uint8_t>(identifier_begin,
1140 identifier_begin + identifier_len),
1141 identifier_type);
1142 const auto& range = idx.equal_range(t);
1143 size_t erased = 0;
1144 for (auto key = range.first; key != range.second;) {
1145 if ((*key)->getIPv4SubnetID() != subnet_id) {
1146 ++key;
1147 // Skip hosts from other subnets.
1148 continue;
1149 }
1150
1151 key = idx.erase(key);
1152 erased++;
1153 }
1154
1156 .arg(erased)
1157 .arg(subnet_id)
1158 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin, identifier_len));
1159
1160 return (erased != 0);
1161}
1162
1163size_t
1164CfgHosts::delAll6(const SubnetID& subnet_id) {
1165 // Delete IPv6 reservations.
1166 HostContainer6Index2& idx6 = hosts6_.get<2>();
1167 size_t erased_addresses = idx6.erase(subnet_id);
1168
1169 // Delete hosts.
1170 HostContainerIndex3& idx = hosts_.get<3>();
1171 size_t erased_hosts = idx.erase(subnet_id);
1172
1174 .arg(erased_hosts)
1175 .arg(erased_addresses)
1176 .arg(subnet_id);
1177
1178 return (erased_hosts);
1179}
1180
1181bool
1182CfgHosts::del6(const SubnetID& subnet_id,
1183 const Host::IdentifierType& identifier_type,
1184 const uint8_t* identifier_begin,
1185 const size_t identifier_len) {
1186 HostContainerIndex0& idx = hosts_.get<0>();
1187 HostContainer6Index3& idx6 = hosts6_.get<3>();
1188
1189 const auto t = boost::make_tuple(std::vector<uint8_t>(identifier_begin,
1190 identifier_begin + identifier_len),
1191 identifier_type);
1192 const auto& range = idx.equal_range(t);
1193 size_t erased_hosts = 0;
1194 size_t erased_reservations = 0;
1195 for (auto key = range.first; key != range.second;) {
1196 if ((*key)->getIPv6SubnetID() != subnet_id) {
1197 ++key;
1198 // Skip hosts from other subnets.
1199 continue;
1200 }
1201
1202 // Delete host.
1203 auto host_id = (*key)->getHostId();
1204 key = idx.erase(key);
1205 erased_hosts++;
1206 // Delete reservations.
1207 erased_reservations += idx6.erase(host_id);
1208 }
1209
1211 .arg(erased_hosts)
1212 .arg(erased_reservations)
1213 .arg(subnet_id)
1214 .arg(Host::getIdentifierAsText(identifier_type, identifier_begin, identifier_len));
1215
1216 return (erased_hosts != 0);
1217}
1218
1219bool
1221 ip_reservations_unique_ = unique;
1222 return (true);
1223}
1224
1225
1228 uint16_t family = CfgMgr::instance().getFamily();
1229 if (family == AF_INET) {
1230 return (toElement4());
1231 } else if (family == AF_INET6) {
1232 return (toElement6());
1233 } else {
1234 isc_throw(ToElementError, "CfgHosts::toElement: unknown "
1235 "address family: " << family);
1236 }
1237}
1238
1240CfgHosts::toElement4() const {
1241 CfgHostsList result;
1242 // Iterate using arbitrary the index 0
1243 const HostContainerIndex0& idx = hosts_.get<0>();
1244 for (HostContainerIndex0::const_iterator host = idx.begin();
1245 host != idx.end(); ++host) {
1246
1247 // Convert host to element representation
1248 ElementPtr map = (*host)->toElement4();
1249
1250 // Push it on the list
1251 SubnetID subnet_id = (*host)->getIPv4SubnetID();
1252 result.add(subnet_id, map);
1253 }
1254 return (result.externalize());
1255}
1256
1258CfgHosts::toElement6() const {
1259 CfgHostsList result;
1260 // Iterate using arbitrary the index 0
1261 const HostContainerIndex0& idx = hosts_.get<0>();
1262 for (HostContainerIndex0::const_iterator host = idx.begin();
1263 host != idx.end(); ++host) {
1264
1265 // Convert host to Element representation
1266 ElementPtr map = (*host)->toElement6();
1267
1268 // Push it on the list
1269 SubnetID subnet_id = (*host)->getIPv6SubnetID();
1270 result.add(subnet_id, map);
1271 }
1272 return (result.externalize());
1273}
1274
1275} // end of namespace isc::dhcp
1276} // 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:1122
virtual void add(const HostPtr &host)
Adds a new host to the collection.
Definition: cfg_hosts.cc:953
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:175
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:1134
virtual bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr)
Attempts to delete a hosts by address.
Definition: cfg_hosts.cc:1089
virtual bool setIPReservationsUnique(const bool unique)
Controls whether IP reservations are unique or non-unique.
Definition: cfg_hosts.cc:1220
virtual size_t delAll6(const SubnetID &subnet_id)
Attempts to delete all hosts for a given IPv6 subnet.
Definition: cfg_hosts.cc:1164
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:731
virtual ConstHostCollection getAllbyHostname(const std::string &hostname) const
Return all hosts with a hostname.
Definition: cfg_hosts.cc:87
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:1182
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:145
virtual ConstHostCollection getAll4(const SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
Definition: cfg_hosts.cc:51
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:665
virtual ConstHostCollection getAll6(const SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
Definition: cfg_hosts.cc:69
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:125
isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition: cfg_hosts.cc:1227
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:105
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:28
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:274
#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
IPv6ResrvCollection::const_iterator IPv6ResrvIterator
Definition: host.h:241
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:132
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.