| Kea 3.0.2-git

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