Kea 2.7.8
lease_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2025 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& pname_rec_dec(StatsMgr::generateName("subnet", subnet_id,
147 StatsMgr::generateName("pool", pool->getID(),
148 "reclaimed-declined-addresses")));
149 if (!stats_mgr.getObservation(pname_rec_dec)) {
150 stats_mgr.setValue(pname_rec_dec, zero);
151 }
152
153 const std::string& pname_rec(StatsMgr::generateName("subnet", subnet_id,
154 StatsMgr::generateName("pool", pool->getID(),
155 "reclaimed-leases")));
156 if (!stats_mgr.getObservation(pname_rec)) {
157 stats_mgr.setValue(pname_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
259
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",
296 // "cumulative-registered-nas")) never get zeroed.
297 int64_t zero = 0;
298 stats_mgr.setValue("declined-addresses", zero);
299
300 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
301 stats_mgr.setValue("reclaimed-declined-addresses", zero);
302 }
303
304 if (!stats_mgr.getObservation("reclaimed-leases")) {
305 stats_mgr.setValue("reclaimed-leases", zero);
306 }
307
308 // Create if it does not exit cumulative nas global stats.
309 if (!stats_mgr.getObservation("cumulative-assigned-nas")) {
310 stats_mgr.setValue("cumulative-assigned-nas", zero);
311 }
312
313 // Create if it does not exit cumulative pds global stats.
314 if (!stats_mgr.getObservation("cumulative-assigned-pds")) {
315 stats_mgr.setValue("cumulative-assigned-pds", zero);
316 }
317
318 // Create if it does not exit cumulative registered nas global stats.
319 if (!stats_mgr.getObservation("cumulative-registered-nas")) {
320 stats_mgr.setValue("cumulative-registered-nas", zero);
321 }
322
323 // Clear subnet level stats. This ensures we don't end up with corner
324 // cases that leave stale values in place.
325 const Subnet6Collection* subnets =
326 CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
327
328 for (auto const& subnet : *subnets) {
329 SubnetID subnet_id = subnet->getID();
330 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
331 "assigned-nas"),
332 zero);
333
334 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
335 "assigned-pds"),
336 zero);
337
338 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
339 "declined-addresses"),
340 zero);
341
342 if (!stats_mgr.getObservation(
343 StatsMgr::generateName("subnet", subnet_id,
344 "reclaimed-declined-addresses"))) {
345 stats_mgr.setValue(
346 StatsMgr::generateName("subnet", subnet_id,
347 "reclaimed-declined-addresses"),
348 zero);
349 }
350
351 if (!stats_mgr.getObservation(
352 StatsMgr::generateName("subnet", subnet_id,
353 "reclaimed-leases"))) {
354 stats_mgr.setValue(
355 StatsMgr::generateName("subnet", subnet_id,
356 "reclaimed-leases"),
357 zero);
358 }
359
360 if (!stats_mgr.getObservation(
361 StatsMgr::generateName("subnet", subnet_id,
362 "registered-nas"))) {
363 stats_mgr.setValue(
364 StatsMgr::generateName("subnet", subnet_id,
365 "registered-nas"),
366 zero);
367 }
368
369 for (auto const& pool : subnet->getPools(Lease::TYPE_NA)) {
370 const std::string& name_anas(StatsMgr::generateName("subnet", subnet_id,
371 StatsMgr::generateName("pool", pool->getID(),
372 "assigned-nas")));
373 if (!stats_mgr.getObservation(name_anas)) {
374 stats_mgr.setValue(name_anas, zero);
375 }
376
377 const std::string& name_da(StatsMgr::generateName("subnet", subnet_id,
378 StatsMgr::generateName("pool", pool->getID(),
379 "declined-addresses")));
380 if (!stats_mgr.getObservation(name_da)) {
381 stats_mgr.setValue(name_da, zero);
382 }
383
384 const std::string name_rec_dec(StatsMgr::generateName("subnet", subnet_id,
385 StatsMgr::generateName("pool", pool->getID(),
386 "reclaimed-declined-addresses")));
387 if (!stats_mgr.getObservation(name_rec_dec)) {
388 stats_mgr.setValue(name_rec_dec, zero);
389 }
390
391 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
392 StatsMgr::generateName("pool", pool->getID(),
393 "reclaimed-leases")));
394 if (!stats_mgr.getObservation(name_rec)) {
395 stats_mgr.setValue(name_rec, zero);
396 }
397 }
398
399 for (auto const& pool : subnet->getPools(Lease::TYPE_PD)) {
400 const std::string& name_apds(StatsMgr::generateName("subnet", subnet_id,
401 StatsMgr::generateName("pd-pool", pool->getID(),
402 "assigned-pds")));
403 if (!stats_mgr.getObservation(name_apds)) {
404 stats_mgr.setValue(name_apds, zero);
405 }
406
407 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
408 StatsMgr::generateName("pd-pool", pool->getID(),
409 "reclaimed-leases")));
410 if (!stats_mgr.getObservation(name_rec)) {
411 stats_mgr.setValue(name_rec, zero);
412 }
413 }
414 }
415
416 // Get counts per state per subnet. Iterate over the result set
417 // updating the subnet and global values.
418 LeaseStatsRow row;
419 while (query->getNextRow(row)) {
420 switch(row.lease_type_) {
421 case Lease::TYPE_NA:
423 // Add to subnet level value.
424 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
425 "assigned-nas"),
426 row.state_count_);
427 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
428 // Set subnet level value.
429 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
430 "declined-addresses"),
431 row.state_count_);
432
433 // Add to the global value.
434 stats_mgr.addValue("declined-addresses", row.state_count_);
435
436 // Add to subnet level value.
437 // Declined leases also count as assigned.
438 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
439 "assigned-nas"),
440 row.state_count_);
441 } else if (row.lease_state_ == Lease::STATE_REGISTERED) {
442 // Add to subnet level value
443 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
444 "registered-nas"),
445 row.state_count_);
446 }
447 break;
448
449 case Lease::TYPE_PD:
451 // Set subnet level value.
452 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
453 "assigned-pds"),
454 row.state_count_);
455 }
456 break;
457
458 default:
459 // We don't support TYPE_TAs yet
460 break;
461 }
462 }
463
465 if (!query) {
467 return;
468 }
469
470 // Get counts per state per subnet and pool. Iterate over the result set
471 // updating the subnet and pool and global values.
472 while (query->getNextRow(row)) {
473 switch(row.lease_type_) {
474 case Lease::TYPE_NA:
476 // Add to subnet and pool level value.
477 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
478 StatsMgr::generateName("pool", row.pool_id_,
479 "assigned-nas")),
480 row.state_count_);
481 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
482 // Set subnet and pool level value.
483 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
484 StatsMgr::generateName("pool", row.pool_id_,
485 "declined-addresses")),
486 row.state_count_);
487
488 // Add to subnet and pool level value.
489 // Declined leases also count as assigned.
490 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
491 StatsMgr::generateName("pool", row.pool_id_,
492 "assigned-nas")),
493 row.state_count_);
494 }
495 break;
496
497 case Lease::TYPE_PD:
499 // Set subnet and pool level value.
500 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
501 StatsMgr::generateName("pd-pool", row.pool_id_,
502 "assigned-pds")),
503 row.state_count_);
504 }
505 break;
506
507 default:
508 // We don't support TYPE_TAs yet
509 break;
510 }
511 }
512}
513
518
523
526 return(LeaseStatsQueryPtr());
527}
528
531 const SubnetID& /* last_subnet_id */) {
532 return(LeaseStatsQueryPtr());
533}
534
535std::string
537 isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called");
538}
539
540void
542 std::string extended_info_tables;
543 try {
544 extended_info_tables = parameters.at("extended-info-tables");
545 } catch (const exception&) {
546 extended_info_tables = "false";
547 }
548 // If extended_info_tables is 'true' we will enable them.
549 if (extended_info_tables == "true") {
551 }
552}
553
554bool
558
559 bool changed = false;
560 if (!lease) {
561 return (changed);
562 }
563
565 return (changed);
566 }
567
568 ConstElementPtr user_context = lease->getContext();
569 if (!user_context) {
570 return (changed);
571 }
572
574 ConstElementPtr extended_info;
575 ElementPtr mutable_user_context;
576 ElementPtr mutable_isc;
577 string verifying = "";
578 bool removed_extended_info = false;
579
580 try {
581 verifying = "user context";
582 if (user_context->getType() != Element::map) {
583 isc_throw(BadValue, "user context is not a map");
584 }
585 if (user_context->empty()) {
586 changed = true;
587 lease->setContext(ConstElementPtr());
588 return (changed);
589 }
590
591 verifying = "isc";
592 isc = user_context->get("ISC");
593 if (!isc) {
594 return (changed);
595 }
596 mutable_user_context =
597 boost::const_pointer_cast<Element>(user_context);
598 if (!mutable_user_context) {
599 // Should not happen...
600 mutable_user_context = copy(user_context, 0);
601 lease->setContext(mutable_user_context);
602 }
603
604 if (isc->getType() != Element::map) {
605 isc_throw(BadValue, "ISC entry is not a map");
606 }
607 if (isc->empty()) {
608 changed = true;
609 mutable_user_context->remove("ISC");
610 if (mutable_user_context->empty()) {
611 lease->setContext(ConstElementPtr());
612 }
613 return (changed);
614 }
615
616 verifying = "relay-agent-info";
617 extended_info = isc->get("relay-agent-info");
618 if (!extended_info) {
619 return (changed);
620 }
621 mutable_isc = boost::const_pointer_cast<Element>(isc);
622 if (!mutable_isc) {
623 // Should not happen...
624 mutable_isc = copy(isc, 0);
625 mutable_user_context->set("ISC", mutable_isc);
626 }
627
628 if (extended_info->getType() == Element::string) {
629 // Upgrade
630 changed = true;
631 ElementPtr upgraded = Element::createMap();
632 upgraded->set("sub-options", extended_info);
633 mutable_isc->set("relay-agent-info", upgraded);
634
635 // Try to decode sub-options.
636 verifying = "rai";
637 string rai_hex = extended_info->stringValue();
638 vector<uint8_t> rai_data;
639 str::decodeFormattedHexString(rai_hex, rai_data);
640 OptionCustomPtr rai(new OptionCustom(rai_def, Option::V4, rai_data));
641 if (!rai) {
642 isc_throw(BadValue, "can't create RAI option");
643 }
644
645 OptionPtr remote_id = rai->getOption(RAI_OPTION_REMOTE_ID);
646 if (remote_id) {
647 vector<uint8_t> bytes = remote_id->toBinary();
648 if (bytes.size() > 0) {
649 upgraded->set("remote-id",
651 }
652 }
653
654 OptionPtr relay_id = rai->getOption(RAI_OPTION_RELAY_ID);
655 if (relay_id) {
656 vector<uint8_t> bytes = relay_id->toBinary(false);
657 if (bytes.size() > 0) {
658 upgraded->set("relay-id",
660 }
661 }
662
665 .arg(lease->addr_.toText());
666 return (changed);
667 } else if (extended_info->getType() != Element::map) {
668 mutable_isc->remove("relay-agent-info");
669 removed_extended_info = true;
670 isc_throw(BadValue, "relay-agent-info is not a map or a string");
671 }
672
674 return (changed);
675 }
676
677 // Try to decode sub-options.
678 ConstElementPtr sub_options = extended_info->get("sub-options");
679 if (sub_options) {
680 verifying = "sub-options";
681 if (sub_options->getType() != Element::string) {
682 mutable_isc->remove("relay-agent-info");
683 removed_extended_info = true;
684 isc_throw(BadValue, "sub-options is not a string");
685 }
686 string rai_hex = sub_options->stringValue();
687 vector<uint8_t> rai_data;
688 str::decodeFormattedHexString(rai_hex, rai_data);
689 }
690
691 ConstElementPtr remote_id = extended_info->get("remote-id");
692 if (remote_id) {
693 verifying = "remote-id";
694 if (remote_id->getType() != Element::string) {
695 mutable_isc->remove("relay-agent-info");
696 removed_extended_info = true;
697 isc_throw(BadValue, "remote-id is not a string");
698 }
699 string remote_id_hex = remote_id->stringValue();
700 vector<uint8_t> remote_id_data;
701 encode::decodeHex(remote_id_hex, remote_id_data);
702 if (remote_id_data.empty()) {
703 mutable_isc->remove("relay-agent-info");
704 removed_extended_info = true;
705 isc_throw(BadValue, "remote-id is empty");
706 }
707 }
708
709 ConstElementPtr relay_id = extended_info->get("relay-id");
710 if (relay_id) {
711 verifying = "relay-id";
712 if (relay_id->getType() != Element::string) {
713 mutable_isc->remove("relay-agent-info");
714 removed_extended_info = true;
715 isc_throw(BadValue, "relay-id is not a string");
716 }
717 string relay_id_hex = relay_id->stringValue();
718 vector<uint8_t> relay_id_data;
719 encode::decodeHex(relay_id_hex, relay_id_data);
720 if (relay_id_data.empty()) {
721 mutable_isc->remove("relay-agent-info");
722 removed_extended_info = true;
723 isc_throw(BadValue, "relay-id is empty");
724 }
725 }
726
728 return (changed);
729 }
730
731 verifying = "relay-agent-info";
732 for (auto const& elem : extended_info->mapValue()) {
733 if ((elem.first != "sub-options") &&
734 (elem.first != "remote-id") &&
735 (elem.first != "relay-id") &&
736 (elem.first != "comment")) {
737 mutable_isc->remove("relay-agent-info");
738 removed_extended_info = true;
739 isc_throw(BadValue, "spurious '" << elem.first <<
740 "' entry in relay-agent-info");
741 }
742 }
743
744 return (changed);
745 } catch (const exception& ex) {
746 ostringstream err;
747 err << "in " << verifying << " a problem was found: " << ex.what();
749 .arg(lease->addr_.toText())
750 .arg(err.str());
751
752 changed = true;
753 if (verifying == "user context") {
754 lease->setContext(ConstElementPtr());
755 } else if (verifying == "isc") {
756 mutable_user_context->remove("ISC");
757 if (mutable_user_context->empty()) {
758 lease->setContext(ConstElementPtr());
759 }
760 } else {
761 if (!removed_extended_info) {
762 mutable_isc->remove("relay-agent-info");
763 }
764 if (mutable_isc->empty()) {
765 mutable_user_context->remove("ISC");
766 if (mutable_user_context->empty()) {
767 lease->setContext(ConstElementPtr());
768 }
769 }
770 }
771 return (changed);
772 }
773}
774
775bool
778 bool changed = false;
779 if (!lease) {
780 return (changed);
781 }
782
784 return (changed);
785 }
786
787 ConstElementPtr user_context = lease->getContext();
788 if (!user_context) {
789 return (changed);
790 }
791
793 ConstElementPtr relay_info;
794 ElementPtr mutable_user_context;
795 ElementPtr mutable_isc;
796 string verifying = "";
797 bool removed_relay_info = false;
798 bool upgraded = false;
799 bool have_both = false;
800 int i = -1;
801
802 try {
803 verifying = "user context";
804 if (user_context->getType() != Element::map) {
805 isc_throw(BadValue, "user context is not a map");
806 }
807 if (user_context->empty()) {
808 changed = true;
809 lease->setContext(ConstElementPtr());
810 return (changed);
811 }
812
813 verifying = "isc";
814 isc = user_context->get("ISC");
815 if (!isc) {
816 return (changed);
817 }
818 mutable_user_context =
819 boost::const_pointer_cast<Element>(user_context);
820 if (!mutable_user_context) {
821 // Should not happen...
822 mutable_user_context = copy(user_context, 0);
823 lease->setContext(mutable_user_context);
824 }
825
826 if (isc->getType() != Element::map) {
827 isc_throw(BadValue, "ISC entry is not a map");
828 }
829 if (isc->empty()) {
830 changed = true;
831 mutable_user_context->remove("ISC");
832 if (mutable_user_context->empty()) {
833 lease->setContext(ConstElementPtr());
834 }
835 return (changed);
836 }
837 mutable_isc = boost::const_pointer_cast<Element>(isc);
838 if (!mutable_isc) {
839 // Should not happen...
840 mutable_isc = copy(isc, 0);
841 mutable_user_context->set("ISC", mutable_isc);
842 }
843
844 relay_info = mutable_isc->get("relays");
845 if (relay_info && isc->contains("relay-info")) {
846 changed = true;
847 mutable_isc->remove("relays");
848 have_both = true;
849 relay_info.reset();
850 }
851 if (relay_info) {
852 // Upgrade
853 changed = true;
854 upgraded = true;
855 verifying = "relays";
856 mutable_isc->set("relay-info", relay_info);
857 mutable_isc->remove("relays");
858
859 if (relay_info->getType() != Element::list) {
860 mutable_isc->remove("relay-info");
861 removed_relay_info = true;
862 isc_throw(BadValue, "relays is not a list");
863 }
864 if (relay_info->empty()) {
865 mutable_isc->remove("relay-info");
866 removed_relay_info = true;
867 isc_throw(BadValue, "relays is empty");
868 }
869
870 verifying = "relay";
871 for (i = 0; static_cast<size_t>(i) < relay_info->size(); ++i) {
872 ElementPtr relay = relay_info->getNonConst(i);
873 if (!relay) {
874 mutable_isc->remove("relay-info");
875 removed_relay_info = true;
876 isc_throw(BadValue, "null relay#" << i);
877 }
878 if (relay->getType() != Element::map) {
879 mutable_isc->remove("relay-info");
880 removed_relay_info = true;
881 isc_throw(BadValue, "relay#" << i << " is not a map");
882 }
883
884 // Try to decode options.
885 ConstElementPtr options = relay->get("options");
886 if (!options) {
887 continue;
888 }
889
890 verifying = "options";
891 if (options->getType() != Element::string) {
892 mutable_isc->remove("relay-info");
893 removed_relay_info = true;
894 isc_throw(BadValue, "options is not a string");
895 }
896 string options_hex = options->stringValue();
897 vector<uint8_t> options_data;
898 str::decodeFormattedHexString(options_hex, options_data);
899 OptionCollection opts;
900 LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
901
902 auto remote_id_it = opts.find(D6O_REMOTE_ID);
903 if (remote_id_it != opts.end()) {
904 OptionPtr remote_id = remote_id_it->second;
905 if (remote_id) {
906 vector<uint8_t> bytes = remote_id->toBinary();
907 if (bytes.size() > 0) {
908 relay->set("remote-id",
910 }
911 }
912 }
913
914 auto relay_id_it = opts.find(D6O_RELAY_ID);
915 if (relay_id_it != opts.end()) {
916 OptionPtr relay_id = relay_id_it->second;
917 if (relay_id) {
918 vector<uint8_t> bytes = relay_id->toBinary(false);
919 if (bytes.size() > 0) {
920 relay->set("relay-id",
922 }
923 }
924 }
925 }
926 }
927
928 verifying = (upgraded ? "relays" : "relay-info");
929 i = -1;
930 relay_info = mutable_isc->get("relay-info");
931 if (!relay_info) {
932 return (changed);
933 }
934 if (!upgraded && (relay_info->getType() != Element::list)) {
935 mutable_isc->remove("relay-info");
936 removed_relay_info = true;
937 isc_throw(BadValue, "relay-info is not a list");
938 }
939 if (!upgraded && relay_info->empty()) {
940 mutable_isc->remove("relay-info");
941 removed_relay_info = true;
942 isc_throw(BadValue, "relay-info is empty");
943 }
944
945 verifying = "relay";
946 for (i = 0; static_cast<size_t>(i) < relay_info->size(); ++i) {
947 ElementPtr relay = relay_info->getNonConst(i);
948 if (!upgraded && !relay) {
949 mutable_isc->remove("relay-info");
950 removed_relay_info = true;
951 isc_throw(BadValue, "null relay#" << i);
952 }
953 if (!upgraded && (relay->getType() != Element::map)) {
954 mutable_isc->remove("relay-info");
955 removed_relay_info = true;
956 isc_throw(BadValue, "relay#" << i << " is not a map");
957 }
958
959 ConstElementPtr options = relay->get("options");
960 if (!upgraded && options) {
961 // Try to decode options.
962 verifying = "options";
963 if (options->getType() != Element::string) {
964 mutable_isc->remove("relay-info");
965 removed_relay_info = true;
966 isc_throw(BadValue, "options is not a string");
967 }
968 string options_hex = options->stringValue();
969 vector<uint8_t> options_data;
970 str::decodeFormattedHexString(options_hex, options_data);
971 OptionCollection opts;
972 LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
973 }
975 continue;
976 }
977
978 verifying = "link";
979 ConstElementPtr link_addr = relay->get("link");
980 if (!link_addr) {
981 mutable_isc->remove("relay-info");
982 removed_relay_info = true;
983 isc_throw(BadValue, "no link");
984 }
985 if (link_addr->getType() != Element::string) {
986 mutable_isc->remove("relay-info");
987 removed_relay_info = true;
988 isc_throw(BadValue, "link is not a string");
989 }
990 IOAddress laddr(link_addr->stringValue());
991 if (!laddr.isV6()) {
992 mutable_isc->remove("relay-info");
993 removed_relay_info = true;
994 isc_throw(BadValue, "link is not an IPv6 address");
995 }
996
997 ConstElementPtr remote_id = relay->get("remote-id");
998 if (!upgraded && remote_id) {
999 verifying = "remote-id";
1000 if (remote_id->getType() != Element::string) {
1001 mutable_isc->remove("relay-info");
1002 removed_relay_info = true;
1003 isc_throw(BadValue, "remote-id is not a string");
1004 }
1005 string remote_id_hex = remote_id->stringValue();
1006 vector<uint8_t> remote_id_data;
1007 encode::decodeHex(remote_id_hex, remote_id_data);
1008 if (remote_id_data.empty()) {
1009 mutable_isc->remove("relay-info");
1010 removed_relay_info = true;
1011 isc_throw(BadValue, "remote-id is empty");
1012 }
1013 }
1014
1015 ConstElementPtr relay_id = relay->get("relay-id");
1016 if (!upgraded && relay_id) {
1017 verifying = "relay-id";
1018 if (relay_id->getType() != Element::string) {
1019 mutable_isc->remove("relay-info");
1020 removed_relay_info = true;
1021 isc_throw(BadValue, "relay-id is not a string");
1022 }
1023 string relay_id_hex = relay_id->stringValue();
1024 vector<uint8_t> relay_id_data;
1025 encode::decodeHex(relay_id_hex, relay_id_data);
1026 if (relay_id_data.empty()) {
1027 mutable_isc->remove("relay-info");
1028 removed_relay_info = true;
1029 isc_throw(BadValue, "relay-id is empty");
1030 }
1031 }
1032
1034 continue;
1035 }
1036
1037 verifying = "peer";
1038 ConstElementPtr peer_addr = relay->get("peer");
1039 if (!peer_addr) {
1040 mutable_isc->remove("relay-info");
1041 removed_relay_info = true;
1042 isc_throw(BadValue, "no peer");
1043 }
1044 if (peer_addr->getType() != Element::string) {
1045 mutable_isc->remove("relay-info");
1046 removed_relay_info = true;
1047 isc_throw(BadValue, "peer is not a string");
1048 }
1049 IOAddress paddr(peer_addr->stringValue());
1050 if (!paddr.isV6()) {
1051 mutable_isc->remove("relay-info");
1052 removed_relay_info = true;
1053 isc_throw(BadValue, "peer is not an IPv6 address");
1054 }
1055
1056 verifying = "hop";
1057 ConstElementPtr hop = relay->get("hop");
1058 if (!hop) {
1059 mutable_isc->remove("relay-info");
1060 removed_relay_info = true;
1061 isc_throw(BadValue, "no hop");
1062 }
1063 if (hop->getType() != Element::integer) {
1064 mutable_isc->remove("relay-info");
1065 removed_relay_info = true;
1066 isc_throw(BadValue, "hop is not an integer");
1067 }
1068
1069 verifying = (upgraded ? "relays" : "relay-info");
1070 for (auto const& elem : relay->mapValue()) {
1071 if ((elem.first != "hop") &&
1072 (elem.first != "link") &&
1073 (elem.first != "peer") &&
1074 (elem.first != "options") &&
1075 (elem.first != "remote-id") &&
1076 (elem.first != "relay-id") &&
1077 (elem.first != "comment")) {
1078 mutable_isc->remove("relay-info");
1079 removed_relay_info = true;
1080 isc_throw(BadValue, "spurious '" << elem.first << "' entry");
1081 }
1082 }
1083 }
1084
1085 if (upgraded) {
1088 .arg(lease->addr_.toText());
1089 }
1090
1091 return (changed);
1092 } catch (const exception& ex) {
1093 ostringstream err;
1094 err << "in " << verifying;
1095 if (i >= 0) {
1096 err << " [relay#" << i << "]";
1097 }
1098 err << " a problem was found: " << ex.what();
1100 .arg(lease->addr_.toText())
1101 .arg(err.str());
1102
1103 changed = true;
1104 have_both = !have_both;
1105 if (verifying == "user context") {
1106 lease->setContext(ConstElementPtr());
1107 } else if (verifying == "isc") {
1108 mutable_user_context->remove("ISC");
1109 if (mutable_user_context->empty()) {
1110 lease->setContext(ConstElementPtr());
1111 }
1112 } else {
1113 if (!removed_relay_info) {
1114 mutable_isc->remove("relay-info");
1115 }
1116 if (mutable_isc->empty()) {
1117 mutable_user_context->remove("ISC");
1118 if (mutable_user_context->empty()) {
1119 lease->setContext(ConstElementPtr());
1120 }
1121 }
1122 }
1123 return (changed);
1124 }
1125}
1126
1127void
1129 bool ignore_errors) {
1130 if (!lease) {
1131 return;
1132 }
1133
1134 ConstElementPtr user_context = lease->getContext();
1135 if (!user_context) {
1136 return;
1137 }
1138 if (user_context->getType() != Element::map) {
1139 if (ignore_errors) {
1140 return;
1141 }
1142 isc_throw(BadValue, "user context is not a map");
1143 }
1144 if (user_context->empty()) {
1145 return;
1146 }
1147
1148 ConstElementPtr isc = user_context->get("ISC");
1149 if (!isc) {
1150 return;
1151 }
1152 if (isc->getType() != Element::map) {
1153 if (ignore_errors) {
1154 return;
1155 }
1156 isc_throw(BadValue, "ISC entry is not a map");
1157 }
1158 if (isc->empty()) {
1159 return;
1160 }
1161
1162 ConstElementPtr extended_info = isc->get("relay-agent-info");
1163 if (!extended_info) {
1164 return;
1165 }
1166 if (extended_info->getType() != Element::map) {
1167 if (ignore_errors) {
1168 return;
1169 }
1170 isc_throw(BadValue, "relay-agent-info is not a map");
1171 }
1172 if (extended_info->empty()) {
1173 return;
1174 }
1175
1176 ConstElementPtr relay_id = extended_info->get("relay-id");
1177 if (relay_id) {
1178 if (relay_id->getType() == Element::string) {
1179 vector<uint8_t> bytes;
1180 try {
1181 encode::decodeHex(relay_id->stringValue(), bytes);
1182 } catch (...) {
1183 // Decode failed
1184 if (!ignore_errors) {
1185 throw;
1186 }
1187 }
1188 lease->relay_id_ = bytes;
1189 } else if (!ignore_errors) {
1190 isc_throw(BadValue, "relay-id entry is not a string");
1191 }
1192 }
1193
1194 ConstElementPtr remote_id = extended_info->get("remote-id");
1195 if (remote_id) {
1196 if (remote_id->getType() == Element::string) {
1197 vector<uint8_t> bytes;
1198 try {
1199 encode::decodeHex(remote_id->stringValue(), bytes);
1200 } catch (...) {
1201 // Decode failed
1202 if (!ignore_errors) {
1203 throw;
1204 }
1205 }
1206 lease->remote_id_ = bytes;
1207 } else if (!ignore_errors) {
1208 isc_throw(BadValue, "remote-id entry is not a string");
1209 }
1210 }
1211}
1212
1213bool
1215
1216 bool added = false;
1217 if (!lease) {
1218 return (added);
1219 }
1220
1221 ConstElementPtr user_context = lease->getContext();
1222 if (!user_context || (user_context->getType() != Element::map) ||
1223 user_context->empty()) {
1224 return (added);
1225 }
1226
1227 ConstElementPtr isc = user_context->get("ISC");
1228 if (!isc || (isc->getType() != Element::map) || isc->empty()) {
1229 return (added);
1230 }
1231
1232 ConstElementPtr relay_info = isc->get("relay-info");
1233 if (!relay_info || (relay_info->getType() != Element::list) ||
1234 relay_info->empty()) {
1235 return (added);
1236 }
1237
1238 for (unsigned i = 0; i < relay_info->size(); ++i) {
1239 ConstElementPtr relay = relay_info->get(i);
1240 if (!relay || (relay->getType() != Element::map) || relay->empty()) {
1241 continue;
1242 }
1243 try {
1244 ConstElementPtr relay_id = relay->get("relay-id");
1245 if (relay_id) {
1246 string relay_id_hex = relay_id->stringValue();
1247 vector<uint8_t> relay_id_data;
1248 encode::decodeHex(relay_id_hex, relay_id_data);
1249 if (relay_id_data.empty()) {
1250 continue;
1251 }
1252 addRelayId6(lease->addr_, relay_id_data);
1253 added = true;
1254 }
1255
1256 ConstElementPtr remote_id = relay->get("remote-id");
1257 if (remote_id) {
1258 string remote_id_hex = remote_id->stringValue();
1259 vector<uint8_t> remote_id_data;
1260 encode::decodeHex(remote_id_hex, remote_id_data);
1261 if (remote_id_data.empty()) {
1262 continue;
1263 }
1264 addRemoteId6(lease->addr_, remote_id_data);
1265 added = true;
1266 }
1267 } catch (const exception&) {
1268 continue;
1269 }
1270 }
1271 return (added);
1272}
1273
1274size_t
1276 return (0);
1277}
1278
1279size_t
1281 return (0);
1282}
1283
1284} // namespace isc::dhcp
1285} // 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...
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.
ExtendedInfoSanity
Values for extended info sanity checks done for leases.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:28
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:115
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:525
virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets and pools.
Definition lease_mgr.cc:520
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:1020
virtual size_t byRelayId6size() const
Return the by-relay-id table size.
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:776
virtual size_t byRemoteId6size() const
Return the by-remote-id table size.
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:536
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:530
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.
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:555
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.
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets.
Definition lease_mgr.cc:515
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 const OptionDefinition & DHO_DHCP_AGENT_OPTIONS_DEF()
Get definition of DHO_DHCP_AGENT_OPTIONS option.
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:317
Option with defined data fields represented as buffers that can be accessed using data field index.
Base class representing a DHCP option definition.
@ 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
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:528
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition lease.h:693
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:937
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
Definition option.h:40
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:866
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition subnet_id.h:25
@ RAI_OPTION_RELAY_ID
Definition dhcp4.h:276
@ RAI_OPTION_REMOTE_ID
Definition dhcp4.h:266
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:315
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 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
static const uint32_t STATE_REGISTERED
Registered self-generated lease.
Definition lease.h:81