Kea 2.5.8
lease_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2012-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
9#include <dhcp/libdhcp++.h>
10#include <dhcp/option_custom.h>
11#include <dhcpsrv/cfgmgr.h>
12#include <dhcpsrv/dhcpsrv_log.h>
13#include <dhcpsrv/lease_mgr.h>
15#include <stats/stats_mgr.h>
16#include <util/encode/encode.h>
17#include <util/str.h>
18
19#include <boost/algorithm/string.hpp>
20
21#include <algorithm>
22#include <iostream>
23#include <iterator>
24#include <limits>
25#include <map>
26#include <sstream>
27#include <string>
28
29#include <time.h>
30
31using namespace isc::asiolink;
32using namespace isc::data;
33using namespace isc::db;
34using namespace isc::dhcp;
35using namespace isc::util;
36using namespace std;
37
38namespace isc {
39namespace dhcp {
40
41LeasePageSize::LeasePageSize(const size_t page_size)
42 : page_size_(page_size) {
43
44 if (page_size_ == 0) {
45 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
46 }
47
48 if (page_size_ > std::numeric_limits<uint32_t>::max()) {
49 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
50 << std::numeric_limits<uint32_t>::max());
51 }
52}
53
56 uint32_t iaid, SubnetID subnet_id) const {
57 Lease6Collection col = getLeases6(type, duid, iaid, subnet_id);
58
59 if (col.size() > 1) {
60 isc_throw(MultipleRecords, "More than one lease found for type "
61 << static_cast<int>(type) << ", duid "
62 << duid.toText() << ", iaid " << iaid
63 << " and subnet-id " << subnet_id);
64 }
65 if (col.empty()) {
66 return (Lease6Ptr());
67 }
68 return (*col.begin());
69}
70
71void
73 using namespace stats;
74
75 StatsMgr& stats_mgr = StatsMgr::instance();
76
78 if (!query) {
80 return;
81 }
82
83 // Zero out the global stats.
84 // Cumulative counters ("reclaimed-declined-addresses", "reclaimed-leases",
85 // "cumulative-assigned-addresses") never get zeroed.
86 int64_t zero = 0;
87 stats_mgr.setValue("declined-addresses", zero);
88
89 // Create if it does not exit reclaimed declined leases global stats.
90 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
91 stats_mgr.setValue("reclaimed-declined-addresses", zero);
92 }
93
94 // Create if it does not exit reclaimed leases global stats.
95 if (!stats_mgr.getObservation("reclaimed-leases")) {
96 stats_mgr.setValue("reclaimed-leases", zero);
97 }
98
99 // Create if it does not exit cumulative global stats.
100 if (!stats_mgr.getObservation("cumulative-assigned-addresses")) {
101 stats_mgr.setValue("cumulative-assigned-addresses", zero);
102 }
103
104 // Clear subnet level stats. This ensures we don't end up with corner
105 // cases that leave stale values in place.
106 const Subnet4Collection* subnets =
107 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
108
109 for (auto const& subnet : *subnets) {
110 SubnetID subnet_id = subnet->getID();
111 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
112 "assigned-addresses"),
113 zero);
114
115 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
116 "declined-addresses"),
117 zero);
118
119 const std::string name_rec_dec(StatsMgr::generateName("subnet", subnet_id,
120 "reclaimed-declined-addresses"));
121 if (!stats_mgr.getObservation(name_rec_dec)) {
122 stats_mgr.setValue(name_rec_dec, zero);
123 }
124
125 const std::string name_rec(StatsMgr::generateName("subnet", subnet_id,
126 "reclaimed-leases"));
127 if (!stats_mgr.getObservation(name_rec)) {
128 stats_mgr.setValue(name_rec, zero);
129 }
130
131 for (auto const& pool : subnet->getPools(Lease::TYPE_V4)) {
132 const std::string name_aa(StatsMgr::generateName("subnet", subnet_id,
133 StatsMgr::generateName("pool", pool->getID(),
134 "assigned-addresses")));
135 if (!stats_mgr.getObservation(name_aa)) {
136 stats_mgr.setValue(name_aa, zero);
137 }
138
139 const std::string& name_da(StatsMgr::generateName("subnet", subnet_id,
140 StatsMgr::generateName("pool", pool->getID(),
141 "declined-addresses")));
142 if (!stats_mgr.getObservation(name_da)) {
143 stats_mgr.setValue(name_da, zero);
144 }
145
146 const std::string& name_rec_dec(StatsMgr::generateName("subnet", subnet_id,
147 StatsMgr::generateName("pool", pool->getID(),
148 "reclaimed-declined-addresses")));
149 if (!stats_mgr.getObservation(name_rec_dec)) {
150 stats_mgr.setValue(name_rec_dec, zero);
151 }
152
153 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
154 StatsMgr::generateName("pool", pool->getID(),
155 "reclaimed-leases")));
156 if (!stats_mgr.getObservation(name_rec)) {
157 stats_mgr.setValue(name_rec, zero);
158 }
159 }
160 }
161
162 // Get counts per state per subnet. Iterate over the result set
163 // updating the subnet and global values.
164 LeaseStatsRow row;
165 while (query->getNextRow(row)) {
167 // Add to subnet level value.
168 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
169 "assigned-addresses"),
170 row.state_count_);
171 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
172 // Set subnet level value.
173 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
174 "declined-addresses"),
175 row.state_count_);
176
177 // Add to the global value.
178 stats_mgr.addValue("declined-addresses", row.state_count_);
179
180 // Add to subnet level value.
181 // Declined leases also count as assigned.
182 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
183 "assigned-addresses"),
184 row.state_count_);
185 }
186 }
187
189 if (!query) {
191 return;
192 }
193
194 // Get counts per state per subnet and pool. Iterate over the result set
195 // updating the subnet and pool and global values.
196 while (query->getNextRow(row)) {
198 // Add to subnet and pool level value.
199 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
200 StatsMgr::generateName("pool", row.pool_id_,
201 "assigned-addresses")),
202 row.state_count_);
203 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
204 // Set subnet and pool level value.
205 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
206 StatsMgr::generateName("pool", row.pool_id_,
207 "declined-addresses")),
208 row.state_count_);
209
210 // Add to subnet and pool level value.
211 // Declined leases also count as assigned.
212 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
213 StatsMgr::generateName("pool", row.pool_id_,
214 "assigned-addresses")),
215 row.state_count_);
216 }
217 }
218}
219
221 : first_subnet_id_(0), last_subnet_id_(0), select_mode_(select_mode) {
222 if (select_mode != ALL_SUBNETS && select_mode != ALL_SUBNET_POOLS) {
223 isc_throw(BadValue, "LeaseStatsQuery: mode must be either ALL_SUBNETS or ALL_SUBNET_POOLS");
224 }
225}
226
228 : first_subnet_id_(subnet_id), last_subnet_id_(0),
229 select_mode_(SINGLE_SUBNET) {
230
231 if (first_subnet_id_ == 0) {
232 isc_throw(BadValue, "LeaseStatsQuery: subnet_id_ must be > 0");
233 }
234}
235
237 const SubnetID& last_subnet_id)
238 : first_subnet_id_(first_subnet_id), last_subnet_id_(last_subnet_id),
239 select_mode_(SUBNET_RANGE) {
240
241 if (first_subnet_id_ == 0) {
242 isc_throw(BadValue, "LeaseStatsQuery: first_subnet_id_ must be > 0");
243 }
244
245 if (last_subnet_id_ == 0) {
246 isc_throw(BadValue, "LeaseStatsQuery: last_subnet_id_ must be > 0");
247 }
248
251 "LeaseStatsQuery: last_subnet_id_must be > first_subnet_id_");
252 }
253}
254
257 return(LeaseStatsQueryPtr());
258}
259
262 return(LeaseStatsQueryPtr());
263}
264
267 return(LeaseStatsQueryPtr());
268}
269
272 const SubnetID& /* last_subnet_id */) {
273 return(LeaseStatsQueryPtr());
274}
275
276bool
278 return (false);
279}
280
281void
283 using namespace stats;
284
285 StatsMgr& stats_mgr = StatsMgr::instance();
286
288 if (!query) {
290 return;
291 }
292
293 // Zero out the global stats.
294 // Cumulative counters ("reclaimed-declined-addresses", "reclaimed-leases",
295 // "cumulative-assigned-nas", "cumulative-assigned-pds") never get zeroed.
296 int64_t zero = 0;
297 stats_mgr.setValue("declined-addresses", zero);
298
299 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
300 stats_mgr.setValue("reclaimed-declined-addresses", zero);
301 }
302
303 if (!stats_mgr.getObservation("reclaimed-leases")) {
304 stats_mgr.setValue("reclaimed-leases", zero);
305 }
306
307 // Create if it does not exit cumulative nas global stats.
308 if (!stats_mgr.getObservation("cumulative-assigned-nas")) {
309 stats_mgr.setValue("cumulative-assigned-nas", zero);
310 }
311
312 // Create if it does not exit cumulative pds global stats.
313 if (!stats_mgr.getObservation("cumulative-assigned-pds")) {
314 stats_mgr.setValue("cumulative-assigned-pds", zero);
315 }
316
317 // Clear subnet level stats. This ensures we don't end up with corner
318 // cases that leave stale values in place.
319 const Subnet6Collection* subnets =
320 CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
321
322 for (auto const& subnet : *subnets) {
323 SubnetID subnet_id = subnet->getID();
324 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
325 "assigned-nas"),
326 zero);
327
328 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
329 "assigned-pds"),
330 zero);
331
332 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
333 "declined-addresses"),
334 zero);
335
336 if (!stats_mgr.getObservation(
337 StatsMgr::generateName("subnet", subnet_id,
338 "reclaimed-declined-addresses"))) {
339 stats_mgr.setValue(
340 StatsMgr::generateName("subnet", subnet_id,
341 "reclaimed-declined-addresses"),
342 zero);
343 }
344
345 if (!stats_mgr.getObservation(
346 StatsMgr::generateName("subnet", subnet_id,
347 "reclaimed-leases"))) {
348 stats_mgr.setValue(
349 StatsMgr::generateName("subnet", subnet_id,
350 "reclaimed-leases"),
351 zero);
352 }
353
354 for (auto const& pool : subnet->getPools(Lease::TYPE_NA)) {
355 const std::string& name_anas(StatsMgr::generateName("subnet", subnet_id,
356 StatsMgr::generateName("pool", pool->getID(),
357 "assigned-nas")));
358 if (!stats_mgr.getObservation(name_anas)) {
359 stats_mgr.setValue(name_anas, zero);
360 }
361
362 const std::string& name_da(StatsMgr::generateName("subnet", subnet_id,
363 StatsMgr::generateName("pool", pool->getID(),
364 "declined-addresses")));
365 if (!stats_mgr.getObservation(name_da)) {
366 stats_mgr.setValue(name_da, zero);
367 }
368
369 const std::string name_rec_dec(StatsMgr::generateName("subnet", subnet_id,
370 StatsMgr::generateName("pool", pool->getID(),
371 "reclaimed-declined-addresses")));
372 if (!stats_mgr.getObservation(name_rec_dec)) {
373 stats_mgr.setValue(name_rec_dec, zero);
374 }
375
376 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
377 StatsMgr::generateName("pool", pool->getID(),
378 "reclaimed-leases")));
379 if (!stats_mgr.getObservation(name_rec)) {
380 stats_mgr.setValue(name_rec, zero);
381 }
382 }
383
384 for (auto const& pool : subnet->getPools(Lease::TYPE_PD)) {
385 const std::string& name_apds(StatsMgr::generateName("subnet", subnet_id,
386 StatsMgr::generateName("pd-pool", pool->getID(),
387 "assigned-pds")));
388 if (!stats_mgr.getObservation(name_apds)) {
389 stats_mgr.setValue(name_apds, zero);
390 }
391
392 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
393 StatsMgr::generateName("pd-pool", pool->getID(),
394 "reclaimed-leases")));
395 if (!stats_mgr.getObservation(name_rec)) {
396 stats_mgr.setValue(name_rec, zero);
397 }
398 }
399 }
400
401 // Get counts per state per subnet. Iterate over the result set
402 // updating the subnet and global values.
403 LeaseStatsRow row;
404 while (query->getNextRow(row)) {
405 switch(row.lease_type_) {
406 case Lease::TYPE_NA:
408 // Add to subnet level value.
409 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
410 "assigned-nas"),
411 row.state_count_);
412 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
413 // Set subnet level value.
414 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
415 "declined-addresses"),
416 row.state_count_);
417
418 // Add to the global value.
419 stats_mgr.addValue("declined-addresses", row.state_count_);
420
421 // Add to subnet level value.
422 // Declined leases also count as assigned.
423 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
424 "assigned-nas"),
425 row.state_count_);
426 }
427 break;
428
429 case Lease::TYPE_PD:
431 // Set subnet level value.
432 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
433 "assigned-pds"),
434 row.state_count_);
435 }
436 break;
437
438 default:
439 // We don't support TYPE_TAs yet
440 break;
441 }
442 }
443
445 if (!query) {
447 return;
448 }
449
450 // Get counts per state per subnet and pool. Iterate over the result set
451 // updating the subnet and pool and global values.
452 while (query->getNextRow(row)) {
453 switch(row.lease_type_) {
454 case Lease::TYPE_NA:
456 // Add to subnet and pool level value.
457 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
458 StatsMgr::generateName("pool", row.pool_id_,
459 "assigned-nas")),
460 row.state_count_);
461 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
462 // Set subnet and pool level value.
463 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
464 StatsMgr::generateName("pool", row.pool_id_,
465 "declined-addresses")),
466 row.state_count_);
467
468 // Add to subnet and pool level value.
469 // Declined leases also count as assigned.
470 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
471 StatsMgr::generateName("pool", row.pool_id_,
472 "assigned-nas")),
473 row.state_count_);
474 }
475 break;
476
477 case Lease::TYPE_PD:
479 // Set subnet and pool level value.
480 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
481 StatsMgr::generateName("pd-pool", row.pool_id_,
482 "assigned-pds")),
483 row.state_count_);
484 }
485 break;
486
487 default:
488 // We don't support TYPE_TAs yet
489 break;
490 }
491 }
492}
493
496 return(LeaseStatsQueryPtr());
497}
498
501 return(LeaseStatsQueryPtr());
502}
503
506 return(LeaseStatsQueryPtr());
507}
508
511 const SubnetID& /* last_subnet_id */) {
512 return(LeaseStatsQueryPtr());
513}
514
515std::string
517 isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called");
518}
519
520void
522 std::string extended_info_tables;
523 try {
524 extended_info_tables = parameters.at("extended-info-tables");
525 } catch (const exception&) {
526 extended_info_tables = "false";
527 }
528 // If extended_info_tables is 'true' we will enable them.
529 if (extended_info_tables == "true") {
531 }
532}
533
534bool
537 static OptionDefinitionPtr rai_def;
538
539 bool changed = false;
540 if (!lease) {
541 return (changed);
542 }
543
545 return (changed);
546 }
547
548 ConstElementPtr user_context = lease->getContext();
549 if (!user_context) {
550 return (changed);
551 }
552
553 if (!rai_def) {
556 }
557
558 if (!rai_def) {
559 // The definition is set when libdhcp++ is loaded so it is impossible
560 // to not be able to get it... so should not happen!
561 isc_throw(Unexpected, "can't find RAI option definition?!");
562 }
563
565 ConstElementPtr extended_info;
566 ElementPtr mutable_user_context;
567 ElementPtr mutable_isc;
568 string verifying = "";
569 bool removed_extended_info = false;
570
571 try {
572 verifying = "user context";
573 if (user_context->getType() != Element::map) {
574 isc_throw(BadValue, "user context is not a map");
575 }
576 if (user_context->empty()) {
577 changed = true;
578 lease->setContext(ConstElementPtr());
579 return (changed);
580 }
581
582 verifying = "isc";
583 isc = user_context->get("ISC");
584 if (!isc) {
585 return (changed);
586 }
587 mutable_user_context =
588 boost::const_pointer_cast<Element>(user_context);
589 if (!mutable_user_context) {
590 // Should not happen...
591 mutable_user_context = copy(user_context, 0);
592 lease->setContext(mutable_user_context);
593 }
594
595 if (isc->getType() != Element::map) {
596 isc_throw(BadValue, "ISC entry is not a map");
597 }
598 if (isc->empty()) {
599 changed = true;
600 mutable_user_context->remove("ISC");
601 if (mutable_user_context->empty()) {
602 lease->setContext(ConstElementPtr());
603 }
604 return (changed);
605 }
606
607 verifying = "relay-agent-info";
608 extended_info = isc->get("relay-agent-info");
609 if (!extended_info) {
610 return (changed);
611 }
612 mutable_isc = boost::const_pointer_cast<Element>(isc);
613 if (!mutable_isc) {
614 // Should not happen...
615 mutable_isc = copy(isc, 0);
616 mutable_user_context->set("ISC", mutable_isc);
617 }
618
619 if (extended_info->getType() == Element::string) {
620 // Upgrade
621 changed = true;
622 ElementPtr upgraded = Element::createMap();
623 upgraded->set("sub-options", extended_info);
624 mutable_isc->set("relay-agent-info", upgraded);
625
626 // Try to decode sub-options.
627 verifying = "rai";
628 string rai_hex = extended_info->stringValue();
629 vector<uint8_t> rai_data;
630 str::decodeFormattedHexString(rai_hex, rai_data);
631 OptionCustomPtr rai(new OptionCustom(*rai_def, Option::V4, rai_data));
632 if (!rai) {
633 isc_throw(BadValue, "can't create RAI option");
634 }
635
636 OptionPtr remote_id = rai->getOption(RAI_OPTION_REMOTE_ID);
637 if (remote_id) {
638 vector<uint8_t> bytes = remote_id->toBinary();
639 if (bytes.size() > 0) {
640 upgraded->set("remote-id",
642 }
643 }
644
645 OptionPtr relay_id = rai->getOption(RAI_OPTION_RELAY_ID);
646 if (relay_id) {
647 vector<uint8_t> bytes = relay_id->toBinary(false);
648 if (bytes.size() > 0) {
649 upgraded->set("relay-id",
651 }
652 }
653
656 .arg(lease->addr_.toText());
657 return (changed);
658 } else if (extended_info->getType() != Element::map) {
659 mutable_isc->remove("relay-agent-info");
660 removed_extended_info = true;
661 isc_throw(BadValue, "relay-agent-info is not a map or a string");
662 }
663
665 return (changed);
666 }
667
668 // Try to decode sub-options.
669 ConstElementPtr sub_options = extended_info->get("sub-options");
670 if (sub_options) {
671 verifying = "sub-options";
672 if (sub_options->getType() != Element::string) {
673 mutable_isc->remove("relay-agent-info");
674 removed_extended_info = true;
675 isc_throw(BadValue, "sub-options is not a string");
676 }
677 string rai_hex = sub_options->stringValue();
678 vector<uint8_t> rai_data;
679 str::decodeFormattedHexString(rai_hex, rai_data);
680 }
681
682 ConstElementPtr remote_id = extended_info->get("remote-id");
683 if (remote_id) {
684 verifying = "remote-id";
685 if (remote_id->getType() != Element::string) {
686 mutable_isc->remove("relay-agent-info");
687 removed_extended_info = true;
688 isc_throw(BadValue, "remote-id is not a string");
689 }
690 string remote_id_hex = remote_id->stringValue();
691 vector<uint8_t> remote_id_data;
692 encode::decodeHex(remote_id_hex, remote_id_data);
693 if (remote_id_data.empty()) {
694 mutable_isc->remove("relay-agent-info");
695 removed_extended_info = true;
696 isc_throw(BadValue, "remote-id is empty");
697 }
698 }
699
700 ConstElementPtr relay_id = extended_info->get("relay-id");
701 if (relay_id) {
702 verifying = "relay-id";
703 if (relay_id->getType() != Element::string) {
704 mutable_isc->remove("relay-agent-info");
705 removed_extended_info = true;
706 isc_throw(BadValue, "relay-id is not a string");
707 }
708 string relay_id_hex = relay_id->stringValue();
709 vector<uint8_t> relay_id_data;
710 encode::decodeHex(relay_id_hex, relay_id_data);
711 if (relay_id_data.empty()) {
712 mutable_isc->remove("relay-agent-info");
713 removed_extended_info = true;
714 isc_throw(BadValue, "relay-id is empty");
715 }
716 }
717
719 return (changed);
720 }
721
722 verifying = "relay-agent-info";
723 for (auto const& elem : extended_info->mapValue()) {
724 if ((elem.first != "sub-options") &&
725 (elem.first != "remote-id") &&
726 (elem.first != "relay-id") &&
727 (elem.first != "comment")) {
728 mutable_isc->remove("relay-agent-info");
729 removed_extended_info = true;
730 isc_throw(BadValue, "spurious '" << elem.first <<
731 "' entry in relay-agent-info");
732 }
733 }
734
735 return (changed);
736 } catch (const exception& ex) {
737 ostringstream err;
738 err << "in " << verifying << " a problem was found: " << ex.what();
740 .arg(lease->addr_.toText())
741 .arg(err.str());
742
743 changed = true;
744 if (verifying == "user context") {
745 lease->setContext(ConstElementPtr());
746 } else if (verifying == "isc") {
747 mutable_user_context->remove("ISC");
748 if (mutable_user_context->empty()) {
749 lease->setContext(ConstElementPtr());
750 }
751 } else {
752 if (!removed_extended_info) {
753 mutable_isc->remove("relay-agent-info");
754 }
755 if (mutable_isc->empty()) {
756 mutable_user_context->remove("ISC");
757 if (mutable_user_context->empty()) {
758 lease->setContext(ConstElementPtr());
759 }
760 }
761 }
762 return (changed);
763 }
764}
765
766bool
769 bool changed = false;
770 if (!lease) {
771 return (changed);
772 }
773
775 return (changed);
776 }
777
778 ConstElementPtr user_context = lease->getContext();
779 if (!user_context) {
780 return (changed);
781 }
782
784 ConstElementPtr relay_info;
785 ElementPtr mutable_user_context;
786 ElementPtr mutable_isc;
787 string verifying = "";
788 bool removed_relay_info = false;
789 bool upgraded = false;
790 bool have_both = false;
791 int i = -1;
792
793 try {
794 verifying = "user context";
795 if (user_context->getType() != Element::map) {
796 isc_throw(BadValue, "user context is not a map");
797 }
798 if (user_context->empty()) {
799 changed = true;
800 lease->setContext(ConstElementPtr());
801 return (changed);
802 }
803
804 verifying = "isc";
805 isc = user_context->get("ISC");
806 if (!isc) {
807 return (changed);
808 }
809 mutable_user_context =
810 boost::const_pointer_cast<Element>(user_context);
811 if (!mutable_user_context) {
812 // Should not happen...
813 mutable_user_context = copy(user_context, 0);
814 lease->setContext(mutable_user_context);
815 }
816
817 if (isc->getType() != Element::map) {
818 isc_throw(BadValue, "ISC entry is not a map");
819 }
820 if (isc->empty()) {
821 changed = true;
822 mutable_user_context->remove("ISC");
823 if (mutable_user_context->empty()) {
824 lease->setContext(ConstElementPtr());
825 }
826 return (changed);
827 }
828 mutable_isc = boost::const_pointer_cast<Element>(isc);
829 if (!mutable_isc) {
830 // Should not happen...
831 mutable_isc = copy(isc, 0);
832 mutable_user_context->set("ISC", mutable_isc);
833 }
834
835 relay_info = mutable_isc->get("relays");
836 if (relay_info && isc->contains("relay-info")) {
837 changed = true;
838 mutable_isc->remove("relays");
839 have_both = true;
840 relay_info.reset();
841 }
842 if (relay_info) {
843 // Upgrade
844 changed = true;
845 upgraded = true;
846 verifying = "relays";
847 mutable_isc->set("relay-info", relay_info);
848 mutable_isc->remove("relays");
849
850 if (relay_info->getType() != Element::list) {
851 mutable_isc->remove("relay-info");
852 removed_relay_info = true;
853 isc_throw(BadValue, "relays is not a list");
854 }
855 if (relay_info->empty()) {
856 mutable_isc->remove("relay-info");
857 removed_relay_info = true;
858 isc_throw(BadValue, "relays is empty");
859 }
860
861 verifying = "relay";
862 for (i = 0; i < relay_info->size(); ++i) {
863 ElementPtr relay = relay_info->getNonConst(i);
864 if (!relay) {
865 mutable_isc->remove("relay-info");
866 removed_relay_info = true;
867 isc_throw(BadValue, "null relay#" << i);
868 }
869 if (relay->getType() != Element::map) {
870 mutable_isc->remove("relay-info");
871 removed_relay_info = true;
872 isc_throw(BadValue, "relay#" << i << " is not a map");
873 }
874
875 // Try to decode options.
876 ConstElementPtr options = relay->get("options");
877 if (!options) {
878 continue;
879 }
880
881 verifying = "options";
882 if (options->getType() != Element::string) {
883 mutable_isc->remove("relay-info");
884 removed_relay_info = true;
885 isc_throw(BadValue, "options is not a string");
886 }
887 string options_hex = options->stringValue();
888 vector<uint8_t> options_data;
889 str::decodeFormattedHexString(options_hex, options_data);
890 OptionCollection opts;
891 LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
892
893 auto remote_id_it = opts.find(D6O_REMOTE_ID);
894 if (remote_id_it != opts.end()) {
895 OptionPtr remote_id = remote_id_it->second;
896 if (remote_id) {
897 vector<uint8_t> bytes = remote_id->toBinary();
898 if (bytes.size() > 0) {
899 relay->set("remote-id",
901 }
902 }
903 }
904
905 auto relay_id_it = opts.find(D6O_RELAY_ID);
906 if (relay_id_it != opts.end()) {
907 OptionPtr relay_id = relay_id_it->second;
908 if (relay_id) {
909 vector<uint8_t> bytes = relay_id->toBinary(false);
910 if (bytes.size() > 0) {
911 relay->set("relay-id",
913 }
914 }
915 }
916 }
917 }
918
919 verifying = (upgraded ? "relays" : "relay-info");
920 i = -1;
921 relay_info = mutable_isc->get("relay-info");
922 if (!relay_info) {
923 return (changed);
924 }
925 if (!upgraded && (relay_info->getType() != Element::list)) {
926 mutable_isc->remove("relay-info");
927 removed_relay_info = true;
928 isc_throw(BadValue, "relay-info is not a list");
929 }
930 if (!upgraded && relay_info->empty()) {
931 mutable_isc->remove("relay-info");
932 removed_relay_info = true;
933 isc_throw(BadValue, "relay-info is empty");
934 }
935
936 verifying = "relay";
937 for (i = 0; i < relay_info->size(); ++i) {
938 ElementPtr relay = relay_info->getNonConst(i);
939 if (!upgraded && !relay) {
940 mutable_isc->remove("relay-info");
941 removed_relay_info = true;
942 isc_throw(BadValue, "null relay#" << i);
943 }
944 if (!upgraded && (relay->getType() != Element::map)) {
945 mutable_isc->remove("relay-info");
946 removed_relay_info = true;
947 isc_throw(BadValue, "relay#" << i << " is not a map");
948 }
949
950 ConstElementPtr options = relay->get("options");
951 if (!upgraded && options) {
952 // Try to decode options.
953 verifying = "options";
954 if (options->getType() != Element::string) {
955 mutable_isc->remove("relay-info");
956 removed_relay_info = true;
957 isc_throw(BadValue, "options is not a string");
958 }
959 string options_hex = options->stringValue();
960 vector<uint8_t> options_data;
961 str::decodeFormattedHexString(options_hex, options_data);
962 OptionCollection opts;
963 LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
964 }
966 continue;
967 }
968
969 verifying = "link";
970 ConstElementPtr link_addr = relay->get("link");
971 if (!link_addr) {
972 mutable_isc->remove("relay-info");
973 removed_relay_info = true;
974 isc_throw(BadValue, "no link");
975 }
976 if (link_addr->getType() != Element::string) {
977 mutable_isc->remove("relay-info");
978 removed_relay_info = true;
979 isc_throw(BadValue, "link is not a string");
980 }
981 IOAddress laddr(link_addr->stringValue());
982 if (!laddr.isV6()) {
983 mutable_isc->remove("relay-info");
984 removed_relay_info = true;
985 isc_throw(BadValue, "link is not an IPv6 address");
986 }
987
988 ConstElementPtr remote_id = relay->get("remote-id");
989 if (!upgraded && remote_id) {
990 verifying = "remote-id";
991 if (remote_id->getType() != Element::string) {
992 mutable_isc->remove("relay-info");
993 removed_relay_info = true;
994 isc_throw(BadValue, "remote-id is not a string");
995 }
996 string remote_id_hex = remote_id->stringValue();
997 vector<uint8_t> remote_id_data;
998 encode::decodeHex(remote_id_hex, remote_id_data);
999 if (remote_id_data.empty()) {
1000 mutable_isc->remove("relay-info");
1001 removed_relay_info = true;
1002 isc_throw(BadValue, "remote-id is empty");
1003 }
1004 }
1005
1006 ConstElementPtr relay_id = relay->get("relay-id");
1007 if (!upgraded && relay_id) {
1008 verifying = "relay-id";
1009 if (relay_id->getType() != Element::string) {
1010 mutable_isc->remove("relay-info");
1011 removed_relay_info = true;
1012 isc_throw(BadValue, "relay-id is not a string");
1013 }
1014 string relay_id_hex = relay_id->stringValue();
1015 vector<uint8_t> relay_id_data;
1016 encode::decodeHex(relay_id_hex, relay_id_data);
1017 if (relay_id_data.empty()) {
1018 mutable_isc->remove("relay-info");
1019 removed_relay_info = true;
1020 isc_throw(BadValue, "relay-id is empty");
1021 }
1022 }
1023
1025 continue;
1026 }
1027
1028 verifying = "peer";
1029 ConstElementPtr peer_addr = relay->get("peer");
1030 if (!peer_addr) {
1031 mutable_isc->remove("relay-info");
1032 removed_relay_info = true;
1033 isc_throw(BadValue, "no peer");
1034 }
1035 if (peer_addr->getType() != Element::string) {
1036 mutable_isc->remove("relay-info");
1037 removed_relay_info = true;
1038 isc_throw(BadValue, "peer is not a string");
1039 }
1040 IOAddress paddr(peer_addr->stringValue());
1041 if (!paddr.isV6()) {
1042 mutable_isc->remove("relay-info");
1043 removed_relay_info = true;
1044 isc_throw(BadValue, "peer is not an IPv6 address");
1045 }
1046
1047 verifying = "hop";
1048 ConstElementPtr hop = relay->get("hop");
1049 if (!hop) {
1050 mutable_isc->remove("relay-info");
1051 removed_relay_info = true;
1052 isc_throw(BadValue, "no hop");
1053 }
1054 if (hop->getType() != Element::integer) {
1055 mutable_isc->remove("relay-info");
1056 removed_relay_info = true;
1057 isc_throw(BadValue, "hop is not an integer");
1058 }
1059
1060 verifying = (upgraded ? "relays" : "relay-info");
1061 for (auto const& elem : relay->mapValue()) {
1062 if ((elem.first != "hop") &&
1063 (elem.first != "link") &&
1064 (elem.first != "peer") &&
1065 (elem.first != "options") &&
1066 (elem.first != "remote-id") &&
1067 (elem.first != "relay-id") &&
1068 (elem.first != "comment")) {
1069 mutable_isc->remove("relay-info");
1070 removed_relay_info = true;
1071 isc_throw(BadValue, "spurious '" << elem.first << "' entry");
1072 }
1073 }
1074 }
1075
1076 if (upgraded) {
1079 .arg(lease->addr_.toText());
1080 }
1081
1082 return (changed);
1083 } catch (const exception& ex) {
1084 ostringstream err;
1085 err << "in " << verifying;
1086 if (i >= 0) {
1087 err << " [relay#" << i << "]";
1088 }
1089 err << " a problem was found: " << ex.what();
1091 .arg(lease->addr_.toText())
1092 .arg(err.str());
1093
1094 changed = true;
1095 have_both = !have_both;
1096 if (verifying == "user context") {
1097 lease->setContext(ConstElementPtr());
1098 } else if (verifying == "isc") {
1099 mutable_user_context->remove("ISC");
1100 if (mutable_user_context->empty()) {
1101 lease->setContext(ConstElementPtr());
1102 }
1103 } else {
1104 if (!removed_relay_info) {
1105 mutable_isc->remove("relay-info");
1106 }
1107 if (mutable_isc->empty()) {
1108 mutable_user_context->remove("ISC");
1109 if (mutable_user_context->empty()) {
1110 lease->setContext(ConstElementPtr());
1111 }
1112 }
1113 }
1114 return (changed);
1115 }
1116}
1117
1118void
1120 bool ignore_errors) {
1121 if (!lease) {
1122 return;
1123 }
1124
1125 ConstElementPtr user_context = lease->getContext();
1126 if (!user_context) {
1127 return;
1128 }
1129 if (user_context->getType() != Element::map) {
1130 if (ignore_errors) {
1131 return;
1132 }
1133 isc_throw(BadValue, "user context is not a map");
1134 }
1135 if (user_context->empty()) {
1136 return;
1137 }
1138
1139 ConstElementPtr isc = user_context->get("ISC");
1140 if (!isc) {
1141 return;
1142 }
1143 if (isc->getType() != Element::map) {
1144 if (ignore_errors) {
1145 return;
1146 }
1147 isc_throw(BadValue, "ISC entry is not a map");
1148 }
1149 if (isc->empty()) {
1150 return;
1151 }
1152
1153 ConstElementPtr extended_info = isc->get("relay-agent-info");
1154 if (!extended_info) {
1155 return;
1156 }
1157 if (extended_info->getType() != Element::map) {
1158 if (ignore_errors) {
1159 return;
1160 }
1161 isc_throw(BadValue, "relay-agent-info is not a map");
1162 }
1163 if (extended_info->empty()) {
1164 return;
1165 }
1166
1167 ConstElementPtr relay_id = extended_info->get("relay-id");
1168 if (relay_id) {
1169 if (relay_id->getType() == Element::string) {
1170 vector<uint8_t> bytes;
1171 try {
1172 encode::decodeHex(relay_id->stringValue(), bytes);
1173 } catch (...) {
1174 // Decode failed
1175 if (!ignore_errors) {
1176 throw;
1177 }
1178 }
1179 lease->relay_id_ = bytes;
1180 } else if (!ignore_errors) {
1181 isc_throw(BadValue, "relay-id entry is not a string");
1182 }
1183 }
1184
1185 ConstElementPtr remote_id = extended_info->get("remote-id");
1186 if (remote_id) {
1187 if (remote_id->getType() == Element::string) {
1188 vector<uint8_t> bytes;
1189 try {
1190 encode::decodeHex(remote_id->stringValue(), bytes);
1191 } catch (...) {
1192 // Decode failed
1193 if (!ignore_errors) {
1194 throw;
1195 }
1196 }
1197 lease->remote_id_ = bytes;
1198 } else if (!ignore_errors) {
1199 isc_throw(BadValue, "remote-id entry is not a string");
1200 }
1201 }
1202}
1203
1204bool
1206
1207 bool added = false;
1208 if (!lease) {
1209 return (added);
1210 }
1211
1212 ConstElementPtr user_context = lease->getContext();
1213 if (!user_context || (user_context->getType() != Element::map) ||
1214 user_context->empty()) {
1215 return (added);
1216 }
1217
1218 ConstElementPtr isc = user_context->get("ISC");
1219 if (!isc || (isc->getType() != Element::map) || isc->empty()) {
1220 return (added);
1221 }
1222
1223 ConstElementPtr relay_info = isc->get("relay-info");
1224 if (!relay_info || (relay_info->getType() != Element::list) ||
1225 relay_info->empty()) {
1226 return (added);
1227 }
1228
1229 for (int i = 0; i < relay_info->size(); ++i) {
1230 ConstElementPtr relay = relay_info->get(i);
1231 if (!relay || (relay->getType() != Element::map) || relay->empty()) {
1232 continue;
1233 }
1234 try {
1235 ConstElementPtr relay_id = relay->get("relay-id");
1236 if (relay_id) {
1237 string relay_id_hex = relay_id->stringValue();
1238 vector<uint8_t> relay_id_data;
1239 encode::decodeHex(relay_id_hex, relay_id_data);
1240 if (relay_id_data.empty()) {
1241 continue;
1242 }
1243 addRelayId6(lease->addr_, relay_id_data);
1244 added = true;
1245 }
1246
1247 ConstElementPtr remote_id = relay->get("remote-id");
1248 if (remote_id) {
1249 string remote_id_hex = remote_id->stringValue();
1250 vector<uint8_t> remote_id_data;
1251 encode::decodeHex(remote_id_hex, remote_id_data);
1252 if (remote_id_data.empty()) {
1253 continue;
1254 }
1255 addRemoteId6(lease->addr_, remote_id_data);
1256 added = true;
1257 }
1258 } catch (const exception&) {
1259 continue;
1260 }
1261 }
1262 return (added);
1263}
1264
1265size_t
1267 return (0);
1268}
1269
1270size_t
1272 return (0);
1273}
1274
1275} // namespace isc::dhcp
1276} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
A generic exception that is thrown when an unexpected error condition occurs.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:304
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Multiple lease records found where one expected.
Definition: db_exceptions.h:16
ExtendedInfoSanity
Values for extended info sanity checks done for leases.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition: cfgmgr.cc:161
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:142
std::string toText() const
Returns textual representation of the identifier (e.g.
Definition: duid.h:88
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: lease_mgr.cc:505
virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets and pools.
Definition: lease_mgr.cc:500
virtual Lease6Collection getLeases6() const =0
Returns all IPv6 leases.
void recountLeaseStats6()
Recalculates per-subnet and global stats for IPv6 leases.
Definition: lease_mgr.cc:282
void setExtendedInfoTablesEnabled(const bool enabled)
Modifies the setting whether the lease6 extended info tables are enabled.
Definition: lease_mgr.h:1018
virtual size_t byRelayId6size() const
Return the by-relay-id table size.
Definition: lease_mgr.cc:1266
static bool upgradeLease6ExtendedInfo(const Lease6Ptr &lease, CfgConsistency::ExtendedInfoSanity check=CfgConsistency::EXTENDED_INFO_CHECK_FIX)
Upgrade a V6 lease user context to the new extended info entry.
Definition: lease_mgr.cc:767
virtual size_t byRemoteId6size() const
Return the by-remote-id table size.
Definition: lease_mgr.cc:1271
virtual void addRelayId6(const isc::asiolink::IOAddress &lease_addr, const std::vector< uint8_t > &relay_id)=0
Add lease6 extended info into by-relay-id table.
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: lease_mgr.cc:271
void recountLeaseStats4()
Recalculates per-subnet and global stats for IPv4 leases.
Definition: lease_mgr.cc:72
static std::string getDBVersion()
Class method to return extended version info This class method must be redeclared and redefined in de...
Definition: lease_mgr.cc:516
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: lease_mgr.cc:510
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: lease_mgr.cc:266
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query for all subnets.
Definition: lease_mgr.cc:256
static void extractLease4ExtendedInfo(const Lease4Ptr &lease, bool ignore_errors=true)
Extract relay and remote identifiers from the extended info.
Definition: lease_mgr.cc:1119
static bool upgradeLease4ExtendedInfo(const Lease4Ptr &lease, CfgConsistency::ExtendedInfoSanity check=CfgConsistency::EXTENDED_INFO_CHECK_FIX)
The following queries are used to fulfill Bulk Lease Query queries.
Definition: lease_mgr.cc:535
virtual void addRemoteId6(const isc::asiolink::IOAddress &lease_addr, const std::vector< uint8_t > &remote_id)=0
Add lease6 extended info into by-remote-id table.
virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query for all subnets and pools.
Definition: lease_mgr.cc:261
virtual bool addExtendedInfo6(const Lease6Ptr &lease)
Extract extended info from a lease6 and add it into tables.
Definition: lease_mgr.cc:1205
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets.
Definition: lease_mgr.cc:495
const size_t page_size_
Holds page size.
Definition: lease_mgr.h:56
LeasePageSize(const size_t page_size)
Constructor.
Definition: lease_mgr.cc:41
LeaseStatsQuery(const SelectMode &select_mode=ALL_SUBNETS)
Constructor to query statistics for all subnets.
Definition: lease_mgr.cc:220
SubnetID first_subnet_id_
First (or only) subnet_id in the selection criteria.
Definition: lease_mgr.h:222
SubnetID last_subnet_id_
Last subnet_id in the selection criteria when a range is given.
Definition: lease_mgr.h:225
virtual bool getNextRow(LeaseStatsRow &row)
Fetches the next row of data.
Definition: lease_mgr.cc:277
SelectMode
Defines the types of selection criteria supported.
Definition: lease_mgr.h:152
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
Definition: libdhcp++.cc:126
static size_t unpackOptions6(const OptionBuffer &buf, const std::string &option_space, isc::dhcp::OptionCollection &options, size_t *relay_msg_offset=0, size_t *relay_msg_len=0)
Parses provided buffer as DHCPv6 options and creates Option objects.
Definition: libdhcp++.cc:311
Option with defined data fields represented as buffers that can be accessed using data field index.
Definition: option_custom.h:31
@ D6O_REMOTE_ID
Definition: dhcp6.h:57
@ D6O_RELAY_ID
Definition: dhcp6.h:73
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
An abstract API for lease database.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1420
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
@ DHO_DHCP_AGENT_OPTIONS
Definition: dhcp4.h:151
const isc::log::MessageID DHCPSRV_LEASE6_EXTENDED_INFO_UPGRADED
boost::shared_ptr< OptionCustom > OptionCustomPtr
A pointer to the OptionCustom object.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:505
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:670
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Definition: lease_mgr.h:233
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet6Collection
A collection of Subnet6 objects.
Definition: subnet.h:974
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
Definition: option.h:40
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:903
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
@ RAI_OPTION_RELAY_ID
Definition: dhcp4.h:277
@ RAI_OPTION_REMOTE_ID
Definition: dhcp4.h:267
const isc::log::MessageID DHCPSRV_LEASE4_EXTENDED_INFO_SANITY_FAIL
const isc::log::MessageID DHCPSRV_LEASE4_EXTENDED_INFO_UPGRADED
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:292
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition: dhcpsrv_log.h:26
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
const isc::log::MessageID DHCPSRV_LEASE6_EXTENDED_INFO_SANITY_FAIL
void decodeHex(const string &encoded_str, vector< uint8_t > &output)
Decode a base16 encoded string into binary data.
Definition: encode.cc:367
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
Definition: encode.cc:361
void decodeFormattedHexString(const string &hex_string, vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
Definition: str.cc:212
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
#define DHCP6_OPTION_SPACE
Contains a single row of lease statistical data.
Definition: lease_mgr.h:64
uint32_t pool_id_
The pool ID to which this data applies.
Definition: lease_mgr.h:132
int64_t state_count_
state_count The count of leases in the lease state
Definition: lease_mgr.h:141
uint32_t lease_state_
The lease_state to which the count applies.
Definition: lease_mgr.h:138
SubnetID subnet_id_
The subnet ID to which this data applies.
Definition: lease_mgr.h:129
Lease::Type lease_type_
The lease_type to which the count applies.
Definition: lease_mgr.h:135
static const uint32_t STATE_DEFAULT
A lease in the default state.
Definition: lease.h:69
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:72
Type
Type of lease or pool.
Definition: lease.h:46
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:49
@ TYPE_V4
IPv4 lease.
Definition: lease.h:50
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:47