Kea: cfg_hosts.cc Source File

| Kea 3.2.0-git

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