Kea 3.1.3
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
10#include <dhcp/libdhcp++.h>
11#include <dhcp/option_custom.h>
12#include <dhcpsrv/cfgmgr.h>
13#include <dhcpsrv/dhcpsrv_log.h>
14#include <dhcpsrv/lease_mgr.h>
16#include <stats/stats_mgr.h>
17#include <util/encode/encode.h>
18#include <util/str.h>
19
20#include <boost/algorithm/string.hpp>
21
22#include <algorithm>
23#include <iostream>
24#include <iterator>
25#include <limits>
26#include <map>
27#include <sstream>
28#include <string>
29
30#include <time.h>
31
32using namespace isc::asiolink;
33using namespace isc::config;
34using namespace isc::data;
35using namespace isc::db;
36using namespace isc::dhcp;
37using namespace isc::util;
38using namespace std;
39
40namespace isc {
41namespace dhcp {
42
43LeasePageSize::LeasePageSize(const size_t page_size)
44 : page_size_(page_size) {
45
46 if (page_size_ == 0) {
47 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
48 }
49
50 if (page_size_ > std::numeric_limits<uint32_t>::max()) {
51 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
52 << std::numeric_limits<uint32_t>::max());
53 }
54}
55
58 uint32_t iaid, SubnetID subnet_id) const {
59 Lease6Collection col = getLeases6(type, duid, iaid, subnet_id);
60
61 if (col.size() > 1) {
62 isc_throw(MultipleRecords, "More than one lease found for type "
63 << static_cast<int>(type) << ", duid "
64 << duid.toText() << ", iaid " << iaid
65 << " and subnet-id " << subnet_id);
66 }
67 if (col.empty()) {
68 return (Lease6Ptr());
69 }
70 return (*col.begin());
71}
72
73void
75 using namespace stats;
76
77 StatsMgr& stats_mgr = StatsMgr::instance();
78
80 if (!query) {
82 return;
83 }
84
85 // Zero out the global stats.
86 // Cumulative counters ("reclaimed-declined-addresses", "reclaimed-leases",
87 // "cumulative-assigned-addresses") never get zeroed.
88 int64_t zero = 0;
89
90 stats_mgr.setValue("assigned-addresses", zero);
91
92 stats_mgr.setValue("declined-addresses", zero);
93
94 // Create if it does not exit reclaimed declined leases global stats.
95 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
96 stats_mgr.setValue("reclaimed-declined-addresses", zero);
97 }
98
99 // Create if it does not exit reclaimed leases global stats.
100 if (!stats_mgr.getObservation("reclaimed-leases")) {
101 stats_mgr.setValue("reclaimed-leases", zero);
102 }
103
104 // Create if it does not exit cumulative global stats.
105 if (!stats_mgr.getObservation("cumulative-assigned-addresses")) {
106 stats_mgr.setValue("cumulative-assigned-addresses", zero);
107 }
108
109 // Clear subnet level stats. This ensures we don't end up with corner
110 // cases that leave stale values in place.
111 const Subnet4Collection* subnets =
112 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
113
114 for (auto const& subnet : *subnets) {
115 SubnetID subnet_id = subnet->getID();
116 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
117 "assigned-addresses"),
118 zero);
119
120 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
121 "declined-addresses"),
122 zero);
123
124 const std::string name_rec_dec(StatsMgr::generateName("subnet", subnet_id,
125 "reclaimed-declined-addresses"));
126 if (!stats_mgr.getObservation(name_rec_dec)) {
127 stats_mgr.setValue(name_rec_dec, zero);
128 }
129
130 const std::string name_rec(StatsMgr::generateName("subnet", subnet_id,
131 "reclaimed-leases"));
132 if (!stats_mgr.getObservation(name_rec)) {
133 stats_mgr.setValue(name_rec, zero);
134 }
135
136 for (auto const& pool : subnet->getPools(Lease::TYPE_V4)) {
137 const std::string name_aa(StatsMgr::generateName("subnet", subnet_id,
138 StatsMgr::generateName("pool", pool->getID(),
139 "assigned-addresses")));
140 if (!stats_mgr.getObservation(name_aa)) {
141 stats_mgr.setValue(name_aa, zero);
142 }
143
144 const std::string& name_da(StatsMgr::generateName("subnet", subnet_id,
145 StatsMgr::generateName("pool", pool->getID(),
146 "declined-addresses")));
147 if (!stats_mgr.getObservation(name_da)) {
148 stats_mgr.setValue(name_da, zero);
149 }
150
151 const std::string& pname_rec_dec(StatsMgr::generateName("subnet", subnet_id,
152 StatsMgr::generateName("pool", pool->getID(),
153 "reclaimed-declined-addresses")));
154 if (!stats_mgr.getObservation(pname_rec_dec)) {
155 stats_mgr.setValue(pname_rec_dec, zero);
156 }
157
158 const std::string& pname_rec(StatsMgr::generateName("subnet", subnet_id,
159 StatsMgr::generateName("pool", pool->getID(),
160 "reclaimed-leases")));
161 if (!stats_mgr.getObservation(pname_rec)) {
162 stats_mgr.setValue(pname_rec, zero);
163 }
164 }
165 }
166
167 // Get counts per state per subnet. Iterate over the result set
168 // updating the subnet and global values.
169 LeaseStatsRow row;
170 while (query->getNextRow(row)) {
172 // Add to the global value.
173 stats_mgr.addValue("assigned-addresses", row.state_count_);
174
175 // Add to subnet level value.
176 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
177 "assigned-addresses"),
178 row.state_count_);
179 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
180 // Set subnet level value.
181 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
182 "declined-addresses"),
183 row.state_count_);
184
185 // Add to the global value.
186 stats_mgr.addValue("assigned-addresses", row.state_count_);
187
188 // Add to the global value.
189 stats_mgr.addValue("declined-addresses", row.state_count_);
190
191 // Add to subnet level value.
192 // Declined leases also count as assigned.
193 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
194 "assigned-addresses"),
195 row.state_count_);
196 }
197 }
198
200 if (!query) {
202 return;
203 }
204
205 // Get counts per state per subnet and pool. Iterate over the result set
206 // updating the subnet and pool and global values.
207 while (query->getNextRow(row)) {
209 // Add to subnet and pool level value.
210 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
211 StatsMgr::generateName("pool", row.pool_id_,
212 "assigned-addresses")),
213 row.state_count_);
214 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
215 // Set subnet and pool level value.
216 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
217 StatsMgr::generateName("pool", row.pool_id_,
218 "declined-addresses")),
219 row.state_count_);
220
221 // Add to subnet and pool level value.
222 // Declined leases also count as assigned.
223 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
224 StatsMgr::generateName("pool", row.pool_id_,
225 "assigned-addresses")),
226 row.state_count_);
227 }
228 }
229}
230
232 : first_subnet_id_(0), last_subnet_id_(0), select_mode_(select_mode) {
233 if (select_mode != ALL_SUBNETS && select_mode != ALL_SUBNET_POOLS) {
234 isc_throw(BadValue, "LeaseStatsQuery: mode must be either ALL_SUBNETS or ALL_SUBNET_POOLS");
235 }
236}
237
239 : first_subnet_id_(subnet_id), last_subnet_id_(0),
240 select_mode_(SINGLE_SUBNET) {
241
242 if (first_subnet_id_ == 0) {
243 isc_throw(BadValue, "LeaseStatsQuery: subnet_id_ must be > 0");
244 }
245}
246
248 const SubnetID& last_subnet_id)
249 : first_subnet_id_(first_subnet_id), last_subnet_id_(last_subnet_id),
250 select_mode_(SUBNET_RANGE) {
251
252 if (first_subnet_id_ == 0) {
253 isc_throw(BadValue, "LeaseStatsQuery: first_subnet_id_ must be > 0");
254 }
255
256 if (last_subnet_id_ == 0) {
257 isc_throw(BadValue, "LeaseStatsQuery: last_subnet_id_ must be > 0");
258 }
259
262 "LeaseStatsQuery: last_subnet_id_must be > first_subnet_id_");
263 }
264}
265
270
275
278 return(LeaseStatsQueryPtr());
279}
280
283 const SubnetID& /* last_subnet_id */) {
284 return(LeaseStatsQueryPtr());
285}
286
287bool
289 return (false);
290}
291
292void
294 using namespace stats;
295
296 StatsMgr& stats_mgr = StatsMgr::instance();
297
299 if (!query) {
301 return;
302 }
303
304 // Zero out the global stats.
305 // Cumulative counters ("reclaimed-declined-addresses", "reclaimed-leases",
306 // "cumulative-assigned-nas", "cumulative-assigned-pds",
307 // "cumulative-registered-nas")) never get zeroed.
308 int64_t zero = 0;
309
310 stats_mgr.setValue("assigned-nas", zero);
311
312 stats_mgr.setValue("assigned-pds", zero);
313
314 stats_mgr.setValue("declined-addresses", zero);
315
316 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
317 stats_mgr.setValue("reclaimed-declined-addresses", zero);
318 }
319
320 if (!stats_mgr.getObservation("reclaimed-leases")) {
321 stats_mgr.setValue("reclaimed-leases", zero);
322 }
323
324 // Create if it does not exit cumulative nas global stats.
325 if (!stats_mgr.getObservation("cumulative-assigned-nas")) {
326 stats_mgr.setValue("cumulative-assigned-nas", zero);
327 }
328
329 // Create if it does not exit cumulative pds global stats.
330 if (!stats_mgr.getObservation("cumulative-assigned-pds")) {
331 stats_mgr.setValue("cumulative-assigned-pds", zero);
332 }
333
334 // Create if it does not exit cumulative registered nas global stats.
335 if (!stats_mgr.getObservation("cumulative-registered-nas")) {
336 stats_mgr.setValue("cumulative-registered-nas", zero);
337 }
338
339 // Clear subnet level stats. This ensures we don't end up with corner
340 // cases that leave stale values in place.
341 const Subnet6Collection* subnets =
342 CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
343
344 for (auto const& subnet : *subnets) {
345 SubnetID subnet_id = subnet->getID();
346 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
347 "assigned-nas"),
348 zero);
349
350 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
351 "assigned-pds"),
352 zero);
353
354 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
355 "declined-addresses"),
356 zero);
357
358 if (!stats_mgr.getObservation(
359 StatsMgr::generateName("subnet", subnet_id,
360 "reclaimed-declined-addresses"))) {
361 stats_mgr.setValue(
362 StatsMgr::generateName("subnet", subnet_id,
363 "reclaimed-declined-addresses"),
364 zero);
365 }
366
367 if (!stats_mgr.getObservation(
368 StatsMgr::generateName("subnet", subnet_id,
369 "reclaimed-leases"))) {
370 stats_mgr.setValue(
371 StatsMgr::generateName("subnet", subnet_id,
372 "reclaimed-leases"),
373 zero);
374 }
375
376 if (!stats_mgr.getObservation(
377 StatsMgr::generateName("subnet", subnet_id,
378 "registered-nas"))) {
379 stats_mgr.setValue(
380 StatsMgr::generateName("subnet", subnet_id,
381 "registered-nas"),
382 zero);
383 }
384
385 for (auto const& pool : subnet->getPools(Lease::TYPE_NA)) {
386 const std::string& name_anas(StatsMgr::generateName("subnet", subnet_id,
387 StatsMgr::generateName("pool", pool->getID(),
388 "assigned-nas")));
389 if (!stats_mgr.getObservation(name_anas)) {
390 stats_mgr.setValue(name_anas, zero);
391 }
392
393 const std::string& name_da(StatsMgr::generateName("subnet", subnet_id,
394 StatsMgr::generateName("pool", pool->getID(),
395 "declined-addresses")));
396 if (!stats_mgr.getObservation(name_da)) {
397 stats_mgr.setValue(name_da, zero);
398 }
399
400 const std::string name_rec_dec(StatsMgr::generateName("subnet", subnet_id,
401 StatsMgr::generateName("pool", pool->getID(),
402 "reclaimed-declined-addresses")));
403 if (!stats_mgr.getObservation(name_rec_dec)) {
404 stats_mgr.setValue(name_rec_dec, zero);
405 }
406
407 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
408 StatsMgr::generateName("pool", pool->getID(),
409 "reclaimed-leases")));
410 if (!stats_mgr.getObservation(name_rec)) {
411 stats_mgr.setValue(name_rec, zero);
412 }
413 }
414
415 for (auto const& pool : subnet->getPools(Lease::TYPE_PD)) {
416 const std::string& name_apds(StatsMgr::generateName("subnet", subnet_id,
417 StatsMgr::generateName("pd-pool", pool->getID(),
418 "assigned-pds")));
419 if (!stats_mgr.getObservation(name_apds)) {
420 stats_mgr.setValue(name_apds, zero);
421 }
422
423 const std::string& name_rec(StatsMgr::generateName("subnet", subnet_id,
424 StatsMgr::generateName("pd-pool", pool->getID(),
425 "reclaimed-leases")));
426 if (!stats_mgr.getObservation(name_rec)) {
427 stats_mgr.setValue(name_rec, zero);
428 }
429 }
430 }
431
432 // Get counts per state per subnet. Iterate over the result set
433 // updating the subnet and global values.
434 LeaseStatsRow row;
435 while (query->getNextRow(row)) {
436 switch(row.lease_type_) {
437 case Lease::TYPE_NA:
439 // Add to the global value.
440 stats_mgr.addValue("assigned-nas", row.state_count_);
441
442 // Add to subnet level value.
443 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
444 "assigned-nas"),
445 row.state_count_);
446 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
447 // Set subnet level value.
448 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
449 "declined-addresses"),
450 row.state_count_);
451
452 // Add to the global value.
453 stats_mgr.addValue("assigned-nas", row.state_count_);
454
455 // Add to the global value.
456 stats_mgr.addValue("declined-addresses", row.state_count_);
457
458 // Add to subnet level value.
459 // Declined leases also count as assigned.
460 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
461 "assigned-nas"),
462 row.state_count_);
463 } else if (row.lease_state_ == Lease::STATE_REGISTERED) {
464 // Add to subnet level value
465 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
466 "registered-nas"),
467 row.state_count_);
468 }
469 break;
470
471 case Lease::TYPE_PD:
473 // Add to the global value.
474 stats_mgr.addValue("assigned-pds", row.state_count_);
475
476 // Set subnet level value.
477 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
478 "assigned-pds"),
479 row.state_count_);
480 }
481 break;
482
483 default:
484 // We don't support TYPE_TAs yet
485 break;
486 }
487 }
488
490 if (!query) {
492 return;
493 }
494
495 // Get counts per state per subnet and pool. Iterate over the result set
496 // updating the subnet and pool and global values.
497 while (query->getNextRow(row)) {
498 switch(row.lease_type_) {
499 case Lease::TYPE_NA:
501 // Add to subnet and pool level value.
502 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
503 StatsMgr::generateName("pool", row.pool_id_,
504 "assigned-nas")),
505 row.state_count_);
506 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
507 // Set subnet and pool level value.
508 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
509 StatsMgr::generateName("pool", row.pool_id_,
510 "declined-addresses")),
511 row.state_count_);
512
513 // Add to subnet and pool level value.
514 // Declined leases also count as assigned.
515 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
516 StatsMgr::generateName("pool", row.pool_id_,
517 "assigned-nas")),
518 row.state_count_);
519 }
520 break;
521
522 case Lease::TYPE_PD:
524 // Set subnet and pool level value.
525 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
526 StatsMgr::generateName("pd-pool", row.pool_id_,
527 "assigned-pds")),
528 row.state_count_);
529 }
530 break;
531
532 default:
533 // We don't support TYPE_TAs yet
534 break;
535 }
536 }
537}
538
543
548
551 return(LeaseStatsQueryPtr());
552}
553
556 const SubnetID& /* last_subnet_id */) {
557 return(LeaseStatsQueryPtr());
558}
559
560std::string
562 isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called");
563}
564
565void
567 std::string extended_info_tables;
568 try {
569 extended_info_tables = parameters.at("extended-info-tables");
570 } catch (const exception&) {
571 extended_info_tables = "false";
572 }
573 // If extended_info_tables is 'true' we will enable them.
574 if (extended_info_tables == "true") {
576 }
577}
578
579bool
583
584 bool changed = false;
585 if (!lease) {
586 return (changed);
587 }
588
590 return (changed);
591 }
592
593 ConstElementPtr user_context = lease->getContext();
594 if (!user_context) {
595 return (changed);
596 }
597
599 ConstElementPtr extended_info;
600 ElementPtr mutable_user_context;
601 ElementPtr mutable_isc;
602 string verifying = "";
603 bool removed_extended_info = false;
604
605 try {
606 verifying = "user context";
607 if (user_context->getType() != Element::map) {
608 isc_throw(BadValue, "user context is not a map");
609 }
610 if (user_context->empty()) {
611 changed = true;
612 lease->setContext(ConstElementPtr());
613 return (changed);
614 }
615
616 verifying = "isc";
617 isc = user_context->get("ISC");
618 if (!isc) {
619 return (changed);
620 }
621 mutable_user_context =
622 boost::const_pointer_cast<Element>(user_context);
623 if (!mutable_user_context) {
624 // Should not happen...
625 mutable_user_context = copy(user_context, 0);
626 lease->setContext(mutable_user_context);
627 }
628
629 if (isc->getType() != Element::map) {
630 isc_throw(BadValue, "ISC entry is not a map");
631 }
632 if (isc->empty()) {
633 changed = true;
634 mutable_user_context->remove("ISC");
635 if (mutable_user_context->empty()) {
636 lease->setContext(ConstElementPtr());
637 }
638 return (changed);
639 }
640
641 verifying = "relay-agent-info";
642 extended_info = isc->get("relay-agent-info");
643 if (!extended_info) {
644 return (changed);
645 }
646 mutable_isc = boost::const_pointer_cast<Element>(isc);
647 if (!mutable_isc) {
648 // Should not happen...
649 mutable_isc = copy(isc, 0);
650 mutable_user_context->set("ISC", mutable_isc);
651 }
652
653 if (extended_info->getType() == Element::string) {
654 // Upgrade
655 changed = true;
656 ElementPtr upgraded = Element::createMap();
657 upgraded->set("sub-options", extended_info);
658 mutable_isc->set("relay-agent-info", upgraded);
659
660 // Try to decode sub-options.
661 verifying = "rai";
662 string rai_hex = extended_info->stringValue();
663 vector<uint8_t> rai_data;
664 str::decodeFormattedHexString(rai_hex, rai_data);
665 OptionCustomPtr rai(new OptionCustom(rai_def, Option::V4, rai_data));
666 if (!rai) {
667 isc_throw(BadValue, "can't create RAI option");
668 }
669
670 OptionPtr remote_id = rai->getOption(RAI_OPTION_REMOTE_ID);
671 if (remote_id) {
672 vector<uint8_t> bytes = remote_id->toBinary();
673 if (bytes.size() > 0) {
674 upgraded->set("remote-id",
676 }
677 }
678
679 OptionPtr relay_id = rai->getOption(RAI_OPTION_RELAY_ID);
680 if (relay_id) {
681 vector<uint8_t> bytes = relay_id->toBinary(false);
682 if (bytes.size() > 0) {
683 upgraded->set("relay-id",
685 }
686 }
687
690 .arg(lease->addr_.toText());
691 return (changed);
692 } else if (extended_info->getType() != Element::map) {
693 mutable_isc->remove("relay-agent-info");
694 removed_extended_info = true;
695 isc_throw(BadValue, "relay-agent-info is not a map or a string");
696 }
697
699 return (changed);
700 }
701
702 // Try to decode sub-options.
703 ConstElementPtr sub_options = extended_info->get("sub-options");
704 if (sub_options) {
705 verifying = "sub-options";
706 if (sub_options->getType() != Element::string) {
707 mutable_isc->remove("relay-agent-info");
708 removed_extended_info = true;
709 isc_throw(BadValue, "sub-options is not a string");
710 }
711 string rai_hex = sub_options->stringValue();
712 vector<uint8_t> rai_data;
713 str::decodeFormattedHexString(rai_hex, rai_data);
714 }
715
716 ConstElementPtr remote_id = extended_info->get("remote-id");
717 if (remote_id) {
718 verifying = "remote-id";
719 if (remote_id->getType() != Element::string) {
720 mutable_isc->remove("relay-agent-info");
721 removed_extended_info = true;
722 isc_throw(BadValue, "remote-id is not a string");
723 }
724 string remote_id_hex = remote_id->stringValue();
725 vector<uint8_t> remote_id_data;
726 encode::decodeHex(remote_id_hex, remote_id_data);
727 if (remote_id_data.empty()) {
728 mutable_isc->remove("relay-agent-info");
729 removed_extended_info = true;
730 isc_throw(BadValue, "remote-id is empty");
731 }
732 }
733
734 ConstElementPtr relay_id = extended_info->get("relay-id");
735 if (relay_id) {
736 verifying = "relay-id";
737 if (relay_id->getType() != Element::string) {
738 mutable_isc->remove("relay-agent-info");
739 removed_extended_info = true;
740 isc_throw(BadValue, "relay-id is not a string");
741 }
742 string relay_id_hex = relay_id->stringValue();
743 vector<uint8_t> relay_id_data;
744 encode::decodeHex(relay_id_hex, relay_id_data);
745 if (relay_id_data.empty()) {
746 mutable_isc->remove("relay-agent-info");
747 removed_extended_info = true;
748 isc_throw(BadValue, "relay-id is empty");
749 }
750 }
751
753 return (changed);
754 }
755
756 verifying = "relay-agent-info";
757 for (auto const& elem : extended_info->mapValue()) {
758 if ((elem.first != "sub-options") &&
759 (elem.first != "remote-id") &&
760 (elem.first != "relay-id") &&
761 (elem.first != "comment")) {
762 mutable_isc->remove("relay-agent-info");
763 removed_extended_info = true;
764 isc_throw(BadValue, "spurious '" << elem.first <<
765 "' entry in relay-agent-info");
766 }
767 }
768
769 return (changed);
770 } catch (const exception& ex) {
771 ostringstream err;
772 err << "in " << verifying << " a problem was found: " << ex.what();
774 .arg(lease->addr_.toText())
775 .arg(err.str());
776
777 changed = true;
778 if (verifying == "user context") {
779 lease->setContext(ConstElementPtr());
780 } else if (verifying == "isc") {
781 mutable_user_context->remove("ISC");
782 if (mutable_user_context->empty()) {
783 lease->setContext(ConstElementPtr());
784 }
785 } else {
786 if (!removed_extended_info) {
787 mutable_isc->remove("relay-agent-info");
788 }
789 if (mutable_isc->empty()) {
790 mutable_user_context->remove("ISC");
791 if (mutable_user_context->empty()) {
792 lease->setContext(ConstElementPtr());
793 }
794 }
795 }
796 return (changed);
797 }
798}
799
800bool
803 bool changed = false;
804 if (!lease) {
805 return (changed);
806 }
807
809 return (changed);
810 }
811
812 ConstElementPtr user_context = lease->getContext();
813 if (!user_context) {
814 return (changed);
815 }
816
818 ConstElementPtr relay_info;
819 ElementPtr mutable_user_context;
820 ElementPtr mutable_isc;
821 string verifying = "";
822 bool removed_relay_info = false;
823 bool upgraded = false;
824 bool have_both = false;
825 int i = -1;
826
827 try {
828 verifying = "user context";
829 if (user_context->getType() != Element::map) {
830 isc_throw(BadValue, "user context is not a map");
831 }
832 if (user_context->empty()) {
833 changed = true;
834 lease->setContext(ConstElementPtr());
835 return (changed);
836 }
837
838 verifying = "isc";
839 isc = user_context->get("ISC");
840 if (!isc) {
841 return (changed);
842 }
843 mutable_user_context =
844 boost::const_pointer_cast<Element>(user_context);
845 if (!mutable_user_context) {
846 // Should not happen...
847 mutable_user_context = copy(user_context, 0);
848 lease->setContext(mutable_user_context);
849 }
850
851 if (isc->getType() != Element::map) {
852 isc_throw(BadValue, "ISC entry is not a map");
853 }
854 if (isc->empty()) {
855 changed = true;
856 mutable_user_context->remove("ISC");
857 if (mutable_user_context->empty()) {
858 lease->setContext(ConstElementPtr());
859 }
860 return (changed);
861 }
862 mutable_isc = boost::const_pointer_cast<Element>(isc);
863 if (!mutable_isc) {
864 // Should not happen...
865 mutable_isc = copy(isc, 0);
866 mutable_user_context->set("ISC", mutable_isc);
867 }
868
869 relay_info = mutable_isc->get("relays");
870 if (relay_info && isc->contains("relay-info")) {
871 changed = true;
872 mutable_isc->remove("relays");
873 have_both = true;
874 relay_info.reset();
875 }
876 if (relay_info) {
877 // Upgrade
878 changed = true;
879 upgraded = true;
880 verifying = "relays";
881 mutable_isc->set("relay-info", relay_info);
882 mutable_isc->remove("relays");
883
884 if (relay_info->getType() != Element::list) {
885 mutable_isc->remove("relay-info");
886 removed_relay_info = true;
887 isc_throw(BadValue, "relays is not a list");
888 }
889 if (relay_info->empty()) {
890 mutable_isc->remove("relay-info");
891 removed_relay_info = true;
892 isc_throw(BadValue, "relays is empty");
893 }
894
895 verifying = "relay";
896 for (i = 0; static_cast<size_t>(i) < relay_info->size(); ++i) {
897 ElementPtr relay = relay_info->getNonConst(i);
898 if (!relay) {
899 mutable_isc->remove("relay-info");
900 removed_relay_info = true;
901 isc_throw(BadValue, "null relay#" << i);
902 }
903 if (relay->getType() != Element::map) {
904 mutable_isc->remove("relay-info");
905 removed_relay_info = true;
906 isc_throw(BadValue, "relay#" << i << " is not a map");
907 }
908
909 // Try to decode options.
910 ConstElementPtr options = relay->get("options");
911 if (!options) {
912 continue;
913 }
914
915 verifying = "options";
916 if (options->getType() != Element::string) {
917 mutable_isc->remove("relay-info");
918 removed_relay_info = true;
919 isc_throw(BadValue, "options is not a string");
920 }
921 string options_hex = options->stringValue();
922 vector<uint8_t> options_data;
923 str::decodeFormattedHexString(options_hex, options_data);
924 OptionCollection opts;
925 LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
926
927 auto remote_id_it = opts.find(D6O_REMOTE_ID);
928 if (remote_id_it != opts.end()) {
929 OptionPtr remote_id = remote_id_it->second;
930 if (remote_id) {
931 vector<uint8_t> bytes = remote_id->toBinary();
932 if (bytes.size() > 0) {
933 relay->set("remote-id",
935 }
936 }
937 }
938
939 auto relay_id_it = opts.find(D6O_RELAY_ID);
940 if (relay_id_it != opts.end()) {
941 OptionPtr relay_id = relay_id_it->second;
942 if (relay_id) {
943 vector<uint8_t> bytes = relay_id->toBinary(false);
944 if (bytes.size() > 0) {
945 relay->set("relay-id",
947 }
948 }
949 }
950 }
951 }
952
953 verifying = (upgraded ? "relays" : "relay-info");
954 i = -1;
955 relay_info = mutable_isc->get("relay-info");
956 if (!relay_info) {
957 return (changed);
958 }
959 if (!upgraded && (relay_info->getType() != Element::list)) {
960 mutable_isc->remove("relay-info");
961 removed_relay_info = true;
962 isc_throw(BadValue, "relay-info is not a list");
963 }
964 if (!upgraded && relay_info->empty()) {
965 mutable_isc->remove("relay-info");
966 removed_relay_info = true;
967 isc_throw(BadValue, "relay-info is empty");
968 }
969
970 verifying = "relay";
971 for (i = 0; static_cast<size_t>(i) < relay_info->size(); ++i) {
972 ElementPtr relay = relay_info->getNonConst(i);
973 if (!upgraded && !relay) {
974 mutable_isc->remove("relay-info");
975 removed_relay_info = true;
976 isc_throw(BadValue, "null relay#" << i);
977 }
978 if (!upgraded && (relay->getType() != Element::map)) {
979 mutable_isc->remove("relay-info");
980 removed_relay_info = true;
981 isc_throw(BadValue, "relay#" << i << " is not a map");
982 }
983
984 ConstElementPtr options = relay->get("options");
985 if (!upgraded && options) {
986 // Try to decode options.
987 verifying = "options";
988 if (options->getType() != Element::string) {
989 mutable_isc->remove("relay-info");
990 removed_relay_info = true;
991 isc_throw(BadValue, "options is not a string");
992 }
993 string options_hex = options->stringValue();
994 vector<uint8_t> options_data;
995 str::decodeFormattedHexString(options_hex, options_data);
996 OptionCollection opts;
997 LibDHCP::unpackOptions6(options_data, DHCP6_OPTION_SPACE, opts);
998 }
1000 continue;
1001 }
1002
1003 verifying = "link";
1004 ConstElementPtr link_addr = relay->get("link");
1005 if (!link_addr) {
1006 mutable_isc->remove("relay-info");
1007 removed_relay_info = true;
1008 isc_throw(BadValue, "no link");
1009 }
1010 if (link_addr->getType() != Element::string) {
1011 mutable_isc->remove("relay-info");
1012 removed_relay_info = true;
1013 isc_throw(BadValue, "link is not a string");
1014 }
1015 IOAddress laddr(link_addr->stringValue());
1016 if (!laddr.isV6()) {
1017 mutable_isc->remove("relay-info");
1018 removed_relay_info = true;
1019 isc_throw(BadValue, "link is not an IPv6 address");
1020 }
1021
1022 ConstElementPtr remote_id = relay->get("remote-id");
1023 if (!upgraded && remote_id) {
1024 verifying = "remote-id";
1025 if (remote_id->getType() != Element::string) {
1026 mutable_isc->remove("relay-info");
1027 removed_relay_info = true;
1028 isc_throw(BadValue, "remote-id is not a string");
1029 }
1030 string remote_id_hex = remote_id->stringValue();
1031 vector<uint8_t> remote_id_data;
1032 encode::decodeHex(remote_id_hex, remote_id_data);
1033 if (remote_id_data.empty()) {
1034 mutable_isc->remove("relay-info");
1035 removed_relay_info = true;
1036 isc_throw(BadValue, "remote-id is empty");
1037 }
1038 }
1039
1040 ConstElementPtr relay_id = relay->get("relay-id");
1041 if (!upgraded && relay_id) {
1042 verifying = "relay-id";
1043 if (relay_id->getType() != Element::string) {
1044 mutable_isc->remove("relay-info");
1045 removed_relay_info = true;
1046 isc_throw(BadValue, "relay-id is not a string");
1047 }
1048 string relay_id_hex = relay_id->stringValue();
1049 vector<uint8_t> relay_id_data;
1050 encode::decodeHex(relay_id_hex, relay_id_data);
1051 if (relay_id_data.empty()) {
1052 mutable_isc->remove("relay-info");
1053 removed_relay_info = true;
1054 isc_throw(BadValue, "relay-id is empty");
1055 }
1056 }
1057
1059 continue;
1060 }
1061
1062 verifying = "peer";
1063 ConstElementPtr peer_addr = relay->get("peer");
1064 if (!peer_addr) {
1065 mutable_isc->remove("relay-info");
1066 removed_relay_info = true;
1067 isc_throw(BadValue, "no peer");
1068 }
1069 if (peer_addr->getType() != Element::string) {
1070 mutable_isc->remove("relay-info");
1071 removed_relay_info = true;
1072 isc_throw(BadValue, "peer is not a string");
1073 }
1074 IOAddress paddr(peer_addr->stringValue());
1075 if (!paddr.isV6()) {
1076 mutable_isc->remove("relay-info");
1077 removed_relay_info = true;
1078 isc_throw(BadValue, "peer is not an IPv6 address");
1079 }
1080
1081 verifying = "hop";
1082 ConstElementPtr hop = relay->get("hop");
1083 if (!hop) {
1084 mutable_isc->remove("relay-info");
1085 removed_relay_info = true;
1086 isc_throw(BadValue, "no hop");
1087 }
1088 if (hop->getType() != Element::integer) {
1089 mutable_isc->remove("relay-info");
1090 removed_relay_info = true;
1091 isc_throw(BadValue, "hop is not an integer");
1092 }
1093
1094 verifying = (upgraded ? "relays" : "relay-info");
1095 for (auto const& elem : relay->mapValue()) {
1096 if ((elem.first != "hop") &&
1097 (elem.first != "link") &&
1098 (elem.first != "peer") &&
1099 (elem.first != "options") &&
1100 (elem.first != "remote-id") &&
1101 (elem.first != "relay-id") &&
1102 (elem.first != "comment")) {
1103 mutable_isc->remove("relay-info");
1104 removed_relay_info = true;
1105 isc_throw(BadValue, "spurious '" << elem.first << "' entry");
1106 }
1107 }
1108 }
1109
1110 if (upgraded) {
1113 .arg(lease->addr_.toText());
1114 }
1115
1116 return (changed);
1117 } catch (const exception& ex) {
1118 ostringstream err;
1119 err << "in " << verifying;
1120 if (i >= 0) {
1121 err << " [relay#" << i << "]";
1122 }
1123 err << " a problem was found: " << ex.what();
1125 .arg(lease->addr_.toText())
1126 .arg(err.str());
1127
1128 changed = true;
1129 have_both = !have_both;
1130 if (verifying == "user context") {
1131 lease->setContext(ConstElementPtr());
1132 } else if (verifying == "isc") {
1133 mutable_user_context->remove("ISC");
1134 if (mutable_user_context->empty()) {
1135 lease->setContext(ConstElementPtr());
1136 }
1137 } else {
1138 if (!removed_relay_info) {
1139 mutable_isc->remove("relay-info");
1140 }
1141 if (mutable_isc->empty()) {
1142 mutable_user_context->remove("ISC");
1143 if (mutable_user_context->empty()) {
1144 lease->setContext(ConstElementPtr());
1145 }
1146 }
1147 }
1148 return (changed);
1149 }
1150}
1151
1152void
1154 bool ignore_errors) {
1155 if (!lease) {
1156 return;
1157 }
1158
1159 ConstElementPtr user_context = lease->getContext();
1160 if (!user_context) {
1161 return;
1162 }
1163 if (user_context->getType() != Element::map) {
1164 if (ignore_errors) {
1165 return;
1166 }
1167 isc_throw(BadValue, "user context is not a map");
1168 }
1169 if (user_context->empty()) {
1170 return;
1171 }
1172
1173 ConstElementPtr isc = user_context->get("ISC");
1174 if (!isc) {
1175 return;
1176 }
1177 if (isc->getType() != Element::map) {
1178 if (ignore_errors) {
1179 return;
1180 }
1181 isc_throw(BadValue, "ISC entry is not a map");
1182 }
1183 if (isc->empty()) {
1184 return;
1185 }
1186
1187 ConstElementPtr extended_info = isc->get("relay-agent-info");
1188 if (!extended_info) {
1189 return;
1190 }
1191 if (extended_info->getType() != Element::map) {
1192 if (ignore_errors) {
1193 return;
1194 }
1195 isc_throw(BadValue, "relay-agent-info is not a map");
1196 }
1197 if (extended_info->empty()) {
1198 return;
1199 }
1200
1201 ConstElementPtr relay_id = extended_info->get("relay-id");
1202 if (relay_id) {
1203 if (relay_id->getType() == Element::string) {
1204 vector<uint8_t> bytes;
1205 try {
1206 encode::decodeHex(relay_id->stringValue(), bytes);
1207 } catch (...) {
1208 // Decode failed
1209 if (!ignore_errors) {
1210 throw;
1211 }
1212 }
1213 lease->relay_id_ = bytes;
1214 } else if (!ignore_errors) {
1215 isc_throw(BadValue, "relay-id entry is not a string");
1216 }
1217 }
1218
1219 ConstElementPtr remote_id = extended_info->get("remote-id");
1220 if (remote_id) {
1221 if (remote_id->getType() == Element::string) {
1222 vector<uint8_t> bytes;
1223 try {
1224 encode::decodeHex(remote_id->stringValue(), bytes);
1225 } catch (...) {
1226 // Decode failed
1227 if (!ignore_errors) {
1228 throw;
1229 }
1230 }
1231 lease->remote_id_ = bytes;
1232 } else if (!ignore_errors) {
1233 isc_throw(BadValue, "remote-id entry is not a string");
1234 }
1235 }
1236}
1237
1238bool
1240
1241 bool added = false;
1242 if (!lease) {
1243 return (added);
1244 }
1245
1246 ConstElementPtr user_context = lease->getContext();
1247 if (!user_context || (user_context->getType() != Element::map) ||
1248 user_context->empty()) {
1249 return (added);
1250 }
1251
1252 ConstElementPtr isc = user_context->get("ISC");
1253 if (!isc || (isc->getType() != Element::map) || isc->empty()) {
1254 return (added);
1255 }
1256
1257 ConstElementPtr relay_info = isc->get("relay-info");
1258 if (!relay_info || (relay_info->getType() != Element::list) ||
1259 relay_info->empty()) {
1260 return (added);
1261 }
1262
1263 for (unsigned i = 0; i < relay_info->size(); ++i) {
1264 ConstElementPtr relay = relay_info->get(i);
1265 if (!relay || (relay->getType() != Element::map) || relay->empty()) {
1266 continue;
1267 }
1268 try {
1269 ConstElementPtr relay_id = relay->get("relay-id");
1270 if (relay_id) {
1271 string relay_id_hex = relay_id->stringValue();
1272 vector<uint8_t> relay_id_data;
1273 encode::decodeHex(relay_id_hex, relay_id_data);
1274 if (relay_id_data.empty()) {
1275 continue;
1276 }
1277 addRelayId6(lease->addr_, relay_id_data);
1278 added = true;
1279 }
1280
1281 ConstElementPtr remote_id = relay->get("remote-id");
1282 if (remote_id) {
1283 string remote_id_hex = remote_id->stringValue();
1284 vector<uint8_t> remote_id_data;
1285 encode::decodeHex(remote_id_hex, remote_id_data);
1286 if (remote_id_data.empty()) {
1287 continue;
1288 }
1289 addRemoteId6(lease->addr_, remote_id_data);
1290 added = true;
1291 }
1292 } catch (const exception&) {
1293 continue;
1294 }
1295 }
1296 return (added);
1297}
1298
1299size_t
1301 return (0);
1302}
1303
1304size_t
1306 return (0);
1307}
1308
1311 return (ElementPtr());
1312}
1313
1316 ostringstream msg;
1317 msg << "lease backend '" << getName() << "' is not 'memfile'";
1319}
1320
1321} // namespace isc::dhcp
1322} // 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:29
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
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:550
virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets and pools.
Definition lease_mgr.cc:545
virtual Lease6Collection getLeases6() const =0
Returns all IPv6 leases.
void recountLeaseStats6()
Recalculates per-subnet and global stats for IPv6 leases.
Definition lease_mgr.cc:293
virtual data::ElementPtr getStatus() const
Return status information.
void setExtendedInfoTablesEnabled(const bool enabled)
Modifies the setting whether the lease6 extended info tables are enabled.
Definition lease_mgr.h:1033
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:801
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:282
virtual std::string getName() const =0
Returns backend name.
void recountLeaseStats4()
Recalculates per-subnet and global stats for IPv4 leases.
Definition lease_mgr.cc:74
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:561
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:555
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition lease_mgr.cc:277
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual isc::data::ConstElementPtr lfcStartHandler()
Handler for kea-lfc-start command.
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query for all subnets.
Definition lease_mgr.cc:267
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:580
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:272
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:540
const size_t page_size_
Holds page size.
Definition lease_mgr.h:56
LeasePageSize(const size_t page_size)
Constructor.
Definition lease_mgr.cc:43
LeaseStatsQuery(const SelectMode &select_mode=ALL_SUBNETS)
Constructor to query statistics for all subnets.
Definition lease_mgr.cc:231
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:288
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.
This file contains several functions and constants that are used for handling commands and responses ...
@ 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
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_COMMAND_UNSUPPORTED
Status code indicating that the specified command is not supported.
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