| Kea 3.0.2-git

lease_file_loader.h
Go to the documentation of this file.
1// Copyright (C) 2015-2024 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>
11#include <dhcpsrv/memfile_lease_storage.h>
12#include <util/versioned_csv_file.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
40 class LeaseFileLoader {
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
82 LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_LEASE_FILE_LOAD)
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;
92 if (SanityChecker::leaseCheckingEnabled(false)) {
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)) {
105 LOG_ERROR(dhcpsrv_logger, DHCPSRV_MEMFILE_LEASE_LOAD_ROW_ERROR)
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) {
132 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA,
133 DHCPSRV_MEMFILE_LEASE_LOAD)
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()) {
177 LOG_WARN(dhcpsrv_logger,
178 (lease_file.getInputSchemaState()
179 == util::VersionedCSVFile::NEEDS_UPGRADE
180 ? DHCPSRV_MEMFILE_NEEDS_UPGRADING
181 : DHCPSRV_MEMFILE_NEEDS_DOWNGRADING))
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 (auto const& lease : storage) {
227 try {
228 lease_file.append(*lease);
229 } catch (const isc::Exception&) {
230 // Close the file
231 lease_file.close();
232 throw;
233 }
234 }
235
236 // Close the file
237 lease_file.close();
238 }
239};
240
241} // namespace dhcp
242} // namespace isc
243
244#endif // LEASE_FILE_LOADER_H
isc::Exception
This is a base class for exceptions thrown from the DNS library module.
Definition exceptions/exceptions.h:23
isc::dhcp::LeaseFileLoader
Utility class to manage bulk of leases in the lease files.
Definition lease_file_loader.h:40
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:219
isc::dhcp::LeaseFileLoader::load
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.
Definition lease_file_loader.h:78
isc::dhcp::SanityChecker
Code used to conduct various sanity checks.
Definition sanity_checker.h:23
isc::dhcp::SanityChecker::leaseCheckingEnabled
static bool leaseCheckingEnabled(bool current=true)
Indicates the specified configuration enables lease sanity checking.
Definition sanity_checker.cc:18
isc::util::CSVFileError
Exception thrown when an error occurs during CSV file processing.
Definition csv_file.h:22
isc::util::VersionedCSVFile::NEEDS_UPGRADE
@ NEEDS_UPGRADE
Definition versioned_csv_file.h:128
dhcpsrv_log.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
memfile_lease_storage.h
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::DHCPSRV_DBG_TRACE_DETAIL_DATA
const int DHCPSRV_DBG_TRACE_DETAIL_DATA
Additional information.
Definition dhcpsrv_log.h:43
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
isc::dhcp::DHCPSRV_MEMFILE_LEASE_LOAD
const isc::log::MessageID DHCPSRV_MEMFILE_LEASE_LOAD
Definition dhcpsrv_messages.h:130
isc::dhcp::DHCPSRV_MEMFILE_LEASE_FILE_LOAD
const isc::log::MessageID DHCPSRV_MEMFILE_LEASE_FILE_LOAD
Definition dhcpsrv_messages.h:129
isc::dhcp::DHCPSRV_MEMFILE_NEEDS_DOWNGRADING
const isc::log::MessageID DHCPSRV_MEMFILE_NEEDS_DOWNGRADING
Definition dhcpsrv_messages.h:139
isc::dhcp::DHCPSRV_MEMFILE_LEASE_LOAD_ROW_ERROR
const isc::log::MessageID DHCPSRV_MEMFILE_LEASE_LOAD_ROW_ERROR
Definition dhcpsrv_messages.h:131
isc::dhcp::DHCPSRV_MEMFILE_NEEDS_UPGRADING
const isc::log::MessageID DHCPSRV_MEMFILE_NEEDS_UPGRADING
Definition dhcpsrv_messages.h:140
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
sanity_checker.h
versioned_csv_file.h