Kea: lease.cc Source File

| Kea 2.2.0

lease.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2022 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 <dhcpsrv/lease.h>
10#include <util/pointer_util.h>
11#include <boost/algorithm/string.hpp>
12#include <boost/scoped_ptr.hpp>
13#include <sstream>
14#include <iostream>
15
16
17using namespace isc::util;
18using namespace isc::data;
19using namespace std;
20
21namespace isc {
22namespace dhcp {
23
24const uint32_t Lease::STATE_DEFAULT = 0x0;
25const uint32_t Lease::STATE_DECLINED = 0x1;
26const uint32_t Lease::STATE_EXPIRED_RECLAIMED = 0x2;
27
28std::string
29Lease::lifetimeToText(uint32_t lifetime) {
30 ostringstream repr;
31 if (lifetime == INFINITY_LFT) {
32 repr << "infinity";
33 } else {
34 repr << lifetime;
35 }
36 return repr.str();
37}
38
39Lease::Lease(const isc::asiolink::IOAddress& addr,
40 uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
41 const bool fqdn_fwd, const bool fqdn_rev,
42 const std::string& hostname, const HWAddrPtr& hwaddr)
43 : addr_(addr), valid_lft_(valid_lft), current_valid_lft_(valid_lft),
44 reuseable_valid_lft_(0),
45 cltt_(cltt), current_cltt_(cltt), subnet_id_(subnet_id),
46 hostname_(boost::algorithm::to_lower_copy(hostname)), fqdn_fwd_(fqdn_fwd),
47 fqdn_rev_(fqdn_rev), hwaddr_(hwaddr), state_(STATE_DEFAULT) {
48}
49
50
51std::string
52Lease::typeToText(Lease::Type type) {
53 switch (type) {
54 case Lease::TYPE_V4:
55 return string("V4");
56 case Lease::TYPE_NA:
57 return string("IA_NA");
58 case Lease::TYPE_TA:
59 return string("IA_TA");
60 case Lease::TYPE_PD:
61 return string("IA_PD");
62 break;
63 default: {
64 stringstream tmp;
65 tmp << "unknown (" << type << ")";
66 return (tmp.str());
67 }
68 }
69}
70
71 Lease::Type
72Lease::textToType(const std::string& text) {
73 if (text == "V4") {
74 return (TYPE_V4);
75
76 } else if (text == "IA_NA") {
77 return (TYPE_NA);
78
79 } else if (text == "IA_TA") {
80 return (TYPE_TA);
81
82 } else if (text == "IA_PD") {
83 return (TYPE_PD);
84 }
85
86 isc_throw(BadValue, "unsupported lease type " << text);
87}
88
89std::string
90Lease::basicStatesToText(const uint32_t state) {
91 switch (state) {
92 case STATE_DEFAULT:
93 return ("default");
94 case STATE_DECLINED:
95 return ("declined");
96 case STATE_EXPIRED_RECLAIMED:
97 return ("expired-reclaimed");
98 default:
99 // The default case will be handled further on
100 ;
101 }
102 std::ostringstream s;
103 s << "unknown (" << state << ")";
104 return s.str();
105}
106
107bool
108Lease::expired() const {
109 return ((valid_lft_ != INFINITY_LFT) && (getExpirationTime() < time(NULL)));
110}
111
112bool
113Lease::stateExpiredReclaimed() const {
114 return (state_ == STATE_EXPIRED_RECLAIMED);
115}
116
117bool
118Lease::stateDeclined() const {
119 return (state_ == STATE_DECLINED);
120}
121
122int64_t
123Lease::getExpirationTime() const {
124 return (static_cast<int64_t>(cltt_) + valid_lft_);
125}
126
127bool
128Lease::hasIdenticalFqdn(const Lease& other) const {
129 return (boost::algorithm::iequals(hostname_, other.hostname_) &&
130 fqdn_fwd_ == other.fqdn_fwd_ &&
131 fqdn_rev_ == other.fqdn_rev_);
132}
133
134void
135Lease::fromElementCommon(const LeasePtr& lease, const data::ConstElementPtr& element) {
136 if (!element) {
137 isc_throw(BadValue, "parsed lease data is null");
138 }
139
140 if (element->getType() != Element::map) {
141 isc_throw(BadValue, "parsed lease data is not a JSON map");
142 }
143
144
145 if (!lease) {
146 isc_throw(Unexpected, "pointer to parsed lease is null");
147 }
148
149 // IP address.
150 ConstElementPtr ip_address = element->get("ip-address");
151 if (!ip_address || (ip_address->getType() != Element::string)) {
152 isc_throw(BadValue, "ip-address not present in the parsed lease"
153 " or it is not a string");
154 }
155
156 boost::scoped_ptr<asiolink::IOAddress> io_address;
157 try {
158 io_address.reset(new asiolink::IOAddress(ip_address->stringValue()));
159
160 } catch (const std::exception& ex) {
161 isc_throw(BadValue, "invalid IP address " << ip_address->stringValue()
162 << " in the parsed lease");
163 }
164
165 lease->addr_ = *io_address;
166
167 // Subnet identifier.
168 ConstElementPtr subnet_id = element->get("subnet-id");
169 if (!subnet_id || (subnet_id->getType() != Element::integer)) {
170 isc_throw(BadValue, "subnet-id not present in the parsed lease"
171 " or it is not a number");
172 }
173
174 if (subnet_id->intValue() <= 0) {
175 isc_throw(BadValue, "subnet-id " << subnet_id->intValue() << " is not"
176 << " a positive integer");
177 } else if (subnet_id->intValue() > numeric_limits<uint32_t>::max()) {
178 isc_throw(BadValue, "subnet-id " << subnet_id->intValue() << " is not"
179 << " a 32 bit unsigned integer");
180 }
181
182 lease->subnet_id_ = SubnetID(subnet_id->intValue());
183
184 // Hardware address.
185 ConstElementPtr hw_address = element->get("hw-address");
186 if (hw_address) {
187 if (hw_address->getType() != Element::string) {
188 isc_throw(BadValue, "hw-address is not a string in the parsed lease");
189
190 }
191
192 try {
193 HWAddr parsed_hw_address = HWAddr::fromText(hw_address->stringValue());
194 lease->hwaddr_.reset(new HWAddr(parsed_hw_address.hwaddr_, HTYPE_ETHER));
195
196 } catch (const std::exception& ex) {
197 isc_throw(BadValue, "invalid hardware address "
198 << hw_address->stringValue() << " in the parsed lease");
199 }
200 }
201
202 // cltt
203 ConstElementPtr cltt = element->get("cltt");
204 if (!cltt || (cltt->getType() != Element::integer)) {
205 isc_throw(BadValue, "cltt is not present in the parsed lease"
206 " or it is not a number");
207 }
208
209 if (cltt->intValue() <= 0) {
210 isc_throw(BadValue, "cltt " << cltt->intValue() << " is not a"
211 " positive integer in the parsed lease");
212 }
213
214 lease->cltt_ = static_cast<time_t>(cltt->intValue());
215
216 // valid lifetime
217 ConstElementPtr valid_lifetime = element->get("valid-lft");
218 if (!valid_lifetime || (valid_lifetime->getType() != Element::integer)) {
219 isc_throw(BadValue, "valid-lft is not present in the parsed lease"
220 " or it is not a number");
221 }
222
223 if (valid_lifetime->intValue() < 0) {
224 isc_throw(BadValue, "valid-lft " << valid_lifetime->intValue()
225 << " is negative in the parsed lease");
226 }
227
228 lease->valid_lft_ = valid_lifetime->intValue();
229
230 // fqdn-fwd
231 ConstElementPtr fqdn_fwd = element->get("fqdn-fwd");
232 if (!fqdn_fwd || fqdn_fwd->getType() != Element::boolean) {
233 isc_throw(BadValue, "fqdn-fwd is not present in the parsed lease"
234 " or it is not a boolean value");
235 }
236
237 lease->fqdn_fwd_ = fqdn_fwd->boolValue();
238
239 // fqdn-fwd
240 ConstElementPtr fqdn_rev = element->get("fqdn-rev");
241 if (!fqdn_rev || (fqdn_rev->getType() != Element::boolean)) {
242 isc_throw(BadValue, "fqdn-rev is not present in the parsed lease"
243 " or it is not a boolean value");
244 }
245
246 lease->fqdn_rev_ = fqdn_rev->boolValue();
247
248 // hostname
249 ConstElementPtr hostname = element->get("hostname");
250 if (!hostname || (hostname->getType() != Element::string)) {
251 isc_throw(BadValue, "hostname is not present in the parsed lease"
252 " or it is not a string value");
253 }
254
255 lease->hostname_ = hostname->stringValue();
256 boost::algorithm::to_lower(lease->hostname_);
257
258 // state
259 ConstElementPtr state = element->get("state");
260 if (!state || (state->getType() != Element::integer)) {
261 isc_throw(BadValue, "state is not present in the parsed lease"
262 " or it is not a number");
263 }
264
265 if ((state->intValue() < 0) || (state->intValue() > Lease::STATE_EXPIRED_RECLAIMED)) {
266 isc_throw(BadValue, "state " << state->intValue()
267 << " must be in range [0.."
268 << Lease::STATE_EXPIRED_RECLAIMED << "]");
269 }
270
271 lease->state_ = state->intValue();
272
273 // user context
274 ConstElementPtr ctx = element->get("user-context");
275 if (ctx) {
276 if (ctx->getType() != Element::map) {
277 isc_throw(BadValue, "user context is not a map");
278 }
279 lease->setContext(ctx);
280 }
281
282 lease->updateCurrentExpirationTime();
283}
284
285void
286Lease::updateCurrentExpirationTime() {
287 Lease::syncCurrentExpirationTime(*this, *this);
288}
289
290void
291Lease::syncCurrentExpirationTime(const Lease& from, Lease& to) {
292 to.current_cltt_ = from.cltt_;
293 to.current_valid_lft_ = from.valid_lft_;
294}
295
296 Lease4::Lease4(const Lease4& other)
297 : Lease(other.addr_, other.valid_lft_,
298 other.subnet_id_, other.cltt_, other.fqdn_fwd_,
299 other.fqdn_rev_, other.hostname_, other.hwaddr_) {
300
301 // Copy over fields derived from Lease.
302 state_ = other.state_;
303
304 // Copy the hardware address if it is defined.
305 if (other.hwaddr_) {
306 hwaddr_.reset(new HWAddr(*other.hwaddr_));
307 } else {
308 hwaddr_.reset();
309 }
310
311 if (other.client_id_) {
312 client_id_.reset(new ClientId(other.client_id_->getClientId()));
313
314 } else {
315 client_id_.reset();
316
317 }
318
319 if (other.getContext()) {
320 setContext(other.getContext());
321 }
322}
323
324 Lease4::Lease4(const isc::asiolink::IOAddress& address,
325 const HWAddrPtr& hw_address,
326 const ClientIdPtr& client_id,
327 const uint32_t valid_lifetime,
328 const time_t cltt,
329 const SubnetID subnet_id,
330 const bool fqdn_fwd,
331 const bool fqdn_rev,
332 const std::string& hostname)
333
334 : Lease(address, valid_lifetime, subnet_id, cltt, fqdn_fwd,
335 fqdn_rev, hostname, hw_address),
336 client_id_(client_id) {
337}
338
339std::string
340Lease4::statesToText(const uint32_t state) {
341 return (Lease::basicStatesToText(state));
342}
343
344const std::vector<uint8_t>&
345Lease4::getClientIdVector() const {
346 if(!client_id_) {
347 static std::vector<uint8_t> empty_vec;
348 return (empty_vec);
349 }
350
351 return (client_id_->getClientId());
352}
353
354const std::vector<uint8_t>&
355Lease::getHWAddrVector() const {
356 if (!hwaddr_) {
357 static std::vector<uint8_t> empty_vec;
358 return (empty_vec);
359 }
360 return (hwaddr_->hwaddr_);
361}
362
363bool
364Lease4::belongsToClient(const HWAddrPtr& hw_address,
365 const ClientIdPtr& client_id) const {
366 // If client id matches, lease matches.
367 if (equalValues(client_id, client_id_)) {
368 return (true);
369
370 } else if (!client_id || !client_id_) {
371 // If client id is unspecified, use HW address.
372 if (equalValues(hw_address, hwaddr_)) {
373 return (true);
374 }
375 }
376
377 return (false);
378}
379
380void
381Lease4::decline(uint32_t probation_period) {
382 hwaddr_.reset(new HWAddr());
383 client_id_.reset();
384 cltt_ = time(NULL);
385 hostname_ = string("");
386 fqdn_fwd_ = false;
387 fqdn_rev_ = false;
388 state_ = STATE_DECLINED;
389 valid_lft_ = probation_period;
390}
391
392 Lease4&
393Lease4::operator=(const Lease4& other) {
394 if (this != &other) {
395 addr_ = other.addr_;
396 valid_lft_ = other.valid_lft_;
397 current_valid_lft_ = other.current_valid_lft_;
398 reuseable_valid_lft_ = other.reuseable_valid_lft_;
399 cltt_ = other.cltt_;
400 current_cltt_ = other.current_cltt_;
401 subnet_id_ = other.subnet_id_;
402 hostname_ = other.hostname_;
403 fqdn_fwd_ = other.fqdn_fwd_;
404 fqdn_rev_ = other.fqdn_rev_;
405 state_ = other.state_;
406
407 // Copy the hardware address if it is defined.
408 if (other.hwaddr_) {
409 hwaddr_.reset(new HWAddr(*other.hwaddr_));
410 } else {
411 hwaddr_.reset();
412 }
413
414 if (other.client_id_) {
415 client_id_.reset(new ClientId(other.client_id_->getClientId()));
416 } else {
417 client_id_.reset();
418 }
419
420 if (other.getContext()) {
421 setContext(other.getContext());
422 }
423 }
424 return (*this);
425}
426
427 isc::data::ElementPtr
428Lease4::toElement() const {
429 // Prepare the map
430 ElementPtr map = Element::createMap();
431 contextToElement(map);
432 map->set("ip-address", Element::create(addr_.toText()));
433 map->set("subnet-id", Element::create(static_cast<long int>(subnet_id_)));
434 map->set("hw-address", Element::create(hwaddr_->toText(false)));
435
436 if (client_id_) {
437 map->set("client-id", Element::create(client_id_->toText()));
438 }
439
440 map->set("cltt", Element::create(cltt_));
441 map->set("valid-lft", Element::create(static_cast<long int>(valid_lft_)));
442
443 map->set("fqdn-fwd", Element::create(fqdn_fwd_));
444 map->set("fqdn-rev", Element::create(fqdn_rev_));
445 map->set("hostname", Element::create(hostname_));
446
447 map->set("state", Element::create(static_cast<int>(state_)));
448
449 return (map);
450}
451
452 Lease4Ptr
453Lease4::fromElement(const ConstElementPtr& element) {
454 Lease4Ptr lease(new Lease4());
455
456 // Extract common lease properties into the lease.
457 fromElementCommon(boost::dynamic_pointer_cast<Lease>(lease), element);
458
459 // Validate ip-address, which must be an IPv4 address.
460 if (!lease->addr_.isV4()) {
461 isc_throw(BadValue, "address " << lease->addr_ << " it not an IPv4 address");
462 }
463
464 // Make sure the hw-addres is present.
465 if (!lease->hwaddr_) {
466 isc_throw(BadValue, "hw-address not present in the parsed lease");
467 }
468
469
470 // Client identifier is IPv4 specific.
471 ConstElementPtr client_id = element->get("client-id");
472 if (client_id) {
473 if (client_id->getType() != Element::string) {
474 isc_throw(BadValue, "client identifier is not a string in the"
475 " parsed lease");
476 }
477
478 try {
479 lease->client_id_ = ClientId::fromText(client_id->stringValue());
480
481 } catch (const std::exception& ex) {
482 isc_throw(BadValue, "invalid client identifier "
483 << client_id->stringValue() << " in the parsed lease");
484 }
485 }
486
487 return (lease);
488}
489
490 Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
491 DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
492 SubnetID subnet_id, const HWAddrPtr& hwaddr, uint8_t prefixlen)
493 : Lease(addr, valid, subnet_id, 0/*cltt*/, false, false, "", hwaddr),
494 type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
495 preferred_lft_(preferred), reuseable_preferred_lft_(0) {
496 if (!duid) {
497 isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
498 }
499
500 cltt_ = time(NULL);
501 current_cltt_ = cltt_;
502}
503
504 Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr,
505 DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
506 SubnetID subnet_id, const bool fqdn_fwd, const bool fqdn_rev,
507 const std::string& hostname, const HWAddrPtr& hwaddr,
508 uint8_t prefixlen)
509 : Lease(addr, valid, subnet_id, 0/*cltt*/,
510 fqdn_fwd, fqdn_rev, hostname, hwaddr),
511 type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
512 preferred_lft_(preferred), reuseable_preferred_lft_(0) {
513 if (!duid) {
514 isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
515 }
516
517 cltt_ = time(NULL);
518 current_cltt_ = cltt_;
519}
520
521Lease6::Lease6()
522 : Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, false, false, "",
523 HWAddrPtr()), type_(TYPE_NA), prefixlen_(0), iaid_(0),
524 duid_(DuidPtr()), preferred_lft_(0), reuseable_preferred_lft_(0) {
525}
526
527std::string
528Lease6::statesToText(const uint32_t state) {
529 return (Lease::basicStatesToText(state));
530}
531
532const std::vector<uint8_t>&
533Lease6::getDuidVector() const {
534 if (!duid_) {
535 static std::vector<uint8_t> empty_vec;
536 return (empty_vec);
537 }
538
539 return (duid_->getDuid());
540}
541
542void
543Lease6::decline(uint32_t probation_period) {
544 hwaddr_.reset();
545 duid_.reset(new DUID(DUID::EMPTY()));
546 preferred_lft_ = 0;
547 valid_lft_ = probation_period;
548 cltt_ = time(NULL);
549 hostname_ = string("");
550 fqdn_fwd_ = false;
551 fqdn_rev_ = false;
552 state_ = Lease::STATE_DECLINED;
553}
554
555std::string
556Lease6::toText() const {
557 ostringstream stream;
558
560 stream << "Type: " << typeToText(type_) << "("
561 << static_cast<int>(type_) << ")\n"
562 << "Address: " << addr_ << "\n"
563 << "Prefix length: " << static_cast<int>(prefixlen_) << "\n"
564 << "IAID: " << iaid_ << "\n"
565 << "Pref life: " << lifetimeToText(preferred_lft_) << "\n"
566 << "Valid life: " << lifetimeToText(valid_lft_) << "\n"
567 << "Cltt: " << cltt_ << "\n"
568 << "DUID: " << (duid_?duid_->toText():"(none)") << "\n"
569 << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)") << "\n"
570 << "Subnet ID: " << subnet_id_ << "\n"
571 << "State: " << statesToText(state_) << "\n";
572
573 if (getContext()) {
574 stream << "User context: " << getContext()->str() << "\n";
575 }
576
577 return (stream.str());
578}
579
580std::string
581Lease4::toText() const {
582 ostringstream stream;
583
584 stream << "Address: " << addr_ << "\n"
585 << "Valid life: " << lifetimeToText(valid_lft_) << "\n"
586 << "Cltt: " << cltt_ << "\n"
587 << "Hardware addr: " << (hwaddr_ ? hwaddr_->toText(false) : "(none)") << "\n"
588 << "Client id: " << (client_id_ ? client_id_->toText() : "(none)") << "\n"
589 << "Subnet ID: " << subnet_id_ << "\n"
590 << "State: " << statesToText(state_) << "\n";
591
592 if (getContext()) {
593 stream << "User context: " << getContext()->str() << "\n";
594 }
595
596 return (stream.str());
597}
598
599
600bool
601Lease4::operator==(const Lease4& other) const {
602 return (nullOrEqualValues(hwaddr_, other.hwaddr_) &&
603 nullOrEqualValues(client_id_, other.client_id_) &&
604 addr_ == other.addr_ &&
605 subnet_id_ == other.subnet_id_ &&
606 valid_lft_ == other.valid_lft_ &&
607 current_valid_lft_ == other.current_valid_lft_ &&
608 reuseable_valid_lft_ == other.reuseable_valid_lft_ &&
609 cltt_ == other.cltt_ &&
610 current_cltt_ == other.current_cltt_ &&
611 hostname_ == other.hostname_ &&
612 fqdn_fwd_ == other.fqdn_fwd_ &&
613 fqdn_rev_ == other.fqdn_rev_ &&
614 state_ == other.state_ &&
615 nullOrEqualValues(getContext(), other.getContext()));
616}
617
618bool
619Lease6::operator==(const Lease6& other) const {
620 return (nullOrEqualValues(duid_, other.duid_) &&
621 nullOrEqualValues(hwaddr_, other.hwaddr_) &&
622 addr_ == other.addr_ &&
623 type_ == other.type_ &&
624 prefixlen_ == other.prefixlen_ &&
625 iaid_ == other.iaid_ &&
626 preferred_lft_ == other.preferred_lft_ &&
627 reuseable_preferred_lft_ == other.reuseable_preferred_lft_ &&
628 valid_lft_ == other.valid_lft_ &&
629 current_valid_lft_ == other.current_valid_lft_ &&
630 reuseable_valid_lft_ == other.reuseable_valid_lft_ &&
631 cltt_ == other.cltt_ &&
632 current_cltt_ == other.current_cltt_ &&
633 subnet_id_ == other.subnet_id_ &&
634 hostname_ == other.hostname_ &&
635 fqdn_fwd_ == other.fqdn_fwd_ &&
636 fqdn_rev_ == other.fqdn_rev_ &&
637 state_ == other.state_ &&
638 nullOrEqualValues(getContext(), other.getContext()));
639}
640
641 isc::data::ElementPtr
642Lease6::toElement() const {
643 // Prepare the map
644 ElementPtr map = Element::createMap();
645 contextToElement(map);
646 map->set("ip-address", Element::create(addr_.toText()));
647 map->set("type", Element::create(typeToText(type_)));
648 if (type_ == Lease::TYPE_PD) {
649 map->set("prefix-len", Element::create(prefixlen_));
650 }
651 map->set("iaid", Element::create(static_cast<long int>(iaid_)));
652 map->set("duid", Element::create(duid_->toText()));
653 map->set("subnet-id", Element::create(static_cast<long int>(subnet_id_)));
654
655 map->set("cltt", Element::create(cltt_));
656 map->set("preferred-lft", Element::create(static_cast<long int>(preferred_lft_)));
657 map->set("valid-lft", Element::create(static_cast<long int>(valid_lft_)));
658
659 map->set("fqdn-fwd", Element::create(fqdn_fwd_));
660 map->set("fqdn-rev", Element::create(fqdn_rev_));
661 map->set("hostname", Element::create(hostname_));
662
663 if (hwaddr_) {
664 map->set("hw-address", Element::create(hwaddr_->toText(false)));
665 }
666
667 map->set("state", Element::create(static_cast<long int>(state_)));
668
669 return (map);
670}
671
672 Lease6Ptr
673Lease6::fromElement(const data::ConstElementPtr& element) {
674 Lease6Ptr lease(new Lease6());
675
676 // Extract common lease properties into the lease.
677 fromElementCommon(boost::dynamic_pointer_cast<Lease>(lease), element);
678
679 // Validate ip-address, which must be an IPv6 address.
680 if (!lease->addr_.isV6()) {
681 isc_throw(BadValue, "address " << lease->addr_ << " it not an IPv6 address");
682 }
683
684 // lease type
685 ConstElementPtr lease_type = element->get("type");
686 if (!lease_type || (lease_type->getType() != Element::string)) {
687 isc_throw(BadValue, "type is not present in the parsed lease"
688 " or it is not a string value");
689 }
690
691 lease->type_ = textToType(lease_type->stringValue());
692
693 // prefix length
694 ConstElementPtr prefix_len = element->get("prefix-len");
695 if (lease->type_ == Lease::TYPE_PD) {
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 a number");
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 a number");
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 a number");
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
755std::ostream&
756 operator<<(std::ostream& os, const Lease& lease) {
757 os << lease.toText();
758 return (os);
759}
760
761} // namespace isc::dhcp
762} // namespace isc
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::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition: exceptions/exceptions.h:143
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::asiolink::IOAddress::toText
std::string toText() const
Convert the address to a string.
Definition: io_address.cc:52
isc::data::Element::create
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:241
isc::data::Element::map
@ map
Definition: data.h:155
isc::data::Element::integer
@ integer
Definition: data.h:155
isc::data::Element::boolean
@ boolean
Definition: data.h:155
isc::data::Element::string
@ string
Definition: data.h:155
isc::data::Element::createMap
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:291
isc::dhcp::ClientId
Holds Client identifier or client IPv4 address.
Definition: duid.h:111
isc::dhcp::ClientId::fromText
static ClientIdPtr fromText(const std::string &text)
Create client identifier from the textual format.
Definition: duid.cc:132
isc::dhcp::DUID
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
isc::dhcp::DUID::fromText
static DUID fromText(const std::string &text)
Create DUID from the textual format.
Definition: duid.cc:62
isc::dhcp::DUID::EMPTY
static const DUID & EMPTY()
Defines the constant "empty" DUID.
Definition: duid.cc:69
isc::dhcp::DUID::getDuid
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
Definition: duid.cc:46
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:210
lease.h
asiolink
A wrapper interface for the ASIO library.
boost
Definition: io_service.h:14
isc::data
Definition: base_stamped_element.cc:12
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
isc::data::ElementPtr
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
isc::dhcp::DuidPtr
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:20
isc::dhcp::Lease6Ptr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:503
isc::dhcp::operator<<
std::ostream & operator<<(std::ostream &os, const OpaqueDataTuple &tuple)
Inserts the OpaqueDataTuple as a string into stream.
Definition: opaque_data_tuple.cc:94
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:24
isc::dhcp::LeasePtr
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
Definition: lease.h:22
isc::dhcp::ClientIdPtr
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Definition: duid.h:103
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:284
isc::util
Definition: edns.h:19
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:143
pointer_util.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:70
isc::dhcp::HWAddr::hwaddr_
std::vector< uint8_t > hwaddr_
Definition: hwaddr.h:98
isc::dhcp::Lease4
Structure that holds a lease for IPv4 address.
Definition: lease.h:295
isc::dhcp::Lease4::client_id_
ClientIdPtr client_id_
Client identifier.
Definition: lease.h:301
isc::dhcp::Lease4::decline
void decline(uint32_t probation_period)
Sets IPv4 lease to declined state.
Definition: lease.cc:381
isc::dhcp::Lease4::statesToText
static std::string statesToText(const uint32_t state)
Returns name of the lease states specific to DHCPv4.
Definition: lease.cc:340
isc::dhcp::Lease4::operator==
bool operator==(const Lease4 &other) const
Compare two leases for equality.
Definition: lease.cc:601
isc::dhcp::Lease4::getClientIdVector
const std::vector< uint8_t > & getClientIdVector() const
Returns a client identifier.
Definition: lease.cc:345
isc::dhcp::Lease4::toElement
virtual isc::data::ElementPtr toElement() const
Return the JSON representation of a lease.
Definition: lease.cc:428
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:364
isc::dhcp::Lease4::Lease4
Lease4()
Default constructor.
Definition: lease.h:352
isc::dhcp::Lease4::operator=
Lease4 & operator=(const Lease4 &other)
Assignment operator.
Definition: lease.cc:393
isc::dhcp::Lease4::toText
virtual std::string toText() const
Convert lease to printable form.
Definition: lease.cc:581
isc::dhcp::Lease4::fromElement
static Lease4Ptr fromElement(const data::ConstElementPtr &element)
Returns pointer to the IPv4 lease created from JSON representation.
Definition: lease.cc:453
isc::dhcp::Lease6
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:514
isc::dhcp::Lease6::getDuidVector
const std::vector< uint8_t > & getDuidVector() const
Returns a reference to a vector representing a DUID.
Definition: lease.cc:533
isc::dhcp::Lease6::toText
virtual std::string toText() const
Convert Lease to Printable Form.
Definition: lease.cc:556
isc::dhcp::Lease6::operator==
bool operator==(const Lease6 &other) const
Compare two leases for equality.
Definition: lease.cc:619
isc::dhcp::Lease6::statesToText
static std::string statesToText(const uint32_t state)
Returns name of the lease states specific to DHCPv6.
Definition: lease.cc:528
isc::dhcp::Lease6::Lease6
Lease6()
Constructor.
Definition: lease.cc:521
isc::dhcp::Lease6::type_
Lease::Type type_
Lease type.
Definition: lease.h:519
isc::dhcp::Lease6::reuseable_preferred_lft_
uint32_t reuseable_preferred_lft_
Remaining preferred lifetime.
Definition: lease.h:548
isc::dhcp::Lease6::iaid_
uint32_t iaid_
Identity Association Identifier (IAID)
Definition: lease.h:531
isc::dhcp::Lease6::preferred_lft_
uint32_t preferred_lft_
Preferred lifetime.
Definition: lease.h:540
isc::dhcp::Lease6::duid_
DuidPtr duid_
Client identifier.
Definition: lease.h:534
isc::dhcp::Lease6::fromElement
static Lease6Ptr fromElement(const data::ConstElementPtr &element)
Returns pointer to the IPv6 lease created from JSON representation.
Definition: lease.cc:673
isc::dhcp::Lease6::prefixlen_
uint8_t prefixlen_
IPv6 prefix length.
Definition: lease.h:524
isc::dhcp::Lease6::toElement
virtual isc::data::ElementPtr toElement() const
Return the JSON representation of a lease.
Definition: lease.cc:642
isc::dhcp::Lease6::decline
void decline(uint32_t probation_period)
Sets IPv6 lease to declined state.
Definition: lease.cc:543
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:286
isc::dhcp::Lease::hasIdenticalFqdn
bool hasIdenticalFqdn(const Lease &other) const
Returns true if the other lease has equal FQDN data.
Definition: lease.cc:128
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:137
isc::dhcp::Lease::lifetimeToText
static std::string lifetimeToText(uint32_t lifetime)
Print lifetime.
Definition: lease.cc:29
isc::dhcp::Lease::stateDeclined
bool stateDeclined() const
Indicates if the lease is in the "declined" state.
Definition: lease.cc:118
isc::dhcp::Lease::stateExpiredReclaimed
bool stateExpiredReclaimed() const
Indicates if the lease is in the "expired-reclaimed" state.
Definition: lease.cc:113
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:130
isc::dhcp::Lease::subnet_id_
SubnetID subnet_id_
Subnet identifier.
Definition: lease.h:154
isc::dhcp::Lease::getHWAddrVector
const std::vector< uint8_t > & getHWAddrVector() const
Returns raw (as vector) hardware address.
Definition: lease.cc:355
isc::dhcp::Lease::valid_lft_
uint32_t valid_lft_
Valid lifetime.
Definition: lease.h:125
isc::dhcp::Lease::basicStatesToText
static std::string basicStatesToText(const uint32_t state)
Returns name(s) of the basic lease state(s).
Definition: lease.cc:90
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:108
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:39
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:291
isc::dhcp::Lease::hostname_
std::string hostname_
Client hostname.
Definition: lease.h:159
isc::dhcp::Lease::state_
uint32_t state_
Holds the lease state(s).
Definition: lease.h:185
isc::dhcp::Lease::getExpirationTime
int64_t getExpirationTime() const
Returns lease expiration time.
Definition: lease.cc:123
isc::dhcp::Lease::fqdn_fwd_
bool fqdn_fwd_
Forward zone updated?
Definition: lease.h:164
isc::dhcp::Lease::cltt_
time_t cltt_
Client last transmission time.
Definition: lease.h:143
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:135
isc::dhcp::Lease::typeToText
static std::string typeToText(Type type)
returns text representation of a lease type
Definition: lease.cc:52
isc::dhcp::Lease::textToType
static Type textToType(const std::string &text)
Converts type name to the actual type.
Definition: lease.cc:72
isc::dhcp::Lease::hwaddr_
HWAddrPtr hwaddr_
Client's MAC/hardware address.
Definition: lease.h:174
isc::dhcp::Lease::fqdn_rev_
bool fqdn_rev_
Reverse zone updated?
Definition: lease.h:169
isc::dhcp::Lease::addr_
isc::asiolink::IOAddress addr_
IPv4 ot IPv6 address.
Definition: lease.h:120
isc::dhcp::Lease::current_cltt_
time_t current_cltt_
Current client last transmission time.
Definition: lease.h:149