Kea  1.9.9-git
lease_file_loader.h
Go to the documentation of this file.
1 // Copyright (C) 2015-2019 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/scoped_ptr.hpp>
16 #include <boost/shared_ptr.hpp>
17 
18 namespace isc {
19 namespace dhcp {
20 
41 public:
42 
76  template<typename LeaseObjectType, typename LeaseFileType,
77  typename StorageType>
78  static void load(LeaseFileType& lease_file, StorageType& storage,
79  const uint32_t max_errors = 0,
80  const bool close_file_on_exit = true) {
81 
83  .arg(lease_file.getFilename());
84 
85  // Reopen the file, as we don't know whether the file is open
86  // and we also don't know its current state.
87  lease_file.close();
88  lease_file.open();
89 
90  // Create lease sanity checker if checking is enabled.
91  boost::scoped_ptr<SanityChecker> lease_checker;
93  // Since lease file is loaded during the configuration,
94  // we have to use staging config, rather than current
95  // config for this (false = staging).
96  lease_checker.reset(new SanityChecker());
97  }
98 
99  boost::shared_ptr<LeaseObjectType> lease;
100  // Track the number of corrupted leases.
101  uint32_t errcnt = 0;
102  while (true) {
103  // Unable to parse the lease.
104  if (!lease_file.next(lease)) {
106  .arg(lease_file.getReads())
107  .arg(lease_file.getReadMsg());
108 
109  // A value of 0 indicates that we don't return
110  // until the whole file is parsed, even if errors occur.
111  // Otherwise, check if we have exceeded the maximum number
112  // of errors and throw an exception if we have.
113  if (max_errors && (++errcnt > max_errors)) {
114  // If we break parsing the CSV file because of too many
115  // errors, it doesn't make sense to keep the file open.
116  // This is because the caller wouldn't know where we
117  // stopped parsing and where the internal file pointer
118  // is. So, there are probably no cases when the caller
119  // would continue to use the open file.
120  lease_file.close();
121  isc_throw(util::CSVFileError, "exceeded maximum number of"
122  " failures " << max_errors << " to read a lease"
123  " from the lease file "
124  << lease_file.getFilename());
125  }
126  // Skip the corrupted lease.
127  continue;
128  }
129 
130  // Lease was found and we successfully parsed it.
131  if (lease) {
134  .arg(lease->toText());
135 
136  if (lease_checker) {
137  // If the lease is insane the checker will reset the lease pointer.
138  // As lease file is loaded during the configuration, we have
139  // to use staging config, rather than current config for this
140  // (false = staging).
141  lease_checker->checkLease(lease, false);
142  if (!lease) {
143  continue;
144  }
145  }
146 
147  // Check if this lease exists.
148  typename StorageType::iterator lease_it =
149  storage.find(lease->addr_);
150  // The lease doesn't exist yet. Insert the lease if
151  // it has a positive valid lifetime.
152  if (lease_it == storage.end()) {
153  if (lease->valid_lft_ > 0) {
154  storage.insert(lease);
155  }
156  } else {
157  // The lease exists. If the new entry has a valid
158  // lifetime of 0 it is an indication to remove the
159  // existing entry. Otherwise, we update the lease.
160  if (lease->valid_lft_ == 0) {
161  storage.erase(lease_it);
162 
163  } else {
164  // Use replace to re-index leases on update.
165  storage.replace(lease_it, lease);
166  }
167  }
168 
169  } else {
170  // Being here means that we hit the end of file.
171  break;
172 
173  }
174  }
175 
176  if (lease_file.needsConversion()) {
178  (lease_file.getInputSchemaState()
182  .arg(lease_file.getFilename())
183  .arg(lease_file.getSchemaVersion());
184  }
185 
186  if (close_file_on_exit) {
187  lease_file.close();
188  }
189  }
190 
217  template<typename LeaseObjectType, typename LeaseFileType,
218  typename StorageType>
219  static void write(LeaseFileType& lease_file, const StorageType& storage) {
220  // Reopen the file, as we don't know whether the file is open
221  // and we also don't know its current state.
222  lease_file.close();
223  lease_file.open();
224 
225  // Iterate over the storage area writing out the leases
226  for (typename StorageType::const_iterator lease = storage.begin();
227  lease != storage.end();
228  ++lease) {
229  try {
230  lease_file.append(**lease);
231  } catch (const isc::Exception&) {
232  // Close the file
233  lease_file.close();
234  throw;
235  }
236  }
237 
238  // Close the file
239  lease_file.close();
240  }
241 };
242 
243 } // namespace dhcp
244 } // namespace isc
245 
246 #endif // LEASE_FILE_LOADER_H
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
const int DHCPSRV_DBG_TRACE_DETAIL_DATA
Additional information.
Definition: dhcpsrv_log.h:43
const isc::log::MessageID DHCPSRV_MEMFILE_LEASE_LOAD
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
static bool leaseCheckingEnabled(bool current=true)
Indicates the specified configuration enables lease sanity checking.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
Code used to conduct various sanity checks.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID DHCPSRV_MEMFILE_LEASE_FILE_LOAD
const isc::log::MessageID DHCPSRV_MEMFILE_NEEDS_UPGRADING
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
static void load(LeaseFileType &lease_file, StorageType &storage, const uint32_t max_errors=0, const bool close_file_on_exit=true)
Load leases from the lease file into the specified storage.
const isc::log::MessageID DHCPSRV_MEMFILE_NEEDS_DOWNGRADING
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
Utility class to manage bulk of leases in the lease files.
const isc::log::MessageID DHCPSRV_MEMFILE_LEASE_LOAD_ROW_ERROR
static void write(LeaseFileType &lease_file, const StorageType &storage)
Write leases from the storage into a lease file.
Exception thrown when an error occurs during CSV file processing.
Definition: csv_file.h:22