Kea  1.5.0
lease_file_loader.h
Go to the documentation of this file.
1 // Copyright (C) 2015-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 #ifndef LEASE_FILE_LOADER_H
8 #define LEASE_FILE_LOADER_H
9 
10 #include <dhcpsrv/dhcpsrv_log.h>
13 #include <dhcpsrv/sanity_checker.h>
14 
15 #include <boost/shared_ptr.hpp>
16 
17 namespace isc {
18 namespace dhcp {
19 
40 public:
41 
75  template<typename LeaseObjectType, typename LeaseFileType,
76  typename StorageType>
77  static void load(LeaseFileType& lease_file, StorageType& storage,
78  const uint32_t max_errors = 0xFFFFFFFF,
79  const bool close_file_on_exit = true) {
80 
81  LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LEASE_FILE_LOAD)
82  .arg(lease_file.getFilename());
83 
84  // Reopen the file, as we don't know whether the file is open
85  // and we also don't know its current state.
86  lease_file.close();
87  lease_file.open();
88 
89  SanityChecker lease_checker;
90 
91  boost::shared_ptr<LeaseObjectType> lease;
92  // Track the number of corrupted leases.
93  uint32_t errcnt = 0;
94  while (true) {
95  // Unable to parse the lease.
96  if (!lease_file.next(lease)) {
97  LOG_ERROR(dhcpsrv_logger, DHCPSRV_MEMFILE_LEASE_LOAD_ROW_ERROR)
98  .arg(lease_file.getReads())
99  .arg(lease_file.getReadMsg());
100 
101  // A value of 0xFFFFFFFF indicates that we don't return
102  // until the whole file is parsed, even if errors occur.
103  // Otherwise, check if we have exceeded the maximum number
104  // of errors and throw an exception if we have.
105  if (++errcnt > max_errors) {
106  // If we break parsing the CSV file because of too many
107  // errors, it doesn't make sense to keep the file open.
108  // This is because the caller wouldn't know where we
109  // stopped parsing and where the internal file pointer
110  // is. So, there are probably no cases when the caller
111  // would continue to use the open file.
112  lease_file.close();
113  isc_throw(util::CSVFileError, "exceeded maximum number of"
114  " failures " << max_errors << " to read a lease"
115  " from the lease file "
116  << lease_file.getFilename());
117  }
118  // Skip the corrupted lease.
119  continue;
120  }
121 
122  // Lease was found and we successfully parsed it.
123  if (lease) {
125  DHCPSRV_MEMFILE_LEASE_LOAD)
126  .arg(lease->toText());
127 
128  // Now see if we need to sanitize this lease. As lease file is
129  // loaded during the configuration, we have to use staging config,
130  // rather than current config for this (false = staging).
131  lease_checker.checkLease(lease, false);
132  if (!lease) {
133  continue;
134  }
135 
136  // Check if this lease exists.
137  typename StorageType::iterator lease_it =
138  storage.find(lease->addr_);
139  // The lease doesn't exist yet. Insert the lease if
140  // it has a positive valid lifetime.
141  if (lease_it == storage.end()) {
142  if (lease->valid_lft_ > 0) {
143  storage.insert(lease);
144  }
145  } else {
146  // The lease exists. If the new entry has a valid
147  // lifetime of 0 it is an indication to remove the
148  // existing entry. Otherwise, we update the lease.
149  if (lease->valid_lft_ == 0) {
150  storage.erase(lease_it);
151 
152  } else {
153  // Use replace to re-index leases on update.
154  storage.replace(lease_it, lease);
155  }
156  }
157 
158  } else {
159  // Being here means that we hit the end of file.
160  break;
161 
162  }
163  }
164 
165  if (lease_file.needsConversion()) {
167  (lease_file.getInputSchemaState()
169  ? DHCPSRV_MEMFILE_NEEDS_UPGRADING
170  : DHCPSRV_MEMFILE_NEEDS_DOWNGRADING))
171  .arg(lease_file.getFilename())
172  .arg(lease_file.getSchemaVersion());
173  }
174 
175  if (close_file_on_exit) {
176  lease_file.close();
177  }
178  }
179 
206  template<typename LeaseObjectType, typename LeaseFileType,
207  typename StorageType>
208  static void write(LeaseFileType& lease_file, const StorageType& storage) {
209  // Reopen the file, as we don't know whether the file is open
210  // and we also don't know its current state.
211  lease_file.close();
212  lease_file.open();
213 
214  // Iterate over the storage area writing out the leases
215  for (typename StorageType::const_iterator lease = storage.begin();
216  lease != storage.end();
217  ++lease) {
218  try {
219  lease_file.append(**lease);
220  } catch (const isc::Exception&) {
221  // Close the file
222  lease_file.close();
223  throw;
224  }
225  }
226 
227  // Close the file
228  lease_file.close();
229  }
230 };
231 
232 } // namespace dhcp
233 } // namespace isc
234 
235 #endif // LEASE_FILE_LOADER_H
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
isc::dhcp::LeaseFileLoader::load
static void load(LeaseFileType &lease_file, StorageType &storage, const uint32_t max_errors=0xFFFFFFFF, const bool close_file_on_exit=true)
Load leases from the lease file into the specified storage.
Definition: lease_file_loader.h:77
sanity_checker.h
memfile_lease_storage.h
isc::dhcp::LeaseFileLoader
Utility class to manage bulk of leases in the lease files.
Definition: lease_file_loader.h:39
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition: exceptions/exceptions.h:23
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
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
dhcpsrv_log.h
isc::dhcp::LeaseFileLoader::write
static void write(LeaseFileType &lease_file, const StorageType &storage)
Write leases from the storage into a lease file.
Definition: lease_file_loader.h:208
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
versioned_csv_file.h
isc::util::CSVFileError
Exception thrown when an error occurs during CSV file processing.
Definition: csv_file.h:22
isc::dhcp::SanityChecker
Code used to conduct various sanity checks.
Definition: sanity_checker.h:21
isc::util::VersionedCSVFile::NEEDS_UPGRADE
@ NEEDS_UPGRADE
Definition: versioned_csv_file.h:128
isc::dhcp::SanityChecker::checkLease
void checkLease(Lease4Ptr &lease, bool current=true)
Sanity checks and possibly corrects an IPv4 lease.
Definition: sanity_checker.cc:16
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL_DATA
const int DHCPSRV_DBG_TRACE_DETAIL_DATA
Additional information.
Definition: dhcpsrv_log.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