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