Kea 3.2.0
lease.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2026 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
11#include <dhcpsrv/lease.h>
12#include <util/pointer_util.h>
13#include <util/str.h>
14#include <boost/algorithm/string.hpp>
15#include <boost/scoped_ptr.hpp>
16#include <sstream>
17#include <iostream>
18
19using namespace isc::asiolink;
20using namespace isc::util;
21using namespace isc::data;
22using namespace std;
23
24namespace isc {
25namespace dhcp {
26
27constexpr uint32_t Lease::STATE_DEFAULT;
28constexpr uint32_t Lease::STATE_DECLINED;
29constexpr uint32_t Lease::STATE_EXPIRED_RECLAIMED;
30constexpr uint32_t Lease::STATE_RELEASED;
31constexpr uint32_t Lease::STATE_REGISTERED;
32
33std::string
34Lease::lifetimeToText(uint32_t lifetime) {
35 ostringstream repr;
36 if (lifetime == INFINITY_LFT) {
37 repr << "infinity";
38 } else {
39 repr << lifetime;
40 }
41 return repr.str();
42}
43
45 uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
46 const bool fqdn_fwd, const bool fqdn_rev,
47 const std::string& hostname, const HWAddrPtr& hwaddr)
48 : addr_(addr), valid_lft_(valid_lft), current_valid_lft_(valid_lft),
50 cltt_(cltt), current_cltt_(cltt), subnet_id_(subnet_id), pool_id_(0),
51 hostname_(boost::algorithm::to_lower_copy(hostname)), fqdn_fwd_(fqdn_fwd),
52 fqdn_rev_(fqdn_rev), hwaddr_(hwaddr), state_(STATE_DEFAULT) {
53}
54
55std::string
57 switch (type) {
58 case Lease::TYPE_V4:
59 return string("V4");
60 case Lease::TYPE_NA:
61 return string("IA_NA");
62 case Lease::TYPE_PD:
63 return string("IA_PD");
64 break;
65 default: {
66 stringstream tmp;
67 tmp << "unknown (" << type << ")";
68 return (tmp.str());
69 }
70 }
71}
72
74Lease::textToType(const std::string& text) {
75 if (text == "V4") {
76 return (TYPE_V4);
77
78 } else if (text == "IA_NA") {
79 return (TYPE_NA);
80
81 } else if (text == "IA_PD") {
82 return (TYPE_PD);
83 }
84
85 isc_throw(BadValue, "unsupported lease type " << text);
86}
87
88std::string
89Lease::basicStatesToText(const uint32_t state) {
90 switch (state) {
91 case STATE_DEFAULT:
92 return ("default");
93 case STATE_DECLINED:
94 return ("declined");
96 return ("expired-reclaimed");
97 case STATE_RELEASED:
98 return ("released");
100 return ("registered");
101 default:
102 // The default case will be handled further on
103 ;
104 }
105 std::ostringstream s;
106 s << "unknown (" << state << ")";
107 return s.str();
108}
109
110bool
112 return ((valid_lft_ != INFINITY_LFT) && (getExpirationTime() < time(NULL)));
113}
114
115bool
119
120bool
122 return (state_ == STATE_DECLINED);
123}
124
125bool
127 return (state_ == STATE_REGISTERED);
128}
129
130int64_t
132 return (static_cast<int64_t>(cltt_) + valid_lft_);
133}
134
135bool
136Lease::hasIdenticalFqdn(const Lease& other) const {
137 return (boost::algorithm::iequals(hostname_, other.hostname_) &&
138 fqdn_fwd_ == other.fqdn_fwd_ &&
139 fqdn_rev_ == other.fqdn_rev_);
140}
141
142void
144 if (!element) {
145 isc_throw(BadValue, "parsed lease data is null");
146 }
147
148 if (element->getType() != Element::map) {
149 isc_throw(BadValue, "parsed lease data is not a JSON map");
150 }
151
152 if (!lease) {
153 isc_throw(Unexpected, "pointer to parsed lease is null");
154 }
155
156 // IP address.
157 ConstElementPtr ip_address = element->get("ip-address");
158 if (!ip_address || (ip_address->getType() != Element::string)) {
159 isc_throw(BadValue, "ip-address not present in the parsed lease"
160 " or it is not a string");
161 }
162
163 boost::scoped_ptr<asiolink::IOAddress> io_address;
164 try {
165 io_address.reset(new asiolink::IOAddress(ip_address->stringValue()));
166
167 } catch (const std::exception& ex) {
168 isc_throw(BadValue, "invalid IP address " << ip_address->stringValue()
169 << " in the parsed lease");
170 }
171
172 lease->addr_ = *io_address;
173
174 // Subnet identifier.
175 ConstElementPtr subnet_id = element->get("subnet-id");
176 if (!subnet_id || (subnet_id->getType() != Element::integer)) {
177 isc_throw(BadValue, "subnet-id not present in the parsed lease"
178 " or it is not an integer");
179 }
180
181 if (subnet_id->intValue() <= 0) {
182 isc_throw(BadValue, "subnet-id " << subnet_id->intValue() << " is not"
183 << " a positive integer");
184 } else if (subnet_id->intValue() > numeric_limits<uint32_t>::max()) {
185 isc_throw(BadValue, "subnet-id " << subnet_id->intValue() << " is not"
186 << " a 32 bit unsigned integer");
187 }
188
189 lease->subnet_id_ = SubnetID(subnet_id->intValue());
190
191 // Pool identifier.
192 ConstElementPtr pool_id = element->get("pool-id");
193 if (pool_id) {
194 if (pool_id->getType() != Element::integer) {
195 isc_throw(BadValue, "pool-id is not an integer");
196 }
197
198 if (pool_id->intValue() <= 0) {
199 isc_throw(BadValue, "pool-id " << pool_id->intValue() << " is not"
200 << " a positive integer");
201 } else if (pool_id->intValue() > numeric_limits<uint32_t>::max()) {
202 isc_throw(BadValue, "pool-id " << pool_id->intValue() << " is not"
203 << " a 32 bit unsigned integer");
204 }
205
206 lease->pool_id_ = pool_id->intValue();
207 }
208
209 // Hardware address.
210 ConstElementPtr hw_address = element->get("hw-address");
211 if (hw_address) {
212 if (hw_address->getType() != Element::string) {
213 isc_throw(BadValue, "hw-address is not a string in the parsed lease");
214
215 }
216
217 try {
218 HWAddr parsed_hw_address = HWAddr::fromText(hw_address->stringValue());
219 lease->hwaddr_.reset(new HWAddr(parsed_hw_address.hwaddr_, HTYPE_ETHER));
220
221 } catch (const std::exception& ex) {
222 isc_throw(BadValue, "invalid hardware address "
223 << hw_address->stringValue() << " in the parsed lease");
224 }
225 }
226
227 // cltt
228 ConstElementPtr cltt = element->get("cltt");
229 if (!cltt || (cltt->getType() != Element::integer)) {
230 isc_throw(BadValue, "cltt is not present in the parsed lease"
231 " or it is not an integer");
232 }
233
234 if (cltt->intValue() <= 0) {
235 isc_throw(BadValue, "cltt " << cltt->intValue() << " is not a"
236 " positive integer in the parsed lease");
237 }
238
239 lease->cltt_ = static_cast<time_t>(cltt->intValue());
240
241 // valid lifetime
242 ConstElementPtr valid_lifetime = element->get("valid-lft");
243 if (!valid_lifetime || (valid_lifetime->getType() != Element::integer)) {
244 isc_throw(BadValue, "valid-lft is not present in the parsed lease"
245 " or it is not an integer");
246 }
247
248 if (valid_lifetime->intValue() < 0) {
249 isc_throw(BadValue, "valid-lft " << valid_lifetime->intValue()
250 << " is negative in the parsed lease");
251 }
252
253 lease->valid_lft_ = valid_lifetime->intValue();
254
255 // fqdn-fwd
256 ConstElementPtr fqdn_fwd = element->get("fqdn-fwd");
257 if (!fqdn_fwd || fqdn_fwd->getType() != Element::boolean) {
258 isc_throw(BadValue, "fqdn-fwd is not present in the parsed lease"
259 " or it is not a boolean value");
260 }
261
262 lease->fqdn_fwd_ = fqdn_fwd->boolValue();
263
264 // fqdn-fwd
265 ConstElementPtr fqdn_rev = element->get("fqdn-rev");
266 if (!fqdn_rev || (fqdn_rev->getType() != Element::boolean)) {
267 isc_throw(BadValue, "fqdn-rev is not present in the parsed lease"
268 " or it is not a boolean value");
269 }
270
271 lease->fqdn_rev_ = fqdn_rev->boolValue();
272
273 // hostname
274 ConstElementPtr hostname = element->get("hostname");
275 if (!hostname || (hostname->getType() != Element::string)) {
276 isc_throw(BadValue, "hostname is not present in the parsed lease"
277 " or it is not a string value");
278 }
279
280 lease->hostname_ = hostname->stringValue();
281 boost::algorithm::to_lower(lease->hostname_);
282
283 // state
284 ConstElementPtr state = element->get("state");
285 if (!state || (state->getType() != Element::integer)) {
286 isc_throw(BadValue, "state is not present in the parsed lease"
287 " or it is not an integer");
288 }
289
290 if ((state->intValue() < 0) || (state->intValue() > Lease::STATE_REGISTERED)) {
291 isc_throw(BadValue, "state " << state->intValue()
292 << " must be in range [0.."
293 << Lease::STATE_REGISTERED << "]");
294 }
295
296 lease->state_ = state->intValue();
297
298 // user context
299 ConstElementPtr ctx = element->get("user-context");
300 if (ctx) {
301 if (ctx->getType() != Element::map) {
302 isc_throw(BadValue, "user context is not a map");
303 }
304 lease->setContext(ctx);
305 }
306
307 lease->updateCurrentExpirationTime();
308}
309
310void
314
315void
317 to.current_cltt_ = from.cltt_;
319}
320
322 const HWAddrPtr& hw_address,
323 const ClientIdPtr& client_id,
324 const uint32_t valid_lifetime,
325 const time_t cltt,
326 const SubnetID subnet_id,
327 const bool fqdn_fwd,
328 const bool fqdn_rev,
329 const std::string& hostname)
330 : Lease(address, valid_lifetime, subnet_id, cltt, fqdn_fwd,
331 fqdn_rev, hostname, hw_address),
332 client_id_(client_id), remote_id_(), relay_id_() {
333}
334
335Lease4::Lease4() : Lease(0, 0, 0, 0, false, false, "", HWAddrPtr()) {
336}
337
338std::string
339Lease4::statesToText(const uint32_t state) {
340 return (Lease::basicStatesToText(state));
341}
342
343const std::vector<uint8_t>&
345 if (!client_id_) {
346 static std::vector<uint8_t> empty_vec;
347 return (empty_vec);
348 }
349
350 return (client_id_->getClientId());
351}
352
353const std::vector<uint8_t>&
355 if (!hwaddr_) {
356 static std::vector<uint8_t> empty_vec;
357 return (empty_vec);
358 }
359 return (hwaddr_->hwaddr_);
360}
361
362bool
364 const ClientIdPtr& client_id) const {
365 // If client id matches, lease matches.
366 if (equalValues(client_id, client_id_)) {
367 return (true);
368
369 } else if (!client_id || !client_id_) {
370 // If client id is unspecified, use HW address.
371 if (equalValues(hw_address, hwaddr_)) {
372 return (true);
373 }
374 }
375
376 return (false);
377}
378
379void
380Lease4::decline(uint32_t probation_period) {
381 hwaddr_.reset(new HWAddr());
382 client_id_.reset();
383 cltt_ = time(NULL);
384 hostname_ = string("");
385 fqdn_fwd_ = false;
386 fqdn_rev_ = false;
388 valid_lft_ = probation_period;
390}
391
394 // Prepare the map
396 contextToElement(map);
397 map->set("ip-address", Element::create(addr_.toText()));
398 map->set("subnet-id", Element::create(static_cast<long int>(subnet_id_)));
399 if (pool_id_) {
400 map->set("pool-id", Element::create(static_cast<long int>(pool_id_)));
401 }
402 map->set("hw-address", Element::create(hwaddr_->toText(false)));
403
404 if (client_id_) {
405 map->set("client-id", Element::create(client_id_->toText()));
406 }
407
408 map->set("cltt", Element::create(cltt_));
409 map->set("valid-lft", Element::create(static_cast<long int>(valid_lft_)));
410
411 map->set("fqdn-fwd", Element::create(fqdn_fwd_));
412 map->set("fqdn-rev", Element::create(fqdn_rev_));
413 map->set("hostname", Element::create(hostname_));
414
415 map->set("state", Element::create(static_cast<int>(state_)));
416
417 return (map);
418}
419
422 Lease4Ptr lease(new Lease4());
423
424 // Extract common lease properties into the lease.
425 fromElementCommon(boost::dynamic_pointer_cast<Lease>(lease), element);
426
427 // Validate ip-address, which must be an IPv4 address.
428 if (!lease->addr_.isV4()) {
429 isc_throw(BadValue, "address " << lease->addr_ << " it not an IPv4 address");
430 }
431
432 // Make sure the hw-addres is present.
433 if (!lease->hwaddr_) {
434 isc_throw(BadValue, "hw-address not present in the parsed lease");
435 }
436
437 // Client identifier is IPv4 specific.
438 ConstElementPtr client_id = element->get("client-id");
439 if (client_id) {
440 if (client_id->getType() != Element::string) {
441 isc_throw(BadValue, "client identifier is not a string in the"
442 " parsed lease");
443 }
444
445 try {
446 lease->client_id_ = ClientId::fromText(client_id->stringValue());
447
448 } catch (const std::exception& ex) {
449 isc_throw(BadValue, "invalid client identifier "
450 << client_id->stringValue() << " in the parsed lease");
451 }
452 }
453
454 return (lease);
455}
456
458 DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
459 SubnetID subnet_id, const HWAddrPtr& hwaddr, uint8_t prefixlen)
460 : Lease(addr, valid, subnet_id, 0/*cltt*/, false, false, "", hwaddr),
461 type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
464 if (!duid) {
465 isc_throw(BadValue, "DUID is mandatory for an IPv6 lease");
466 }
467
468 if (prefixlen != 128) {
469 if (type != Lease::TYPE_PD) {
470 isc_throw(BadValue, "prefixlen must be 128 for non prefix type");
471 } else {
472 IOAddress first_address = firstAddrInPrefix(addr, prefixlen);
473 if (first_address != addr) {
474 isc_throw(BadValue, "Prefix address: " << addr
475 << " exceeds prefix/prefix-len pair: " << first_address
476 << "/" << static_cast<uint32_t>(prefixlen));
477 }
478 }
479 }
480
481 cltt_ = time(NULL);
483}
484
486 DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
487 SubnetID subnet_id, const bool fqdn_fwd, const bool fqdn_rev,
488 const std::string& hostname, const HWAddrPtr& hwaddr,
489 uint8_t prefixlen)
490 : Lease(addr, valid, subnet_id, 0/*cltt*/,
491 fqdn_fwd, fqdn_rev, hostname, hwaddr),
492 type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
495
496 if (!duid) {
497 isc_throw(BadValue, "DUID is mandatory for an IPv6 lease");
498 }
499
500 if (prefixlen != 128) {
501 if (type != Lease::TYPE_PD) {
502 isc_throw(BadValue, "prefixlen must be 128 for non prefix type");
503 } else {
504 IOAddress first_address = firstAddrInPrefix(addr, prefixlen);
505 if (first_address != addr) {
506 isc_throw(BadValue, "Prefix address: " << addr
507 << " exceeds prefix/prefix-len pair: " << first_address
508 << "/" << static_cast<uint32_t>(prefixlen));
509 }
510 }
511 }
512
513 cltt_ = time(NULL);
515}
516
523
524std::string
525Lease6::statesToText(const uint32_t state) {
526 return (Lease::basicStatesToText(state));
527}
528
529const std::vector<uint8_t>&
531 if (!duid_) {
532 static std::vector<uint8_t> empty_vec;
533 return (empty_vec);
534 }
535
536 return (duid_->getDuid());
537}
538
539void
540Lease6::decline(uint32_t probation_period) {
541 hwaddr_.reset();
542 duid_.reset(new DUID(DUID::EMPTY()));
543 preferred_lft_ = 0;
544 valid_lft_ = probation_period;
545 cltt_ = time(NULL);
546 hostname_ = string("");
547 fqdn_fwd_ = false;
548 fqdn_rev_ = false;
550}
551
552std::string
554 ostringstream stream;
555
557 stream << "Type: " << typeToText(type_) << "("
558 << static_cast<int>(type_) << ")\n"
559 << "Address: " << addr_ << "\n"
560 << "Prefix length: " << static_cast<int>(prefixlen_) << "\n"
561 << "IAID: " << iaid_ << "\n"
562 << "Pref life: " << lifetimeToText(preferred_lft_) << "\n"
563 << "Valid life: " << lifetimeToText(valid_lft_) << "\n"
564 << "Cltt: " << cltt_ << "\n"
565 << "DUID: " << (duid_ ? duid_->toText() : "(none)") << "\n"
566 << "Hardware addr: " << (hwaddr_ ? hwaddr_->toText(false) : "(none)") << "\n"
567 << "Subnet ID: " << subnet_id_ << "\n"
568 << "Pool ID: " << pool_id_ << "\n"
569 << "State: " << statesToText(state_) << "\n";
570
571 if (getContext()) {
572 stream << "User context: " << getContext()->str() << "\n";
573 }
574
575 return (stream.str());
576}
577
578std::string
580 ostringstream stream;
581
582 stream << "Address: " << addr_ << "\n"
583 << "Valid life: " << lifetimeToText(valid_lft_) << "\n"
584 << "Cltt: " << cltt_ << "\n"
585 << "Hardware addr: " << (hwaddr_ ? hwaddr_->toText(false) : "(none)") << "\n"
586 << "Client id: " << (client_id_ ? client_id_->toText() : "(none)") << "\n"
587 << "Subnet ID: " << subnet_id_ << "\n"
588 << "Pool ID: " << pool_id_ << "\n"
589 << "State: " << statesToText(state_) << "\n"
590 << "Relay ID: " << (relay_id_.empty() ? "(none)" :
591 str::dumpAsHex(&relay_id_[0], relay_id_.size())) << "\n"
592 << "Remote ID: " << (remote_id_.empty() ? "(none)" :
593 str::dumpAsHex(&remote_id_[0], remote_id_.size())) << "\n";
594
595 if (getContext()) {
596 stream << "User context: " << getContext()->str() << "\n";
597 }
598
599 return (stream.str());
600}
601
602bool
603Lease4::operator==(const Lease4& other) const {
604 return (nullOrEqualValues(hwaddr_, other.hwaddr_) &&
606 addr_ == other.addr_ &&
607 subnet_id_ == other.subnet_id_ &&
608 pool_id_ == other.pool_id_ &&
609 valid_lft_ == other.valid_lft_ &&
612 cltt_ == other.cltt_ &&
613 current_cltt_ == other.current_cltt_ &&
614 hostname_ == other.hostname_ &&
615 fqdn_fwd_ == other.fqdn_fwd_ &&
616 fqdn_rev_ == other.fqdn_rev_ &&
617 state_ == other.state_ &&
619}
620
621bool
622Lease6::operator==(const Lease6& other) const {
623 return (nullOrEqualValues(duid_, other.duid_) &&
625 addr_ == other.addr_ &&
626 type_ == other.type_ &&
627 prefixlen_ == other.prefixlen_ &&
628 iaid_ == other.iaid_ &&
631 valid_lft_ == other.valid_lft_ &&
634 cltt_ == other.cltt_ &&
635 current_cltt_ == other.current_cltt_ &&
636 subnet_id_ == other.subnet_id_ &&
637 pool_id_ == other.pool_id_ &&
638 hostname_ == other.hostname_ &&
639 fqdn_fwd_ == other.fqdn_fwd_ &&
640 fqdn_rev_ == other.fqdn_rev_ &&
641 state_ == other.state_ &&
643}
644
647 // Prepare the map
649 contextToElement(map);
650 map->set("ip-address", Element::create(addr_.toText()));
651 map->set("type", Element::create(typeToText(type_)));
652 if (type_ == Lease::TYPE_PD) {
653 map->set("prefix-len", Element::create(prefixlen_));
654 }
655 map->set("iaid", Element::create(static_cast<long int>(iaid_)));
656 map->set("duid", Element::create(duid_->toText()));
657 map->set("subnet-id", Element::create(static_cast<long int>(subnet_id_)));
658 if (pool_id_) {
659 map->set("pool-id", Element::create(static_cast<long int>(pool_id_)));
660 }
661
662 map->set("cltt", Element::create(cltt_));
663 map->set("preferred-lft", Element::create(static_cast<long int>(preferred_lft_)));
664 map->set("valid-lft", Element::create(static_cast<long int>(valid_lft_)));
665
666 map->set("fqdn-fwd", Element::create(fqdn_fwd_));
667 map->set("fqdn-rev", Element::create(fqdn_rev_));
668 map->set("hostname", Element::create(hostname_));
669
670 if (hwaddr_) {
671 map->set("hw-address", Element::create(hwaddr_->toText(false)));
672 }
673
674 map->set("state", Element::create(static_cast<long int>(state_)));
675
676 return (map);
677}
678
681 Lease6Ptr lease(new Lease6());
682
683 // Extract common lease properties into the lease.
684 fromElementCommon(boost::dynamic_pointer_cast<Lease>(lease), element);
685
686 // Validate ip-address, which must be an IPv6 address.
687 if (!lease->addr_.isV6()) {
688 isc_throw(BadValue, "address " << lease->addr_ << " it not an IPv6 address");
689 }
690
691 // lease type
692 ConstElementPtr lease_type = element->get("type");
693 if (!lease_type || (lease_type->getType() != Element::string)) {
694 isc_throw(BadValue, "type is not present in the parsed lease"
695 " or it is not a string value");
696 }
697
698 lease->type_ = textToType(lease_type->stringValue());
699
700 // prefix length
701 if (lease->type_ != Lease::TYPE_PD) {
702 lease->prefixlen_ = 128;
703 } else {
704 ConstElementPtr prefix_len = element->get("prefix-len");
705 if (!prefix_len || (prefix_len->getType() != Element::integer)) {
706 isc_throw(BadValue, "prefix-len is not present in the parsed lease"
707 " or it is not an integer");
708 }
709
710 if ((prefix_len->intValue() < 1) || (prefix_len->intValue() > 128)) {
711 isc_throw(BadValue, "prefix-len " << prefix_len->intValue()
712 << " must be in range of [1..128]");
713 }
714
715 lease->prefixlen_ = static_cast<uint8_t>(prefix_len->intValue());
716 }
717
718 // IAID
719 ConstElementPtr iaid = element->get("iaid");
720 if (!iaid || (iaid->getType() != Element::integer)) {
721 isc_throw(BadValue, "iaid is not present in the parsed lease"
722 " or it is not an integer");
723 }
724
725 if (iaid->intValue() < 0) {
726 isc_throw(BadValue, "iaid " << iaid->intValue() << " must not be negative");
727 }
728
729 lease->iaid_ = static_cast<uint32_t>(iaid->intValue());
730
731 // DUID
732 ConstElementPtr duid = element->get("duid");
733 if (!duid || (duid->getType() != Element::string)) {
734 isc_throw(BadValue, "duid not present in the parsed lease"
735 " or it is not a string");
736 }
737
738 try {
739 DUID parsed_duid = DUID::fromText(duid->stringValue());
740 lease->duid_.reset(new DUID(parsed_duid.getDuid()));
741
742 } catch (const std::exception& ex) {
743 isc_throw(BadValue, "invalid DUID "
744 << duid->stringValue() << " in the parsed lease");
745 }
746
747 // preferred lifetime
748 ConstElementPtr preferred_lft = element->get("preferred-lft");
749 if (!preferred_lft || (preferred_lft->getType() != Element::integer)) {
750 isc_throw(BadValue, "preferred-lft is not present in the parsed lease"
751 " or is not an integer");
752 }
753
754 if (preferred_lft->intValue() < 0) {
755 isc_throw(BadValue, "preferred-lft " << preferred_lft->intValue()
756 << " must not be negative");
757 }
758
759 lease->preferred_lft_ = static_cast<uint32_t>(preferred_lft->intValue());
760
761 return (lease);
762}
763
764bool
765Lease::updateUserContextISC(const std::string elem_name,
766 ConstElementPtr new_values) {
767 // Get a mutable copy of the lease's current user context.
768 ConstElementPtr user_context = getContext();
769 ElementPtr mutable_user_context;
770 if (user_context && (user_context->getType() == Element::map)) {
771 mutable_user_context = copy(user_context, 0);
772 } else {
773 mutable_user_context = Element::createMap();
774 }
775
776 // Get a mutable copy of the ISC entry.
777 ConstElementPtr isc = mutable_user_context->get("ISC");
778 ElementPtr mutable_isc;
779 if (isc && (isc->getType() == Element::map)) {
780 mutable_isc = copy(isc, 0);
781 } else {
782 mutable_isc = Element::createMap();
783 }
784
785 // Add/replace the new_values entry
786 bool changed = false;
787 ConstElementPtr old_values = mutable_isc->get(elem_name);
788 if (!old_values || (*old_values != *new_values)) {
789 changed = true;
790 mutable_isc->set(elem_name, new_values);
791 mutable_user_context->set("ISC", mutable_isc);
792 setContext(mutable_user_context);
793 }
794
795 return(changed);
796}
797
798std::ostream&
799operator<<(std::ostream& os, const Lease& lease) {
800 os << lease.toText();
801 return (os);
802}
803
804} // namespace isc::dhcp
805} // 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 an unexpected error condition occurs.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:299
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:354
static ClientIdPtr fromText(const std::string &text)
Create client identifier from the textual format.
Definition duid.cc:73
Holds DUID (DHCPv6 Unique Identifier).
Definition duid.h:142
static DUID fromText(const std::string &text)
Create DUID from the textual format.
Definition duid.cc:50
static const DUID & EMPTY()
Defines the constant "empty" DUID.
Definition duid.cc:55
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
Definition duid.cc:33
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
ElementPtr copy(ConstElementPtr from, unsigned level)
Copy the data up to a nesting level.
Definition data.cc:1522
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
boost::shared_ptr< DUID > DuidPtr
Definition duid.h:136
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:528
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition hwaddr.h:154
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition subnet_id.h:25
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
Definition lease.h:25
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition duid.h:216
@ HTYPE_ETHER
Ethernet 10Mbps.
Definition dhcp4.h:56
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
string dumpAsHex(const uint8_t *data, size_t length)
Dumps a buffer of bytes as a string of hexadecimal digits.
Definition str.cc:330
bool nullOrEqualValues(const T &ptr1, const T &ptr2)
This function checks if two pointers are both null or both are non-null and they point to equal value...
bool equalValues(const T &ptr1, const T &ptr2)
This function checks if two pointers are non-null and values are equal.
Defines the logger used by the top-level component of kea-lfc.
data::ConstElementPtr getContext() const
Returns const pointer to the user context.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
void setContext(const data::ConstElementPtr &ctx)
Sets user context.
Hardware type that represents information from DHCPv4 packet.
Definition hwaddr.h:20
static HWAddr fromText(const std::string &text, const uint16_t htype=HTYPE_ETHER)
Creates instance of the hardware address from textual format.
Definition hwaddr.cc:69
std::vector< uint8_t > hwaddr_
Definition hwaddr.h:98
ClientIdPtr client_id_
Client identifier.
Definition lease.h:329
void decline(uint32_t probation_period)
Sets IPv4 lease to declined state.
Definition lease.cc:380
static std::string statesToText(const uint32_t state)
Returns name of the lease states specific to DHCPv4.
Definition lease.cc:339
Lease4(const isc::asiolink::IOAddress &addr, const HWAddrPtr &hwaddr, const uint8_t *clientid, size_t clientid_len, uint32_t valid_lft, time_t cltt, uint32_t subnet_id, const bool fqdn_fwd=false, const bool fqdn_rev=false, const std::string &hostname="")
Constructor.
Definition lease.h:343
bool operator==(const Lease4 &other) const
Compare two leases for equality.
Definition lease.cc:603
std::vector< uint8_t > remote_id_
Remote identifier for Bulk Lease Query.
Definition lease.h:513
std::vector< uint8_t > relay_id_
Relay identifier for Bulk Lease Query.
Definition lease.h:516
const std::vector< uint8_t > & getClientIdVector() const
Returns a client identifier.
Definition lease.cc:344
virtual isc::data::ElementPtr toElement() const
Return the JSON representation of a lease.
Definition lease.cc:393
bool belongsToClient(const HWAddrPtr &hw_address, const ClientIdPtr &client_id) const
Check if the lease belongs to the client with the given identifiers.
Definition lease.cc:363
Lease4()
Default constructor.
Definition lease.cc:335
virtual std::string toText() const
Convert lease to printable form.
Definition lease.cc:579
static Lease4Ptr fromElement(const data::ConstElementPtr &element)
Returns pointer to the IPv4 lease created from JSON representation.
Definition lease.cc:421
ExtendedInfoAction extended_info_action_
Record the action on extended info tables in the lease.
Definition lease.h:580
const std::vector< uint8_t > & getDuidVector() const
Returns a reference to a vector representing a DUID.
Definition lease.cc:530
ExtendedInfoAction
Action on extended info tables.
Definition lease.h:573
@ ACTION_IGNORE
ignore extended info,
Definition lease.h:574
virtual std::string toText() const
Convert Lease to Printable Form.
Definition lease.cc:553
Lease6(Lease::Type type, const isc::asiolink::IOAddress &addr, DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid, SubnetID subnet_id, const HWAddrPtr &hwaddr=HWAddrPtr(), uint8_t prefixlen=128)
Constructor.
Definition lease.cc:457
bool operator==(const Lease6 &other) const
Compare two leases for equality.
Definition lease.cc:622
static std::string statesToText(const uint32_t state)
Returns name of the lease states specific to DHCPv6.
Definition lease.cc:525
Lease6()
Constructor.
Definition lease.cc:517
Lease::Type type_
Lease type.
Definition lease.h:541
uint32_t reuseable_preferred_lft_
Remaining preferred lifetime.
Definition lease.h:570
uint32_t iaid_
Identity Association Identifier (IAID).
Definition lease.h:553
uint32_t preferred_lft_
Preferred lifetime.
Definition lease.h:562
DuidPtr duid_
Client identifier.
Definition lease.h:556
static Lease6Ptr fromElement(const data::ConstElementPtr &element)
Returns pointer to the IPv6 lease created from JSON representation.
Definition lease.cc:680
uint8_t prefixlen_
IPv6 prefix length.
Definition lease.h:546
virtual isc::data::ElementPtr toElement() const
Return the JSON representation of a lease.
Definition lease.cc:646
void decline(uint32_t probation_period)
Sets IPv6 lease to declined state.
Definition lease.cc:540
a common structure for IPv4 and IPv6 leases
Definition lease.h:31
void updateCurrentExpirationTime()
Update lease current expiration time with new value, so that additional operations can be done withou...
Definition lease.cc:311
bool hasIdenticalFqdn(const Lease &other) const
Returns true if the other lease has equal FQDN data.
Definition lease.cc:136
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire).
Definition lease.h:34
static constexpr uint32_t STATE_DEFAULT
A lease in the default state.
Definition lease.h:69
uint32_t reuseable_valid_lft_
Remaining valid lifetime.
Definition lease.h:143
static std::string lifetimeToText(uint32_t lifetime)
Print lifetime.
Definition lease.cc:34
static constexpr uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Definition lease.h:75
bool stateDeclined() const
Indicates if the lease is in the "declined" state.
Definition lease.cc:121
bool stateExpiredReclaimed() const
Indicates if the lease is in the "expired-reclaimed" state.
Definition lease.cc:116
static constexpr uint32_t STATE_DECLINED
Declined lease.
Definition lease.h:72
static constexpr uint32_t STATE_REGISTERED
Registered self-generated lease.
Definition lease.h:81
uint32_t current_valid_lft_
Current valid lifetime.
Definition lease.h:136
SubnetID subnet_id_
Subnet identifier.
Definition lease.h:160
uint32_t pool_id_
The pool id.
Definition lease.h:165
const std::vector< uint8_t > & getHWAddrVector() const
Returns raw (as vector) hardware address.
Definition lease.cc:354
uint32_t valid_lft_
Valid lifetime.
Definition lease.h:131
bool stateRegistered() const
Indicates if the lease is in the "registered" state.
Definition lease.cc:126
static std::string basicStatesToText(const uint32_t state)
Returns name(s) of the basic lease state(s).
Definition lease.cc:89
bool expired() const
returns true if the lease is expired
Definition lease.cc:111
static constexpr uint32_t STATE_RELEASED
Released lease held in the database for lease affinity.
Definition lease.h:78
Lease(const isc::asiolink::IOAddress &addr, uint32_t valid_lft, SubnetID subnet_id, time_t cltt, const bool fqdn_fwd, const bool fqdn_rev, const std::string &hostname, const HWAddrPtr &hwaddr)
Constructor.
Definition lease.cc:44
static void syncCurrentExpirationTime(const Lease &from, Lease &to)
Sync lease current expiration time with new value from another lease, so that additional operations c...
Definition lease.cc:316
std::string hostname_
Client hostname.
Definition lease.h:170
uint32_t state_
Holds the lease state(s).
Definition lease.h:196
int64_t getExpirationTime() const
Returns lease expiration time.
Definition lease.cc:131
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
bool fqdn_fwd_
Forward zone updated?
Definition lease.h:175
time_t cltt_
Client last transmission time.
Definition lease.h:149
bool updateUserContextISC(const std::string elem_name, data::ConstElementPtr new_values)
Update the ISC entry in the lease's user-context.
Definition lease.cc:765
virtual std::string toText() const =0
Convert Lease to Printable Form.
static void fromElementCommon(const LeasePtr &lease, const data::ConstElementPtr &element)
Sets common (for v4 and v6) properties of the lease object.
Definition lease.cc:143
static std::string typeToText(Type type)
returns text representation of a lease type
Definition lease.cc:56
static Type textToType(const std::string &text)
Converts type name to the actual type.
Definition lease.cc:74
HWAddrPtr hwaddr_
Client's MAC/hardware address.
Definition lease.h:185
bool fqdn_rev_
Reverse zone updated?
Definition lease.h:180
isc::asiolink::IOAddress addr_
IPv4 ot IPv6 address.
Definition lease.h:126
time_t current_cltt_
Current client last transmission time.
Definition lease.h:155