Kea  1.5.0
memfile_lease_mgr.cc
Go to the documentation of this file.
1 // Copyright (C) 2012-2018 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>
9 #include <dhcpsrv/cfgmgr.h>
11 #include <dhcpsrv/dhcpsrv_log.h>
14 #include <dhcpsrv/timer_mgr.h>
15 #include <exceptions/exceptions.h>
16 #include <util/pid_file.h>
17 #include <util/process_spawn.h>
18 #include <util/signal_set.h>
19 #include <cstdio>
20 #include <cstring>
21 #include <errno.h>
22 #include <iostream>
23 #include <limits>
24 #include <sstream>
25 
26 namespace {
27 
29 const uint32_t MAX_LEASE_ERRORS = 100;
30 
38 const char* KEA_LFC_EXECUTABLE_ENV_NAME = "KEA_LFC_EXECUTABLE";
39 
40 } // end of anonymous namespace
41 
42 using namespace isc::asiolink;
43 using namespace isc::db;
44 using namespace isc::util;
45 
46 namespace isc {
47 namespace dhcp {
48 
63 class LFCSetup {
64 public:
65 
74 
78  ~LFCSetup();
79 
91  void setup(const uint32_t lfc_interval,
92  const boost::shared_ptr<CSVLeaseFile4>& lease_file4,
93  const boost::shared_ptr<CSVLeaseFile6>& lease_file6,
94  bool run_once_now = false);
95 
97  void execute();
98 
102  bool isRunning() const;
103 
105  int getExitStatus() const;
106 
107 private:
108 
111  boost::scoped_ptr<util::ProcessSpawn> process_;
112 
115 
117  pid_t pid_;
118 
123  TimerMgrPtr timer_mgr_;
124 };
125 
126 LFCSetup::LFCSetup(asiolink::IntervalTimer::Callback callback)
127  : process_(), callback_(callback), pid_(0),
128  timer_mgr_(TimerMgr::instance()) {
129 }
130 
132  try {
133  // Remove the timer. This will throw an exception if the timer does not
134  // exist. There are several possible reasons for this:
135  // a) It hasn't been registered (although if the LFC Setup instance
136  // exists it means that the timer must have been registered or that
137  // such registration has been attempted).
138  // b) The registration may fail if the duplicate timer exists or if the
139  // TimerMgr's worker thread is running but if this happens it is a
140  // programming error.
141  // c) The program is shutting down and the timer has been removed by
142  // another component.
143  timer_mgr_->unregisterTimer("memfile-lfc");
144 
145  } catch (const std::exception& ex) {
146  // We don't want exceptions being thrown from the destructor so we just
147  // log a message here. The message is logged at debug severity as
148  // we don't want an error message output during shutdown.
150  DHCPSRV_MEMFILE_LFC_UNREGISTER_TIMER_FAILED).arg(ex.what());
151  }
152 }
153 
154 void
155 LFCSetup::setup(const uint32_t lfc_interval,
156  const boost::shared_ptr<CSVLeaseFile4>& lease_file4,
157  const boost::shared_ptr<CSVLeaseFile6>& lease_file6,
158  bool run_once_now) {
159 
160  // If to nothing to do, punt
161  if (lfc_interval == 0 && !run_once_now) {
162  return;
163  }
164 
165  // Start preparing the command line for kea-lfc.
166  std::string executable;
167  char* c_executable = getenv(KEA_LFC_EXECUTABLE_ENV_NAME);
168  if (c_executable == NULL) {
169  executable = KEA_LFC_EXECUTABLE;
170  } else {
171  executable = c_executable;
172  }
173 
174  // Gather the base file name.
175  std::string lease_file = lease_file4 ? lease_file4->getFilename() :
176  lease_file6->getFilename();
177 
178  // Create the other names by appending suffixes to the base name.
179  util::ProcessArgs args;
180  // Universe: v4 or v6.
181  args.push_back(lease_file4 ? "-4" : "-6");
182 
183  // Previous file.
184  args.push_back("-x");
185  args.push_back(Memfile_LeaseMgr::appendSuffix(lease_file,
187  // Input file.
188  args.push_back("-i");
189  args.push_back(Memfile_LeaseMgr::appendSuffix(lease_file,
191  // Output file.
192  args.push_back("-o");
193  args.push_back(Memfile_LeaseMgr::appendSuffix(lease_file,
195  // Finish file.
196  args.push_back("-f");
197  args.push_back(Memfile_LeaseMgr::appendSuffix(lease_file,
199  // PID file.
200  args.push_back("-p");
201  args.push_back(Memfile_LeaseMgr::appendSuffix(lease_file,
203 
204  // The configuration file is currently unused.
205  args.push_back("-c");
206  args.push_back("ignored-path");
207 
208  // Create the process (do not start it yet).
209  process_.reset(new util::ProcessSpawn(executable, args));
210 
211  // If we've been told to run it once now, invoke the callback directly.
212  if (run_once_now) {
213  callback_();
214  }
215 
216  // If it's supposed to run periodically, setup that now.
217  if (lfc_interval > 0) {
218  // Set the timer to call callback function periodically.
219  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_SETUP).arg(lfc_interval);
220 
221  // Multiple the lfc_interval value by 1000 as this value specifies
222  // a timeout in seconds, whereas the setup() method expects the
223  // timeout in milliseconds.
224  timer_mgr_->registerTimer("memfile-lfc", callback_, lfc_interval * 1000,
226  timer_mgr_->setup("memfile-lfc");
227  }
228 }
229 
230 void
232  try {
233  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_EXECUTE)
234  .arg(process_->getCommandLine());
235  pid_ = process_->spawn();
236 
237  } catch (const ProcessSpawnError&) {
238  LOG_ERROR(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_SPAWN_FAIL);
239  }
240 }
241 
242 bool
244  return (process_ && process_->isRunning(pid_));
245 }
246 
247 int
249  if (!process_) {
250  isc_throw(InvalidOperation, "unable to obtain LFC process exit code: "
251  " the process is NULL");
252  }
253  return (process_->getExitStatus(pid_));
254 }
255 
256 
263 public:
267  : rows_(0), next_pos_(rows_.end()) {
268  };
269 
274  : LeaseStatsQuery(subnet_id), rows_(0), next_pos_(rows_.end()) {
275  };
276 
281  MemfileLeaseStatsQuery(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id)
282  : LeaseStatsQuery(first_subnet_id, last_subnet_id), rows_(0), next_pos_(rows_.end()) {
283  };
284 
287 
298  virtual bool getNextRow(LeaseStatsRow& row) {
299  if (next_pos_ == rows_.end()) {
300  return (false);
301  }
302 
303  row = *next_pos_;
304  ++next_pos_;
305  return (true);
306  }
307 
309  int getRowCount() const {
310  return (rows_.size());
311  }
312 
313 protected:
315  std::vector<LeaseStatsRow> rows_;
316 
318  std::vector<LeaseStatsRow>::iterator next_pos_;
319 };
320 
331 public:
336  : MemfileLeaseStatsQuery(), storage4_(storage4) {
337  };
338 
343  MemfileLeaseStatsQuery4(Lease4Storage& storage4, const SubnetID& subnet_id)
344  : MemfileLeaseStatsQuery(subnet_id), storage4_(storage4) {
345  };
346 
352  MemfileLeaseStatsQuery4(Lease4Storage& storage4, const SubnetID& first_subnet_id,
353  const SubnetID& last_subnet_id)
354  : MemfileLeaseStatsQuery(first_subnet_id, last_subnet_id), storage4_(storage4) {
355  };
356 
359 
374  void start() {
375  const Lease4StorageSubnetIdIndex& idx
376  = storage4_.get<SubnetIdIndexTag>();
377 
378  // Set lower and upper bounds based on select mode
379  Lease4StorageSubnetIdIndex::const_iterator lower;
380  Lease4StorageSubnetIdIndex::const_iterator upper;
381  switch (getSelectMode()) {
382  case ALL_SUBNETS:
383  lower = idx.begin();
384  upper = idx.end();
385  break;
386 
387  case SINGLE_SUBNET:
388  lower = idx.lower_bound(getFirstSubnetID());
389  upper = idx.upper_bound(getFirstSubnetID());
390  break;
391 
392  case SUBNET_RANGE:
393  lower = idx.lower_bound(getFirstSubnetID());
394  upper = idx.upper_bound(getLastSubnetID());
395  break;
396  }
397 
398  // Return an empty set if there are no rows.
399  if (lower == upper) {
400  return;
401  }
402 
403  // Iterate over the leases in order by subnet, accumulating per
404  // subnet counts for each state of interest. As we finish each
405  // subnet, add the appropriate rows to our result set.
406  SubnetID cur_id = 0;
407  int64_t assigned = 0;
408  int64_t declined = 0;
409  for(Lease4StorageSubnetIdIndex::const_iterator lease = lower;
410  lease != upper; ++lease) {
411  // If we've hit the next subnet, add rows for the current subnet
412  // and wipe the accumulators
413  if ((*lease)->subnet_id_ != cur_id) {
414  if (cur_id > 0) {
415  if (assigned > 0) {
416  rows_.push_back(LeaseStatsRow(cur_id,
418  assigned));
419  assigned = 0;
420  }
421 
422  if (declined > 0) {
423  rows_.push_back(LeaseStatsRow(cur_id,
425  declined));
426  declined = 0;
427  }
428  }
429 
430  // Update current subnet id
431  cur_id = (*lease)->subnet_id_;
432  }
433 
434  // Bump the appropriate accumulator
435  if ((*lease)->state_ == Lease::STATE_DEFAULT) {
436  ++assigned;
437  } else if ((*lease)->state_ == Lease::STATE_DECLINED) {
438  ++declined;
439  }
440  }
441 
442  // Make the rows for last subnet
443  if (assigned > 0) {
444  rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DEFAULT,
445  assigned));
446  }
447 
448  if (declined > 0) {
449  rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DECLINED,
450  declined));
451  }
452 
453  // Reset the next row position back to the beginning of the rows.
454  next_pos_ = rows_.begin();
455  }
456 
457 private:
459  Lease4Storage& storage4_;
460 };
461 
462 
473 public:
478  : MemfileLeaseStatsQuery(), storage6_(storage6) {
479  };
480 
485  MemfileLeaseStatsQuery6(Lease6Storage& storage6, const SubnetID& subnet_id)
486  : MemfileLeaseStatsQuery(subnet_id), storage6_(storage6) {
487  };
488 
494  MemfileLeaseStatsQuery6(Lease6Storage& storage6, const SubnetID& first_subnet_id,
495  const SubnetID& last_subnet_id)
496  : MemfileLeaseStatsQuery(first_subnet_id, last_subnet_id), storage6_(storage6) {
497  };
498 
501 
515  virtual void start() {
516  // Get the subnet_id index
517  const Lease6StorageSubnetIdIndex& idx
518  = storage6_.get<SubnetIdIndexTag>();
519 
520  // Set lower and upper bounds based on select mode
521  Lease6StorageSubnetIdIndex::const_iterator lower;
522  Lease6StorageSubnetIdIndex::const_iterator upper;
523  switch (getSelectMode()) {
524  case ALL_SUBNETS:
525  lower = idx.begin();
526  upper = idx.end();
527  break;
528 
529  case SINGLE_SUBNET:
530  lower = idx.lower_bound(getFirstSubnetID());
531  upper = idx.upper_bound(getFirstSubnetID());
532  break;
533 
534  case SUBNET_RANGE:
535  lower = idx.lower_bound(getFirstSubnetID());
536  upper = idx.upper_bound(getLastSubnetID());
537  break;
538  }
539 
540  // Return an empty set if there are no rows.
541  if (lower == upper) {
542  return;
543  }
544 
545  // Iterate over the leases in order by subnet, accumulating per
546  // subnet counts for each state of interest. As we finish each
547  // subnet, add the appropriate rows to our result set.
548  SubnetID cur_id = 0;
549  int64_t assigned = 0;
550  int64_t declined = 0;
551  int64_t assigned_pds = 0;
552  for(Lease6StorageSubnetIdIndex::const_iterator lease = lower;
553  lease != upper; ++lease) {
554  // If we've hit the next subnet, add rows for the current subnet
555  // and wipe the accumulators
556  if ((*lease)->subnet_id_ != cur_id) {
557  if (cur_id > 0) {
558  if (assigned > 0) {
559  rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
561  assigned));
562  assigned = 0;
563  }
564 
565  if (declined > 0) {
566  rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
568  declined));
569  declined = 0;
570  }
571 
572  if (assigned_pds > 0) {
573  rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
575  assigned_pds));
576  assigned_pds = 0;
577  }
578  }
579 
580  // Update current subnet id
581  cur_id = (*lease)->subnet_id_;
582  }
583 
584  // Bump the appropriate accumulator
585  if ((*lease)->state_ == Lease::STATE_DEFAULT) {
586  switch((*lease)->type_) {
587  case Lease::TYPE_NA:
588  ++assigned;
589  break;
590  case Lease::TYPE_PD:
591  ++assigned_pds;
592  break;
593  default:
594  break;
595  }
596  } else if ((*lease)->state_ == Lease::STATE_DECLINED) {
597  // In theory only NAs can be declined
598  if (((*lease)->type_) == Lease::TYPE_NA) {
599  ++declined;
600  }
601  }
602  }
603 
604  // Make the rows for last subnet, unless there were no rows
605  if (assigned > 0) {
606  rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
607  Lease::STATE_DEFAULT, assigned));
608  }
609 
610  if (declined > 0) {
611  rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
612  Lease::STATE_DECLINED, declined));
613  }
614 
615  if (assigned_pds > 0) {
616  rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
617  Lease::STATE_DEFAULT, assigned_pds));
618  }
619 
620  // Set the next row position to the beginning of the rows.
621  next_pos_ = rows_.begin();
622  }
623 
624 private:
626  Lease6Storage& storage6_;
627 };
628 
629 // Explicit definition of class static constants. Values are given in the
630 // declaration so they're not needed here.
633 
635  : LeaseMgr(), lfc_setup_(), conn_(parameters)
636  {
637  bool conversion_needed = false;
638 
639  // Check the universe and use v4 file or v6 file.
640  std::string universe = conn_.getParameter("universe");
641  if (universe == "4") {
642  std::string file4 = initLeaseFilePath(V4);
643  if (!file4.empty()) {
644  conversion_needed = loadLeasesFromFiles<Lease4,
645  CSVLeaseFile4>(file4,
646  lease_file4_,
647  storage4_);
648  }
649  } else {
650  std::string file6 = initLeaseFilePath(V6);
651  if (!file6.empty()) {
652  conversion_needed = loadLeasesFromFiles<Lease6,
653  CSVLeaseFile6>(file6,
654  lease_file6_,
655  storage6_);
656  }
657  }
658 
659  // If lease persistence have been disabled for both v4 and v6,
660  // issue a warning. It is ok not to write leases to disk when
661  // doing testing, but it should not be done in normal server
662  // operation.
663  if (!persistLeases(V4) && !persistLeases(V6)) {
664  LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_NO_STORAGE);
665  } else {
666  if (conversion_needed) {
667  LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_CONVERTING_LEASE_FILES)
668  .arg(MAJOR_VERSION).arg(MINOR_VERSION);
669  }
670  lfcSetup(conversion_needed);
671  }
672 
673 }
674 
676  if (lease_file4_) {
677  lease_file4_->close();
678  lease_file4_.reset();
679  }
680  if (lease_file6_) {
681  lease_file6_->close();
682  lease_file6_.reset();
683  }
684 }
685 
686 std::string
688  std::stringstream tmp;
689  tmp << "Memfile backend " << MAJOR_VERSION;
690  tmp << "." << MINOR_VERSION;
691  return (tmp.str());
692 }
693 
694 bool
697  DHCPSRV_MEMFILE_ADD_ADDR4).arg(lease->addr_.toText());
698 
699  if (getLease4(lease->addr_)) {
700  // there is a lease with specified address already
701  return (false);
702  }
703 
704  // Try to write a lease to disk first. If this fails, the lease will
705  // not be inserted to the memory and the disk and in-memory data will
706  // remain consistent.
707  if (persistLeases(V4)) {
708  lease_file4_->append(*lease);
709  }
710 
711  storage4_.insert(lease);
712  return (true);
713 }
714 
715 bool
718  DHCPSRV_MEMFILE_ADD_ADDR6).arg(lease->addr_.toText());
719 
720  if (getLease6(lease->type_, lease->addr_)) {
721  // there is a lease with specified address already
722  return (false);
723  }
724 
725  // Try to write a lease to disk first. If this fails, the lease will
726  // not be inserted to the memory and the disk and in-memory data will
727  // remain consistent.
728  if (persistLeases(V6)) {
729  lease_file6_->append(*lease);
730  }
731 
732  storage6_.insert(lease);
733  return (true);
734 }
735 
736 Lease4Ptr
739  DHCPSRV_MEMFILE_GET_ADDR4).arg(addr.toText());
740 
741  const Lease4StorageAddressIndex& idx = storage4_.get<AddressIndexTag>();
742  Lease4StorageAddressIndex::iterator l = idx.find(addr);
743  if (l == idx.end()) {
744  return (Lease4Ptr());
745  } else {
746  return (Lease4Ptr(new Lease4(**l)));
747  }
748 }
749 
751 Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr) const {
753  DHCPSRV_MEMFILE_GET_HWADDR).arg(hwaddr.toText());
754  Lease4Collection collection;
755 
756  // Using composite index by 'hw address' and 'subnet id'. It is
757  // ok to use it for searching by the 'hw address' only.
759  storage4_.get<HWAddressSubnetIdIndexTag>();
760  std::pair<Lease4StorageHWAddressSubnetIdIndex::const_iterator,
761  Lease4StorageHWAddressSubnetIdIndex::const_iterator> l
762  = idx.equal_range(boost::make_tuple(hwaddr.hwaddr_));
763 
764  for(auto lease = l.first; lease != l.second; ++lease) {
765  collection.push_back(Lease4Ptr(new Lease4(**lease)));
766  }
767 
768  return (collection);
769 }
770 
771 Lease4Ptr
772 Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
774  DHCPSRV_MEMFILE_GET_SUBID_HWADDR).arg(subnet_id)
775  .arg(hwaddr.toText());
776 
777  // Get the index by HW Address and Subnet Identifier.
779  storage4_.get<HWAddressSubnetIdIndexTag>();
780  // Try to find the lease using HWAddr and subnet id.
781  Lease4StorageHWAddressSubnetIdIndex::const_iterator lease =
782  idx.find(boost::make_tuple(hwaddr.hwaddr_, subnet_id));
783  // Lease was not found. Return empty pointer to the caller.
784  if (lease == idx.end()) {
785  return (Lease4Ptr());
786  }
787 
788  // Lease was found. Return it to the caller.
789  return (Lease4Ptr(new Lease4(**lease)));
790 }
791 
793 Memfile_LeaseMgr::getLease4(const ClientId& client_id) const {
795  DHCPSRV_MEMFILE_GET_CLIENTID).arg(client_id.toText());
796  Lease4Collection collection;
797  // Using composite index by 'client id' and 'subnet id'. It is ok
798  // to use it to search by 'client id' only.
800  storage4_.get<ClientIdSubnetIdIndexTag>();
801  std::pair<Lease4StorageClientIdSubnetIdIndex::const_iterator,
802  Lease4StorageClientIdSubnetIdIndex::const_iterator> l
803  = idx.equal_range(boost::make_tuple(client_id.getClientId()));
804 
805  for(auto lease = l.first; lease != l.second; ++lease) {
806  collection.push_back(Lease4Ptr(new Lease4(**lease)));
807  }
808 
809  return (collection);
810 }
811 
812 Lease4Ptr
814  const HWAddr& hwaddr,
815  SubnetID subnet_id) const {
817  DHCPSRV_MEMFILE_GET_CLIENTID_HWADDR_SUBID).arg(client_id.toText())
818  .arg(hwaddr.toText())
819  .arg(subnet_id);
820 
821  // Get the index by client id, HW address and subnet id.
823  storage4_.get<ClientIdHWAddressSubnetIdIndexTag>();
824  // Try to get the lease using client id, hardware address and subnet id.
825  Lease4StorageClientIdHWAddressSubnetIdIndex::const_iterator lease =
826  idx.find(boost::make_tuple(client_id.getClientId(), hwaddr.hwaddr_,
827  subnet_id));
828 
829  if (lease == idx.end()) {
830  // Lease was not found. Return empty pointer to the caller.
831  return (Lease4Ptr());
832  }
833 
834  // Lease was found. Return it to the caller.
835  return (*lease);
836 }
837 
838 Lease4Ptr
840  SubnetID subnet_id) const {
842  DHCPSRV_MEMFILE_GET_SUBID_CLIENTID).arg(subnet_id)
843  .arg(client_id.toText());
844 
845  // Get the index by client and subnet id.
847  storage4_.get<ClientIdSubnetIdIndexTag>();
848  // Try to get the lease using client id and subnet id.
849  Lease4StorageClientIdSubnetIdIndex::const_iterator lease =
850  idx.find(boost::make_tuple(client_id.getClientId(), subnet_id));
851  // Lease was not found. Return empty pointer to the caller.
852  if (lease == idx.end()) {
853  return (Lease4Ptr());
854  }
855  // Lease was found. Return it to the caller.
856  return (Lease4Ptr(new Lease4(**lease)));
857 }
858 
861  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_SUBID4)
862  .arg(subnet_id);
863 
864  Lease4Collection collection;
865  const Lease4StorageSubnetIdIndex& idx = storage4_.get<SubnetIdIndexTag>();
866  std::pair<Lease4StorageSubnetIdIndex::const_iterator,
867  Lease4StorageSubnetIdIndex::const_iterator> l =
868  idx.equal_range(subnet_id);
869 
870  for (auto lease = l.first; lease != l.second; ++lease) {
871  collection.push_back(Lease4Ptr(new Lease4(**lease)));
872  }
873 
874  return (collection);
875 }
876 
879  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET4);
880 
881  Lease4Collection collection;
882  for (auto lease = storage4_.begin(); lease != storage4_.end(); ++lease ) {
883  collection.push_back(Lease4Ptr(new Lease4(**lease)));
884  }
885 
886  return (collection);
887 }
888 
891  const LeasePageSize& page_size) const {
892  // Expecting IPv4 address.
893  if (!lower_bound_address.isV4()) {
894  isc_throw(InvalidAddressFamily, "expected IPv4 address while "
895  "retrieving leases from the lease database, got "
896  << lower_bound_address);
897  }
898 
899  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_PAGE4)
900  .arg(page_size.page_size_)
901  .arg(lower_bound_address.toText());
902 
903  Lease4Collection collection;
904  const Lease4StorageAddressIndex& idx = storage4_.get<AddressIndexTag>();
905  Lease4StorageAddressIndex::const_iterator lb = idx.lower_bound(lower_bound_address);
906 
907  // Exclude the lower bound address specified by the caller.
908  if ((lb != idx.end()) && ((*lb)->addr_ == lower_bound_address)) {
909  ++lb;
910  }
911 
912  // Return all other leases being within the page size.
913  for (auto lease = lb;
914  (lease != idx.end()) && (std::distance(lb, lease) < page_size.page_size_);
915  ++lease) {
916  collection.push_back(Lease4Ptr(new Lease4(**lease)));
917  }
918 
919  return (collection);
920 }
921 
922 Lease6Ptr
924  const isc::asiolink::IOAddress& addr) const {
926  DHCPSRV_MEMFILE_GET_ADDR6)
927  .arg(addr.toText())
928  .arg(Lease::typeToText(type));
929  Lease6Storage::iterator l = storage6_.find(addr);
930  if (l == storage6_.end() || !(*l) || ((*l)->type_ != type)) {
931  return (Lease6Ptr());
932  } else {
933  return (Lease6Ptr(new Lease6(**l)));
934  }
935 }
936 
939  const DUID& duid, uint32_t iaid) const {
941  DHCPSRV_MEMFILE_GET_IAID_DUID)
942  .arg(iaid)
943  .arg(duid.toText())
944  .arg(Lease::typeToText(type));
945 
946  // Get the index by DUID, IAID, lease type.
947  const Lease6StorageDuidIaidTypeIndex& idx = storage6_.get<DuidIaidTypeIndexTag>();
948  // Try to get the lease using the DUID, IAID and lease type.
949  std::pair<Lease6StorageDuidIaidTypeIndex::const_iterator,
950  Lease6StorageDuidIaidTypeIndex::const_iterator> l =
951  idx.equal_range(boost::make_tuple(duid.getDuid(), iaid, type));
952  Lease6Collection collection;
953  for(Lease6StorageDuidIaidTypeIndex::const_iterator lease =
954  l.first; lease != l.second; ++lease) {
955  collection.push_back(Lease6Ptr(new Lease6(**lease)));
956  }
957 
958  return (collection);
959 }
960 
963  const DUID& duid, uint32_t iaid,
964  SubnetID subnet_id) const {
966  DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID)
967  .arg(iaid)
968  .arg(subnet_id)
969  .arg(duid.toText())
970  .arg(Lease::typeToText(type));
971 
972  // Get the index by DUID, IAID, lease type.
973  const Lease6StorageDuidIaidTypeIndex& idx = storage6_.get<DuidIaidTypeIndexTag>();
974  // Try to get the lease using the DUID, IAID and lease type.
975  std::pair<Lease6StorageDuidIaidTypeIndex::const_iterator,
976  Lease6StorageDuidIaidTypeIndex::const_iterator> l =
977  idx.equal_range(boost::make_tuple(duid.getDuid(), iaid, type));
978  Lease6Collection collection;
979  for(Lease6StorageDuidIaidTypeIndex::const_iterator lease =
980  l.first; lease != l.second; ++lease) {
981  // Filter out the leases which subnet id doesn't match.
982  if((*lease)->subnet_id_ == subnet_id) {
983  collection.push_back(Lease6Ptr(new Lease6(**lease)));
984  }
985  }
986 
987  return (collection);
988 }
989 
992  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_SUBID6)
993  .arg(subnet_id);
994 
995  Lease6Collection collection;
996  const Lease6StorageSubnetIdIndex& idx = storage6_.get<SubnetIdIndexTag>();
997  std::pair<Lease6StorageSubnetIdIndex::const_iterator,
998  Lease6StorageSubnetIdIndex::const_iterator> l =
999  idx.equal_range(subnet_id);
1000 
1001  for (auto lease = l.first; lease != l.second; ++lease) {
1002  collection.push_back(Lease6Ptr(new Lease6(**lease)));
1003  }
1004 
1005  return (collection);
1006 }
1007 
1010  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET6);
1011 
1012  Lease6Collection collection;
1013  for (auto lease = storage6_.begin(); lease != storage6_.end(); ++lease ) {
1014  collection.push_back(Lease6Ptr(new Lease6(**lease)));
1015  }
1016 
1017  return (collection);
1018 }
1019 
1022  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET6_DUID)
1023  .arg(duid.toText());
1024 
1025  Lease6Collection collection;
1026  const Lease6StorageDuidIndex& idx = storage6_.get<DuidIndexTag>();
1027  std::pair<Lease6StorageDuidIndex::const_iterator,
1028  Lease6StorageDuidIndex::const_iterator> l =
1029  idx.equal_range(duid.getDuid());
1030 
1031  for (auto lease = l.first; lease != l.second; ++lease) {
1032  collection.push_back(Lease6Ptr(new Lease6(**lease)));
1033  }
1034 
1035  return (collection);
1036 }
1037 
1040  const LeasePageSize& page_size) const {
1041  // Expecting IPv6 address.
1042  if (!lower_bound_address.isV6()) {
1043  isc_throw(InvalidAddressFamily, "expected IPv6 address while "
1044  "retrieving leases from the lease database, got "
1045  << lower_bound_address);
1046  }
1047 
1048  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_PAGE6)
1049  .arg(page_size.page_size_)
1050  .arg(lower_bound_address.toText());
1051 
1052  Lease6Collection collection;
1053  const Lease6StorageAddressIndex& idx = storage6_.get<AddressIndexTag>();
1054  Lease6StorageAddressIndex::const_iterator lb = idx.lower_bound(lower_bound_address);
1055 
1056  // Exclude the lower bound address specified by the caller.
1057  if ((lb != idx.end()) && ((*lb)->addr_ == lower_bound_address)) {
1058  ++lb;
1059  }
1060 
1061  // Return all other leases being within the page size.
1062  for (auto lease = lb;
1063  (lease != idx.end()) && (std::distance(lb, lease) < page_size.page_size_);
1064  ++lease) {
1065  collection.push_back(Lease6Ptr(new Lease6(**lease)));
1066  }
1067 
1068  return (collection);
1069 }
1070 
1071 void
1073  const size_t max_leases) const {
1074  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_EXPIRED4)
1075  .arg(max_leases);
1076 
1077  // Obtain the index which segragates leases by state and time.
1078  const Lease4StorageExpirationIndex& index = storage4_.get<ExpirationIndexTag>();
1079 
1080  // Retrieve leases which are not reclaimed and which haven't expired. The
1081  // 'less-than' operator will be used for both components of the index. So,
1082  // for the 'state' 'false' is less than 'true'. Also the leases with
1083  // expiration time lower than current time will be returned.
1084  Lease4StorageExpirationIndex::const_iterator ub =
1085  index.upper_bound(boost::make_tuple(false, time(NULL)));
1086 
1087  // Copy only the number of leases indicated by the max_leases parameter.
1088  for (Lease4StorageExpirationIndex::const_iterator lease = index.begin();
1089  (lease != ub) && ((max_leases == 0) || (std::distance(index.begin(), lease) <
1090  max_leases));
1091  ++lease) {
1092  expired_leases.push_back(Lease4Ptr(new Lease4(**lease)));
1093  }
1094 }
1095 
1096 void
1098  const size_t max_leases) const {
1099  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_EXPIRED6)
1100  .arg(max_leases);
1101 
1102  // Obtain the index which segragates leases by state and time.
1103  const Lease6StorageExpirationIndex& index = storage6_.get<ExpirationIndexTag>();
1104 
1105  // Retrieve leases which are not reclaimed and which haven't expired. The
1106  // 'less-than' operator will be used for both components of the index. So,
1107  // for the 'state' 'false' is less than 'true'. Also the leases with
1108  // expiration time lower than current time will be returned.
1109  Lease6StorageExpirationIndex::const_iterator ub =
1110  index.upper_bound(boost::make_tuple(false, time(NULL)));
1111 
1112  // Copy only the number of leases indicated by the max_leases parameter.
1113  for (Lease6StorageExpirationIndex::const_iterator lease = index.begin();
1114  (lease != ub) && ((max_leases == 0) || (std::distance(index.begin(), lease) <
1115  max_leases));
1116  ++lease) {
1117  expired_leases.push_back(Lease6Ptr(new Lease6(**lease)));
1118  }
1119 }
1120 
1121 void
1124  DHCPSRV_MEMFILE_UPDATE_ADDR4).arg(lease->addr_.toText());
1125 
1126  // Obtain 'by address' index.
1127  Lease4StorageAddressIndex& index = storage4_.get<AddressIndexTag>();
1128 
1129  // Lease must exist if it is to be updated.
1130  Lease4StorageAddressIndex::const_iterator lease_it = index.find(lease->addr_);
1131  if (lease_it == index.end()) {
1132  isc_throw(NoSuchLease, "failed to update the lease with address "
1133  << lease->addr_ << " - no such lease");
1134  }
1135 
1136  // Try to write a lease to disk first. If this fails, the lease will
1137  // not be inserted to the memory and the disk and in-memory data will
1138  // remain consistent.
1139  if (persistLeases(V4)) {
1140  lease_file4_->append(*lease);
1141  }
1142 
1143  // Use replace() to re-index leases.
1144  index.replace(lease_it, Lease4Ptr(new Lease4(*lease)));
1145 }
1146 
1147 void
1150  DHCPSRV_MEMFILE_UPDATE_ADDR6).arg(lease->addr_.toText());
1151 
1152  // Obtain 'by address' index.
1153  Lease6StorageAddressIndex& index = storage6_.get<AddressIndexTag>();
1154 
1155  // Lease must exist if it is to be updated.
1156  Lease6StorageAddressIndex::const_iterator lease_it = index.find(lease->addr_);
1157  if (lease_it == index.end()) {
1158  isc_throw(NoSuchLease, "failed to update the lease with address "
1159  << lease->addr_ << " - no such lease");
1160  }
1161 
1162  // Try to write a lease to disk first. If this fails, the lease will
1163  // not be inserted to the memory and the disk and in-memory data will
1164  // remain consistent.
1165  if (persistLeases(V6)) {
1166  lease_file6_->append(*lease);
1167  }
1168 
1169  // Use replace() to re-index leases.
1170  index.replace(lease_it, Lease6Ptr(new Lease6(*lease)));
1171 }
1172 
1173 bool
1176  DHCPSRV_MEMFILE_DELETE_ADDR).arg(addr.toText());
1177  if (addr.isV4()) {
1178  // v4 lease
1179  Lease4Storage::iterator l = storage4_.find(addr);
1180  if (l == storage4_.end()) {
1181  // No such lease
1182  return (false);
1183  } else {
1184  if (persistLeases(V4)) {
1185  // Copy the lease. The valid lifetime needs to be modified and
1186  // we don't modify the original lease.
1187  Lease4 lease_copy = **l;
1188  // Setting valid lifetime to 0 means that lease is being
1189  // removed.
1190  lease_copy.valid_lft_ = 0;
1191  lease_file4_->append(lease_copy);
1192  }
1193  storage4_.erase(l);
1194  return (true);
1195  }
1196 
1197  } else {
1198  // v6 lease
1199  Lease6Storage::iterator l = storage6_.find(addr);
1200  if (l == storage6_.end()) {
1201  // No such lease
1202  return (false);
1203  } else {
1204  if (persistLeases(V6)) {
1205  // Copy the lease. The lifetimes need to be modified and we
1206  // don't modify the original lease.
1207  Lease6 lease_copy = **l;
1208  // Setting lifetimes to 0 means that lease is being removed.
1209  lease_copy.valid_lft_ = 0;
1210  lease_copy.preferred_lft_ = 0;
1211  lease_file6_->append(lease_copy);
1212  }
1213 
1214  storage6_.erase(l);
1215  return (true);
1216  }
1217  }
1218 }
1219 
1220 uint64_t
1223  DHCPSRV_MEMFILE_DELETE_EXPIRED_RECLAIMED4)
1224  .arg(secs);
1225  return (deleteExpiredReclaimedLeases<
1227  >(secs, V4, storage4_, lease_file4_));
1228 }
1229 
1230 uint64_t
1233  DHCPSRV_MEMFILE_DELETE_EXPIRED_RECLAIMED6)
1234  .arg(secs);
1235  return (deleteExpiredReclaimedLeases<
1237  >(secs, V6, storage6_, lease_file6_));
1238 }
1239 
1240 template<typename IndexType, typename LeaseType, typename StorageType,
1241  typename LeaseFileType>
1242 uint64_t
1243 Memfile_LeaseMgr::deleteExpiredReclaimedLeases(const uint32_t secs,
1244  const Universe& universe,
1245  StorageType& storage,
1246  LeaseFileType& lease_file) const {
1247  // Obtain the index which segragates leases by state and time.
1248  IndexType& index = storage.template get<ExpirationIndexTag>();
1249 
1250  // This returns the first element which is greater than the specified
1251  // tuple (true, time(NULL) - secs). However, the range between the
1252  // beginning of the index and returned element also includes all the
1253  // elements for which the first value is false (lease state is NOT
1254  // reclaimed), because false < true. All elements between the
1255  // beginning of the index and the element returned, for which the
1256  // first value is true, represent the reclaimed leases which should
1257  // be deleted, because their expiration time + secs has occurred earlier
1258  // than current time.
1259  typename IndexType::const_iterator upper_limit =
1260  index.upper_bound(boost::make_tuple(true, time(NULL) - secs));
1261 
1262  // Now, we have to exclude all elements of the index which represent
1263  // leases in the state other than reclaimed - with the first value
1264  // in the index equal to false. Note that elements in the index are
1265  // ordered from the lower to the higher ones. So, all elements with
1266  // the first value of false are placed before the elements with the
1267  // value of true. Hence, we have to find the first element which
1268  // contains value of true. The time value is the lowest possible.
1269  typename IndexType::const_iterator lower_limit =
1270  index.upper_bound(boost::make_tuple(true, std::numeric_limits<int64_t>::min()));
1271 
1272  // If there are some elements in this range, delete them.
1273  uint64_t num_leases = static_cast<uint64_t>(std::distance(lower_limit, upper_limit));
1274  if (num_leases > 0) {
1275 
1277  DHCPSRV_MEMFILE_DELETE_EXPIRED_RECLAIMED_START)
1278  .arg(num_leases);
1279 
1280  // If lease persistence is enabled, we also have to mark leases
1281  // as deleted in the lease file. We do this by setting the
1282  // lifetime to 0.
1283  if (persistLeases(universe)) {
1284  for (typename IndexType::const_iterator lease = lower_limit;
1285  lease != upper_limit; ++lease) {
1286  // Copy lease to not affect the lease in the container.
1287  LeaseType lease_copy(**lease);
1288  // Set the valid lifetime to 0 to indicate the removal
1289  // of the lease.
1290  lease_copy.valid_lft_ = 0;
1291  lease_file->append(lease_copy);
1292  }
1293  }
1294 
1295  // Erase leases from memory.
1296  index.erase(lower_limit, upper_limit);
1297  }
1298  // Return number of leases deleted.
1299  return (num_leases);
1300 }
1301 
1302 
1303 std::string
1305  return (std::string("In memory database with leases stored in a CSV file."));
1306 }
1307 
1308 void
1310  LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_COMMIT);
1311 }
1312 
1313 void
1316  DHCPSRV_MEMFILE_ROLLBACK);
1317 }
1318 
1319 std::string
1320 Memfile_LeaseMgr::appendSuffix(const std::string& file_name,
1321  const LFCFileType& file_type) {
1322  std::string name(file_name);
1323  switch (file_type) {
1324  case FILE_INPUT:
1325  name += ".1";
1326  break;
1327  case FILE_PREVIOUS:
1328  name += ".2";
1329  break;
1330  case FILE_OUTPUT:
1331  name += ".output";
1332  break;
1333  case FILE_FINISH:
1334  name += ".completed";
1335  break;
1336  case FILE_PID:
1337  name += ".pid";
1338  break;
1339  default:
1340  // Do not append any suffix for the FILE_CURRENT.
1341  ;
1342  }
1343 
1344  return (name);
1345 }
1346 
1347 std::string
1349  std::ostringstream s;
1350  s << CfgMgr::instance().getDataDir() << "/kea-leases";
1351  s << (u == V4 ? "4" : "6");
1352  s << ".csv";
1353  return (s.str());
1354 }
1355 
1356 std::string
1358  if (u == V4) {
1359  return (lease_file4_ ? lease_file4_->getFilename() : "");
1360  }
1361 
1362  return (lease_file6_ ? lease_file6_->getFilename() : "");
1363 }
1364 
1365 bool
1367  // Currently, if the lease file IO is not created, it means that writes to
1368  // disk have been explicitly disabled by the administrator. At some point,
1369  // there may be a dedicated ON/OFF flag implemented to control this.
1370  if (u == V4 && lease_file4_) {
1371  return (true);
1372  }
1373 
1374  return (u == V6 && lease_file6_);
1375 }
1376 
1377 std::string
1378 Memfile_LeaseMgr::initLeaseFilePath(Universe u) {
1379  std::string persist_val;
1380  try {
1381  persist_val = conn_.getParameter("persist");
1382  } catch (const Exception&) {
1383  // If parameter persist hasn't been specified, we use a default value
1384  // 'yes'.
1385  persist_val = "true";
1386  }
1387  // If persist_val is 'false' we will not store leases to disk, so let's
1388  // return empty file name.
1389  if (persist_val == "false") {
1390  return ("");
1391 
1392  } else if (persist_val != "true") {
1393  isc_throw(isc::BadValue, "invalid value 'persist="
1394  << persist_val << "'");
1395  }
1396 
1397  std::string lease_file;
1398  try {
1399  lease_file = conn_.getParameter("name");
1400  } catch (const Exception&) {
1401  lease_file = getDefaultLeaseFilePath(u);
1402  }
1403  return (lease_file);
1404 }
1405 
1406 template<typename LeaseObjectType, typename LeaseFileType, typename StorageType>
1407 bool Memfile_LeaseMgr::loadLeasesFromFiles(const std::string& filename,
1408  boost::shared_ptr<LeaseFileType>& lease_file,
1409  StorageType& storage) {
1410  // Check if the instance of the LFC is running right now. If it is
1411  // running, we refuse to load leases as the LFC may be writing to the
1412  // lease files right now. When the user retries server configuration
1413  // it should go through.
1416  PIDFile pid_file(appendSuffix(filename, FILE_PID));
1417  if (pid_file.check()) {
1418  isc_throw(DbOpenError, "unable to load leases from files while the "
1419  "lease file cleanup is in progress");
1420  }
1421 
1422  storage.clear();
1423 
1424  // Load the leasefile.completed, if exists.
1425  bool conversion_needed = false;
1426  lease_file.reset(new LeaseFileType(std::string(filename + ".completed")));
1427  if (lease_file->exists()) {
1428  LeaseFileLoader::load<LeaseObjectType>(*lease_file, storage,
1429  MAX_LEASE_ERRORS);
1430  conversion_needed = conversion_needed || lease_file->needsConversion();
1431  } else {
1432  // If the leasefile.completed doesn't exist, let's load the leases
1433  // from leasefile.2 and leasefile.1, if they exist.
1434  lease_file.reset(new LeaseFileType(appendSuffix(filename, FILE_PREVIOUS)));
1435  if (lease_file->exists()) {
1436  LeaseFileLoader::load<LeaseObjectType>(*lease_file, storage,
1437  MAX_LEASE_ERRORS);
1438  conversion_needed = conversion_needed || lease_file->needsConversion();
1439  }
1440 
1441  lease_file.reset(new LeaseFileType(appendSuffix(filename, FILE_INPUT)));
1442  if (lease_file->exists()) {
1443  LeaseFileLoader::load<LeaseObjectType>(*lease_file, storage,
1444  MAX_LEASE_ERRORS);
1445  conversion_needed = conversion_needed || lease_file->needsConversion();
1446  }
1447  }
1448 
1449  // Always load leases from the primary lease file. If the lease file
1450  // doesn't exist it will be created by the LeaseFileLoader. Note
1451  // that the false value passed as the last parameter to load
1452  // function causes the function to leave the file open after
1453  // it is parsed. This file will be used by the backend to record
1454  // future lease updates.
1455  lease_file.reset(new LeaseFileType(filename));
1456  LeaseFileLoader::load<LeaseObjectType>(*lease_file, storage,
1457  MAX_LEASE_ERRORS, false);
1458  conversion_needed = conversion_needed || lease_file->needsConversion();
1459 
1460  return (conversion_needed);
1461 }
1462 
1463 
1464 bool
1466  return (lfc_setup_->isRunning());
1467 }
1468 
1469 int
1471  return (lfc_setup_->getExitStatus());
1472 }
1473 
1474 void
1476  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_START);
1477 
1478  // Check if we're in the v4 or v6 space and use the appropriate file.
1479  if (lease_file4_) {
1480  lfcExecute(lease_file4_);
1481 
1482  } else if (lease_file6_) {
1483  lfcExecute(lease_file6_);
1484  }
1485 }
1486 
1487 void
1488 Memfile_LeaseMgr::lfcSetup(bool conversion_needed) {
1489  std::string lfc_interval_str = "3600";
1490  try {
1491  lfc_interval_str = conn_.getParameter("lfc-interval");
1492  } catch (const std::exception&) {
1493  // Ignore and default to 3600.
1494  }
1495 
1496  uint32_t lfc_interval = 0;
1497  try {
1498  lfc_interval = boost::lexical_cast<uint32_t>(lfc_interval_str);
1499  } catch (boost::bad_lexical_cast&) {
1500  isc_throw(isc::BadValue, "invalid value of the lfc-interval "
1501  << lfc_interval_str << " specified");
1502  }
1503 
1504  if (lfc_interval > 0 || conversion_needed) {
1505  lfc_setup_.reset(new LFCSetup(boost::bind(&Memfile_LeaseMgr::lfcCallback, this)));
1506  lfc_setup_->setup(lfc_interval, lease_file4_, lease_file6_, conversion_needed);
1507  }
1508 }
1509 
1510 template<typename LeaseFileType>
1511 void Memfile_LeaseMgr::lfcExecute(boost::shared_ptr<LeaseFileType>& lease_file) {
1512  bool do_lfc = true;
1513 
1514  // Check the status of the LFC instance.
1515  // If the finish file exists or the copy of the lease file exists it
1516  // is an indication that another LFC instance may be in progress or
1517  // may be stalled. In that case we don't want to rotate the current
1518  // lease file to avoid overriding the contents of the existing file.
1519  CSVFile lease_file_finish(appendSuffix(lease_file->getFilename(), FILE_FINISH));
1520  CSVFile lease_file_copy(appendSuffix(lease_file->getFilename(), FILE_INPUT));
1521  if (!lease_file_finish.exists() && !lease_file_copy.exists()) {
1522  // Close the current file so as we can move it to the copy file.
1523  lease_file->close();
1524  // Move the current file to the copy file. Remember the result
1525  // because we don't want to run LFC if the rename failed.
1526  do_lfc = (rename(lease_file->getFilename().c_str(),
1527  lease_file_copy.getFilename().c_str()) == 0);
1528 
1529  if (!do_lfc) {
1530  LOG_ERROR(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_LEASE_FILE_RENAME_FAIL)
1531  .arg(lease_file->getFilename())
1532  .arg(lease_file_copy.getFilename())
1533  .arg(strerror(errno));
1534  }
1535 
1536  // Regardless if we successfully moved the current file or not,
1537  // we need to re-open the current file for the server to write
1538  // new lease updates. If the file has been successfully moved,
1539  // this will result in creation of the new file. Otherwise,
1540  // an existing file will be opened.
1541  try {
1542  lease_file->open(true);
1543 
1544  } catch (const CSVFileError& ex) {
1545  // If we're unable to open the lease file this is a serious
1546  // error because the server will not be able to persist
1547  // leases.
1554  LOG_ERROR(dhcpsrv_logger, DHCPSRV_MEMFILE_LFC_LEASE_FILE_REOPEN_FAIL)
1555  .arg(lease_file->getFilename())
1556  .arg(ex.what());
1557  // Reset the pointer to the file so as the backend doesn't
1558  // try to write leases to disk.
1559  lease_file.reset();
1560  do_lfc = false;
1561  }
1562  }
1563  // Once the files have been rotated, or untouched if another LFC had
1564  // not finished, a new process is started.
1565  if (do_lfc) {
1566  lfc_setup_->execute();
1567  }
1568 }
1569 
1572  LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_));
1573  query->start();
1574  return(query);
1575 }
1576 
1579  LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_, subnet_id));
1580  query->start();
1581  return(query);
1582 }
1583 
1586  const SubnetID& last_subnet_id) {
1587  LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_, first_subnet_id,
1588  last_subnet_id));
1589  query->start();
1590  return(query);
1591 }
1592 
1595  LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_));
1596  query->start();
1597  return(query);
1598 }
1599 
1602  LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, subnet_id));
1603  query->start();
1604  return(query);
1605 }
1606 
1609  const SubnetID& last_subnet_id) {
1610  LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, first_subnet_id,
1611  last_subnet_id));
1612  query->start();
1613  return(query);
1614 }
1615 
1616 size_t Memfile_LeaseMgr::wipeLeases4(const SubnetID& subnet_id) {
1617  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES4)
1618  .arg(subnet_id);
1619 
1620  // Get the index by DUID, IAID, lease type.
1621  const Lease4StorageSubnetIdIndex& idx = storage4_.get<SubnetIdIndexTag>();
1622 
1623  // Try to get the lease using the DUID, IAID and lease type.
1624  std::pair<Lease4StorageSubnetIdIndex::const_iterator,
1625  Lease4StorageSubnetIdIndex::const_iterator> l =
1626  idx.equal_range(subnet_id);
1627 
1628  // Let's collect all leases.
1629  Lease4Collection leases;
1630  for(auto lease = l.first; lease != l.second; ++lease) {
1631  leases.push_back(*lease);
1632  }
1633 
1634  size_t num = leases.size();
1635  for (auto l = leases.begin(); l != leases.end(); ++l) {
1636  deleteLease((*l)->addr_);
1637  }
1638  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES4_FINISHED)
1639  .arg(subnet_id).arg(num);
1640 
1641  return (num);
1642 }
1643 
1644 size_t Memfile_LeaseMgr::wipeLeases6(const SubnetID& subnet_id) {
1645  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES6)
1646  .arg(subnet_id);
1647 
1648  // Get the index by DUID, IAID, lease type.
1649  const Lease6StorageSubnetIdIndex& idx = storage6_.get<SubnetIdIndexTag>();
1650 
1651  // Try to get the lease using the DUID, IAID and lease type.
1652  std::pair<Lease6StorageSubnetIdIndex::const_iterator,
1653  Lease6StorageSubnetIdIndex::const_iterator> l =
1654  idx.equal_range(subnet_id);
1655 
1656  // Let's collect all leases.
1657  Lease6Collection leases;
1658  for(auto lease = l.first; lease != l.second; ++lease) {
1659  leases.push_back(*lease);
1660  }
1661 
1662  size_t num = leases.size();
1663  for (auto l = leases.begin(); l != leases.end(); ++l) {
1664  deleteLease((*l)->addr_);
1665  }
1666  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES6_FINISHED)
1667  .arg(subnet_id).arg(num);
1668 
1669  return (num);
1670 }
1671 
1672 
1673 } // end of namespace isc::dhcp
1674 } // end of namespace isc
isc::dhcp::Memfile_LeaseMgr::wipeLeases6
virtual size_t wipeLeases6(const SubnetID &subnet_id)
Removed specified IPv6 leases.
Definition: memfile_lease_mgr.cc:1644
isc::dhcp::LeasePageSize
Wraps value holding size of the page with leases.
Definition: lease_mgr.h:43
isc::dhcp::MemfileLeaseStatsQuery::next_pos_
std::vector< LeaseStatsRow >::iterator next_pos_
An iterator for accessing the next row within the result set.
Definition: memfile_lease_mgr.cc:318
isc::dhcp::Memfile_LeaseMgr::commit
virtual void commit()
Commit Transactions.
Definition: memfile_lease_mgr.cc:1309
isc::dhcp::Memfile_LeaseMgr::deleteExpiredReclaimedLeases6
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes all expired-reclaimed DHCPv6 leases.
Definition: memfile_lease_mgr.cc:1231
isc::dhcp::Memfile_LeaseMgr::getDBVersion
static std::string getDBVersion()
Local version of getDBVersion() class method.
Definition: memfile_lease_mgr.cc:687
isc::dhcp::Memfile_LeaseMgr::~Memfile_LeaseMgr
virtual ~Memfile_LeaseMgr()
Destructor (closes file)
Definition: memfile_lease_mgr.cc:675
isc::dhcp::Memfile_LeaseMgr::startSubnetLeaseStatsQuery4
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: memfile_lease_mgr.cc:1578
isc::dhcp::ExpirationIndexTag
Tag for indexes by expiration time.
Definition: memfile_lease_storage.h:34
isc::dhcp::Memfile_LeaseMgr::updateLease6
virtual void updateLease6(const Lease6Ptr &lease6)
Updates IPv6 lease.
Definition: memfile_lease_mgr.cc:1148
isc::dhcp::MemfileLeaseStatsQuery6::start
virtual void start()
Creates the IPv6 lease statistical data result set.
Definition: memfile_lease_mgr.cc:515
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
isc::dhcp::LFCSetup::execute
void execute()
Spawns a new process.
Definition: memfile_lease_mgr.cc:231
signal_set.h
isc::dhcp::Memfile_LeaseMgr::FILE_FINISH
@ FILE_FINISH
LFC Finish File.
Definition: memfile_lease_mgr.h:537
isc::dhcp::Memfile_LeaseMgr::startSubnetRangeLeaseStatsQuery6
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: memfile_lease_mgr.cc:1608
isc::dhcp::Memfile_LeaseMgr::FILE_PID
@ FILE_PID
PID File.
Definition: memfile_lease_mgr.h:538
isc::dhcp::Lease6StorageSubnetIdIndex
Lease6Storage::index< SubnetIdIndexTag >::type Lease6StorageSubnetIdIndex
DHCPv6 lease storage index by Subnet-id.
Definition: memfile_lease_storage.h:263
isc::dhcp::Memfile_LeaseMgr::rollback
virtual void rollback()
Rollback Transactions.
Definition: memfile_lease_mgr.cc:1314
isc::dhcp::Memfile_LeaseMgr::getLeaseFilePath
std::string getLeaseFilePath(Universe u) const
Returns an absolute path to the lease file.
Definition: memfile_lease_mgr.cc:1357
isc::dhcp::Lease4Ptr
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition: lease.h:245
isc::dhcp::Memfile_LeaseMgr::persistLeases
bool persistLeases(Universe u) const
Specifies whether or not leases are written to disk.
Definition: memfile_lease_mgr.cc:1366
isc::db
Definition: cql_connection.cc:29
isc::dhcp::Lease4StorageExpirationIndex
Lease4Storage::index< ExpirationIndexTag >::type Lease4StorageExpirationIndex
DHCPv4 lease storage index by expiration time.
Definition: memfile_lease_storage.h:272
isc::dhcp::HWAddr::toText
std::string toText(bool include_htype=true) const
Returns textual representation of a hardware address (e.g.
Definition: hwaddr.cc:51
isc::dhcp::LFCSetup::setup
void setup(const uint32_t lfc_interval, const boost::shared_ptr< CSVLeaseFile4 > &lease_file4, const boost::shared_ptr< CSVLeaseFile6 > &lease_file6, bool run_once_now=false)
Sets the new configuration for the Lease File Cleanup.
Definition: memfile_lease_mgr.cc:155
isc::dhcp::DuidIndexTag
Tag for index using DUID.
Definition: memfile_lease_storage.h:49
isc::dhcp::Lease::STATE_DEFAULT
static const uint32_t STATE_DEFAULT
A lease in the default state.
Definition: lease.h:61
lease_file_loader.h
isc::dhcp::LeaseMgr
Abstract Lease Manager.
Definition: lease_mgr.h:222
isc::dhcp::Lease6Ptr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:460
isc::util::PIDFile
Class to help with processing PID files.
Definition: pid_file.h:40
isc::dhcp::MemfileLeaseStatsQuery6
Memfile derivation of the IPv6 statistical lease data query.
Definition: memfile_lease_mgr.cc:472
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition: dhcpsrv_log.h:38
isc::dhcp::Memfile_LeaseMgr::getLease4
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const
Returns existing IPv4 lease for specified IPv4 address.
Definition: memfile_lease_mgr.cc:737
isc::dhcp::Memfile_LeaseMgr::getDefaultLeaseFilePath
std::string getDefaultLeaseFilePath(Universe u) const
Returns default path to the lease file.
Definition: memfile_lease_mgr.cc:1348
isc::util::ProcessSpawn
Utility class for spawning new processes.
Definition: process_spawn.h:60
isc::dhcp::Lease::STATE_DECLINED
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:64
isc::dhcp::Lease::Type
Type
Type of lease or pool.
Definition: lease.h:38
isc::dhcp::Memfile_LeaseMgr::Universe
Universe
Specifies universe (V4, V6)
Definition: memfile_lease_mgr.h:104
isc::dhcp::DuidIaidTypeIndexTag
Tag for indexes by DUID, IAID, lease type tuple.
Definition: memfile_lease_storage.h:31
isc::dhcp::MemfileLeaseStatsQuery::MemfileLeaseStatsQuery
MemfileLeaseStatsQuery()
Constructor for all subnets query.
Definition: memfile_lease_mgr.cc:266
isc::db::InvalidAddressFamily
Invalid address family used as input to Lease Manager.
Definition: db_exceptions.h:64
isc::dhcp::LeaseStatsQuery::SUBNET_RANGE
@ SUBNET_RANGE
Definition: lease_mgr.h:134
isc::dhcp::HWAddr
Hardware type that represents information from DHCPv4 packet.
Definition: hwaddr.h:20
isc::dhcp::MemfileLeaseStatsQuery4::MemfileLeaseStatsQuery4
MemfileLeaseStatsQuery4(Lease4Storage &storage4)
Constructor for an all subnets query.
Definition: memfile_lease_mgr.cc:335
isc::dhcp::LeaseStatsQuery::getFirstSubnetID
SubnetID getFirstSubnetID() const
Returns the value of first subnet ID specified (or zero)
Definition: lease_mgr.h:178
isc::dhcp::Memfile_LeaseMgr::startSubnetLeaseStatsQuery6
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: memfile_lease_mgr.cc:1601
isc::dhcp::LeaseStatsQuery::SINGLE_SUBNET
@ SINGLE_SUBNET
Definition: lease_mgr.h:133
isc::dhcp::MemfileLeaseStatsQuery6::MemfileLeaseStatsQuery6
MemfileLeaseStatsQuery6(Lease6Storage &storage6)
Constructor.
Definition: memfile_lease_mgr.cc:477
isc::dhcp::Lease6Storage
boost::multi_index_container< Lease6Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< AddressIndexTag >, boost::multi_index::member< Lease, isc::asiolink::IOAddress, &Lease::addr_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< DuidIaidTypeIndexTag >, boost::multi_index::composite_key< Lease6, boost::multi_index::const_mem_fun< Lease6, const std::vector< uint8_t > &, &Lease6::getDuidVector >, boost::multi_index::member< Lease6, uint32_t, &Lease6::iaid_ >, boost::multi_index::member< Lease6, Lease::Type, &Lease6::type_ > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< ExpirationIndexTag >, boost::multi_index::composite_key< Lease6, boost::multi_index::const_mem_fun< Lease, bool, &Lease::stateExpiredReclaimed >, boost::multi_index::const_mem_fun< Lease, int64_t, &Lease::getExpirationTime > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetIdIndexTag >, boost::multi_index::member< Lease, isc::dhcp::SubnetID, &Lease::subnet_id_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< DuidIndexTag >, boost::multi_index::const_mem_fun< Lease6, const std::vector< uint8_t > &, &Lease6::getDuidVector > > >> Lease6Storage
A multi index container holding DHCPv6 leases.
Definition: memfile_lease_storage.h:130
timer_mgr.h
isc::dhcp::HWAddr::hwaddr_
std::vector< uint8_t > hwaddr_
Definition: hwaddr.h:98
isc::dhcp::Memfile_LeaseMgr::FILE_PREVIOUS
@ FILE_PREVIOUS
Previous Lease File.
Definition: memfile_lease_mgr.h:535
isc::dhcp::ClientId::toText
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:121
isc::dhcp::ClientId::getClientId
const std::vector< uint8_t > & getClientId() const
Returns reference to the client-id data.
Definition: duid.cc:116
isc::dhcp::Memfile_LeaseMgr::MAJOR_VERSION
static const int MAJOR_VERSION
Definition: memfile_lease_mgr.h:90
isc::dhcp::MemfileLeaseStatsQuery6::MemfileLeaseStatsQuery6
MemfileLeaseStatsQuery6(Lease6Storage &storage6, const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Constructor for a subnet range query.
Definition: memfile_lease_mgr.cc:494
isc::dhcp::Memfile_LeaseMgr::FILE_OUTPUT
@ FILE_OUTPUT
LFC Output File.
Definition: memfile_lease_mgr.h:536
pid_file.h
isc::dhcp::MemfileLeaseStatsQuery4::MemfileLeaseStatsQuery4
MemfileLeaseStatsQuery4(Lease4Storage &storage4, const SubnetID &subnet_id)
Constructor for a single subnet query.
Definition: memfile_lease_mgr.cc:343
isc::dhcp::Memfile_LeaseMgr::startLeaseStatsQuery6
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query.
Definition: memfile_lease_mgr.cc:1594
isc::dhcp::CSVLeaseFile6
Provides methods to access CSV file with DHCPv6 leases.
Definition: csv_lease_file6.h:33
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition: exceptions/exceptions.h:23
isc::dhcp::MemfileLeaseStatsQuery4::MemfileLeaseStatsQuery4
MemfileLeaseStatsQuery4(Lease4Storage &storage4, const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Constructor for a subnet range query.
Definition: memfile_lease_mgr.cc:352
isc::dhcp::NoSuchLease
Attempt to update lease that was not there.
Definition: dhcpsrv_exceptions.h:16
isc::dhcp::MemfileLeaseStatsQuery::rows_
std::vector< LeaseStatsRow > rows_
A vector containing the "result set".
Definition: memfile_lease_mgr.cc:315
isc::dhcp::MemfileLeaseStatsQuery::MemfileLeaseStatsQuery
MemfileLeaseStatsQuery(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Constructor for subnet range query.
Definition: memfile_lease_mgr.cc:281
isc::util
Definition: edns.h:19
isc::dhcp::CfgMgr::getDataDir
std::string getDataDir() const
returns path do the data directory
Definition: cfgmgr.cc:30
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc::dhcp::Memfile_LeaseMgr::addLease
virtual bool addLease(const Lease4Ptr &lease)
Adds an IPv4 lease.
Definition: memfile_lease_mgr.cc:695
isc::dhcp::Memfile_LeaseMgr::appendSuffix
static std::string appendSuffix(const std::string &file_name, const LFCFileType &file_type)
Appends appropriate suffix to the file name.
Definition: memfile_lease_mgr.cc:1320
isc::dhcp::MemfileLeaseStatsQuery4::~MemfileLeaseStatsQuery4
virtual ~MemfileLeaseStatsQuery4()
Destructor.
Definition: memfile_lease_mgr.cc:358
isc::db::DatabaseConnection::getParameter
std::string getParameter(const std::string &name) const
Returns value of a connection parameter.
Definition: database_connection.cc:28
isc::dhcp::LeaseStatsQuery::getSelectMode
SelectMode getSelectMode() const
Returns the selection criteria mode The value returned is based upon the constructor variant used and...
Definition: lease_mgr.h:190
isc::dhcp::TimerMgr
Manages a pool of asynchronous interval timers.
Definition: timer_mgr.h:54
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition: exceptions/exceptions.cc:32
isc::dhcp::Lease4Storage
boost::multi_index_container< Lease4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< AddressIndexTag >, boost::multi_index::member< Lease, isc::asiolink::IOAddress, &Lease::addr_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< HWAddressSubnetIdIndexTag >, boost::multi_index::composite_key< Lease4, boost::multi_index::const_mem_fun< Lease, const std::vector< uint8_t > &, &Lease::getHWAddrVector >, boost::multi_index::member< Lease, SubnetID, &Lease::subnet_id_ > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< ClientIdSubnetIdIndexTag >, boost::multi_index::composite_key< Lease4, boost::multi_index::const_mem_fun< Lease4, const std::vector< uint8_t > &, &Lease4::getClientIdVector >, boost::multi_index::member< Lease, uint32_t, &Lease::subnet_id_ > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< ClientIdHWAddressSubnetIdIndexTag >, boost::multi_index::composite_key< Lease4, boost::multi_index::const_mem_fun< Lease4, const std::vector< uint8_t > &, &Lease4::getClientIdVector >, boost::multi_index::const_mem_fun< Lease, const std::vector< uint8_t > &, &Lease::getHWAddrVector >, boost::multi_index::member< Lease, SubnetID, &Lease::subnet_id_ > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< ExpirationIndexTag >, boost::multi_index::composite_key< Lease4, boost::multi_index::const_mem_fun< Lease, bool, &Lease::stateExpiredReclaimed >, boost::multi_index::const_mem_fun< Lease, int64_t, &Lease::getExpirationTime > > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetIdIndexTag >, boost::multi_index::member< Lease, isc::dhcp::SubnetID, &Lease::subnet_id_ > > >> Lease4Storage
A multi index container holding DHCPv4 leases.
Definition: memfile_lease_storage.h:245
isc::dhcp::Memfile_LeaseMgr::getLease6
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const
Returns existing IPv6 lease for a given IPv6 address.
Definition: memfile_lease_mgr.cc:923
isc::dhcp::Lease::valid_lft_
uint32_t valid_lft_
Valid lifetime.
Definition: lease.h:125
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
isc::dhcp::MemfileLeaseStatsQuery::MemfileLeaseStatsQuery
MemfileLeaseStatsQuery(const SubnetID &subnet_id)
Constructor for single subnet query.
Definition: memfile_lease_mgr.cc:273
isc::InvalidOperation
A generic exception that is thrown if a function is called in a prohibited way.
Definition: exceptions/exceptions.h:143
isc::dhcp::Lease6
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:471
isc::dhcp::Lease::TYPE_PD
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:41
isc::dhcp::Memfile_LeaseMgr::getLeases4
virtual Lease4Collection getLeases4() const
Returns all IPv4 leases.
Definition: memfile_lease_mgr.cc:878
dhcpsrv_log.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::dhcp::Memfile_LeaseMgr::getExpiredLeases6
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv6 leases.
Definition: memfile_lease_mgr.cc:1097
isc::dhcp::HWAddressSubnetIdIndexTag
Tag for indexes by HW address, subnet identifier tuple.
Definition: memfile_lease_storage.h:37
isc::dhcp::ClientId
Holds Client identifier or client IPv4 address.
Definition: duid.h:111
isc::dhcp::DHCPSRV_DBG_TRACE
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition: dhcpsrv_log.h:26
isc::dhcp::Memfile_LeaseMgr::getExpiredLeases4
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const
Returns a collection of expired DHCPv4 leases.
Definition: memfile_lease_mgr.cc:1072
isc::dhcp::MemfileLeaseStatsQuery::~MemfileLeaseStatsQuery
virtual ~MemfileLeaseStatsQuery()
Destructor.
Definition: memfile_lease_mgr.cc:286
isc::dhcp::DUID::toText
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:74
isc::util::CSVFile
Provides input/output access to CSV files.
Definition: csv_file.h:290
isc::dhcp::Memfile_LeaseMgr::startSubnetRangeLeaseStatsQuery4
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: memfile_lease_mgr.cc:1585
isc::util::ProcessArgs
std::vector< std::string > ProcessArgs
Type of the container holding arguments of the executable being run as a background process.
Definition: process_spawn.h:28
isc::dhcp::Lease6StorageDuidIaidTypeIndex
Lease6Storage::index< DuidIaidTypeIndexTag >::type Lease6StorageDuidIaidTypeIndex
DHCPv6 lease storage index by DUID, IAID, lease type.
Definition: memfile_lease_storage.h:257
isc::dhcp::LeasePageSize::page_size_
const size_t page_size_
Holds page size.
Definition: lease_mgr.h:53
memfile_lease_mgr.h
isc::dhcp::Lease4StorageClientIdSubnetIdIndex
Lease4Storage::index< ClientIdSubnetIdIndexTag >::type Lease4StorageClientIdSubnetIdIndex
DHCPv4 lease storage index by client and subnet identifier.
Definition: memfile_lease_storage.h:280
isc::dhcp::MemfileLeaseStatsQuery6::MemfileLeaseStatsQuery6
MemfileLeaseStatsQuery6(Lease6Storage &storage6, const SubnetID &subnet_id)
Constructor for a single subnet query.
Definition: memfile_lease_mgr.cc:485
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
isc::dhcp::ClientIdSubnetIdIndexTag
Tag for indexes by client and subnet identifiers.
Definition: memfile_lease_storage.h:40
isc::dhcp::LFCSetup::isRunning
bool isRunning() const
Checks if the lease file cleanup is in progress.
Definition: memfile_lease_mgr.cc:243
isc::dhcp::Memfile_LeaseMgr::wipeLeases4
virtual size_t wipeLeases4(const SubnetID &subnet_id)
Removes specified IPv4 leases.
Definition: memfile_lease_mgr.cc:1616
isc::dhcp::Memfile_LeaseMgr::MINOR_VERSION
static const int MINOR_VERSION
Defines minor version of the memfile backend.
Definition: memfile_lease_mgr.h:93
isc::dhcp::Memfile_LeaseMgr::FILE_INPUT
@ FILE_INPUT
Lease File Copy
Definition: memfile_lease_mgr.h:534
isc::dhcp::AddressIndexTag
Tag for indexes by address.
Definition: memfile_lease_storage.h:28
isc::dhcp::MemfileLeaseStatsQuery::getRowCount
int getRowCount() const
Returns the number of rows in the result set.
Definition: memfile_lease_mgr.cc:309
isc::dhcp::Memfile_LeaseMgr::startLeaseStatsQuery4
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query.
Definition: memfile_lease_mgr.cc:1571
isc::dhcp::MemfileLeaseStatsQuery4
Memfile derivation of the IPv4 statistical lease data query.
Definition: memfile_lease_mgr.cc:330
isc::dhcp::Memfile_LeaseMgr::lfcCallback
virtual void lfcCallback()
A callback function triggering Lease File Cleanup (LFC).
Definition: memfile_lease_mgr.cc:1475
isc::dhcp::DUID::getDuid
const std::vector< uint8_t > & getDuid() const
Returns a const reference to the actual DUID value.
Definition: duid.cc:44
isc::dhcp::Lease6StorageAddressIndex
Lease6Storage::index< AddressIndexTag >::type Lease6StorageAddressIndex
DHCPv6 lease storage index by address.
Definition: memfile_lease_storage.h:254
isc::dhcp::LFCSetup
Represents a configuration for Lease File Cleanup.
Definition: memfile_lease_mgr.cc:63
isc::dhcp::Memfile_LeaseMgr::deleteExpiredReclaimedLeases4
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes all expired-reclaimed DHCPv4 leases.
Definition: memfile_lease_mgr.cc:1221
isc::dhcp::Memfile_LeaseMgr::Memfile_LeaseMgr
Memfile_LeaseMgr(const db::DatabaseConnection::ParameterMap &parameters)
The sole lease manager constructor.
Definition: memfile_lease_mgr.cc:634
database_connection.h
isc::dhcp::LeaseStatsQuery
Base class for fulfilling a statistical lease data query.
Definition: lease_mgr.h:128
isc::dhcp::Lease4StorageSubnetIdIndex
Lease4Storage::index< SubnetIdIndexTag >::type Lease4StorageSubnetIdIndex
DHCPv4 lease storage index by client id, HW address and subnet id.
Definition: memfile_lease_storage.h:287
cfgmgr.h
isc::dhcp::Lease4StorageClientIdHWAddressSubnetIdIndex
Lease4Storage::index< ClientIdHWAddressSubnetIdIndexTag >::type Lease4StorageClientIdHWAddressSubnetIdIndex
DHCPv4 lease storage index by client id, HW address and subnet id.
Definition: memfile_lease_storage.h:284
isc::dhcp::TimerMgrPtr
boost::shared_ptr< TimerMgr > TimerMgrPtr
Type definition of the shared pointer to TimerMgr.
Definition: timer_mgr.h:22
isc::util::CSVFileError
Exception thrown when an error occurs during CSV file processing.
Definition: csv_file.h:22
isc::dhcp::MemfileLeaseStatsQuery
Base Memfile derivation of the statistical lease data query.
Definition: memfile_lease_mgr.cc:262
isc::dhcp::Memfile_LeaseMgr::V6
@ V6
Definition: memfile_lease_mgr.h:106
isc::dhcp::Lease4Collection
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
Definition: lease.h:455
exceptions.h
isc::dhcp::CSVLeaseFile4
Provides methods to access CSV file with DHCPv4 leases.
Definition: csv_lease_file4.h:34
isc::util::ProcessSpawnError
Exception thrown when error occurs during spawning a process.
Definition: process_spawn.h:20
isc::dhcp::LeaseStatsQueryPtr
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Definition: lease_mgr.h:207
isc::dhcp::Memfile_LeaseMgr::V4
@ V4
Definition: memfile_lease_mgr.h:105
isc::dhcp::DUID
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
isc::dhcp::LFCSetup::~LFCSetup
~LFCSetup()
Destructor.
Definition: memfile_lease_mgr.cc:131
isc::dhcp::SubnetIdIndexTag
Tag for indexs by subnet-id.
Definition: memfile_lease_storage.h:46
isc::dhcp::Lease6::preferred_lft_
uint32_t preferred_lft_
preferred lifetime
Definition: lease.h:497
isc::dhcp::LeaseStatsQuery::getLastSubnetID
SubnetID getLastSubnetID() const
Returns the value of last subnet ID specified (or zero)
Definition: lease_mgr.h:183
isc::dhcp::Memfile_LeaseMgr::getLFCExitStatus
int getLFCExitStatus() const
Returns the status code returned by the last executed LFC process.
Definition: memfile_lease_mgr.cc:1470
isc::dhcp::Memfile_LeaseMgr::LFCFileType
LFCFileType
Types of the lease files used by the Lease File Cleanup.
Definition: memfile_lease_mgr.h:532
isc::db::DbOpenError
Exception thrown on failure to open database.
Definition: database_connection.h:29
isc::dhcp::Lease::typeToText
static std::string typeToText(Type type)
returns text representation of a lease type
Definition: lease.cc:39
isc::dhcp::Lease6StorageExpirationIndex
Lease6Storage::index< ExpirationIndexTag >::type Lease6StorageExpirationIndex
DHCPv6 lease storage index by expiration time.
Definition: memfile_lease_storage.h:260
isc::dhcp::SubnetID
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24
isc::dhcp::LeaseStatsRow
Contains a single row of lease statistical data.
Definition: lease_mgr.h:61
isc::dhcp::Lease6Collection
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:604
isc::db::DatabaseConnection::ParameterMap
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Definition: database_connection.h:152
isc::dhcp::MemfileLeaseStatsQuery4::start
void start()
Creates the IPv4 lease statistical data result set.
Definition: memfile_lease_mgr.cc:374
isc::dhcp::LeaseStatsQuery::ALL_SUBNETS
@ ALL_SUBNETS
Definition: lease_mgr.h:132
process_spawn.h
dhcpsrv_exceptions.h
isc::dhcp::Lease::TYPE_NA
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:39
isc::dhcp::Memfile_LeaseMgr::isLFCRunning
bool isLFCRunning() const
Checks if the process performing lease file cleanup is running.
Definition: memfile_lease_mgr.cc:1465
isc::dhcp::ClientIdHWAddressSubnetIdIndexTag
Tag for indexes by client id, HW address and subnet id.
Definition: memfile_lease_storage.h:43
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
isc::dhcp::Memfile_LeaseMgr::updateLease4
virtual void updateLease4(const Lease4Ptr &lease4)
Updates IPv4 lease.
Definition: memfile_lease_mgr.cc:1122
isc::dhcp::Lease6StorageDuidIndex
Lease6Storage::index< DuidIndexTag >::type Lease6StorageDuidIndex
DHCPv6 lease storage index by Subnet-id.
Definition: memfile_lease_storage.h:266
isc::dhcp::Lease4StorageAddressIndex
Lease4Storage::index< AddressIndexTag >::type Lease4StorageAddressIndex
DHCPv4 lease storage index by address.
Definition: memfile_lease_storage.h:269
isc::dhcp::Memfile_LeaseMgr::deleteLease
virtual bool deleteLease(const isc::asiolink::IOAddress &addr)
Deletes a lease.
Definition: memfile_lease_mgr.cc:1174
isc::dhcp::LFCSetup::getExitStatus
int getExitStatus() const
Returns exit code of the last completed cleanup.
Definition: memfile_lease_mgr.cc:248
isc::dhcp::Memfile_LeaseMgr::getDescription
virtual std::string getDescription() const
Returns description of the backend.
Definition: memfile_lease_mgr.cc:1304
isc::dhcp::Memfile_LeaseMgr::getLeases6
virtual Lease6Collection getLeases6() const
Returns all IPv6 leases.
Definition: memfile_lease_mgr.cc:1009
isc::dhcp::MemfileLeaseStatsQuery::getNextRow
virtual bool getNextRow(LeaseStatsRow &row)
Fetches the next row in the result set.
Definition: memfile_lease_mgr.cc:298
isc::dhcp::MemfileLeaseStatsQuery6::~MemfileLeaseStatsQuery6
virtual ~MemfileLeaseStatsQuery6()
Destructor.
Definition: memfile_lease_mgr.cc:500
isc::dhcp::Lease4
Structure that holds a lease for IPv4 address.
Definition: lease.h:256
isc::dhcp::Lease4StorageHWAddressSubnetIdIndex
Lease4Storage::index< HWAddressSubnetIdIndexTag >::type Lease4StorageHWAddressSubnetIdIndex
DHCPv4 lease storage index by HW address and subnet identifier.
Definition: memfile_lease_storage.h:276