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>
14
15#include <boost/shared_ptr.hpp>
16
17namespace isc {
18namespace dhcp {
19
40public:
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
This is a base class for exceptions thrown from the DNS library module.
Utility class to manage bulk of leases in the lease files.
static void write(LeaseFileType &lease_file, const StorageType &storage)
Write leases from the storage into a lease file.
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.
Code used to conduct various sanity checks.
void checkLease(Lease4Ptr &lease, bool current=true)
Sanity checks and possibly corrects an IPv4 lease.
Exception thrown when an error occurs during CSV file processing.
Definition: csv_file.h:22
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
const int DHCPSRV_DBG_TRACE_DETAIL_DATA
Additional information.
Definition: dhcpsrv_log.h:43
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
Defines the logger used by the top-level component of kea-dhcp-ddns.