Kea 2.0.2
csv_lease_file6.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2020 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>
10#include <ctime>
11
12using namespace isc::asiolink;
13using namespace isc::data;
14using namespace isc::util;
15
16namespace isc {
17namespace dhcp {
18
19CSVLeaseFile6::CSVLeaseFile6(const std::string& filename)
20 : VersionedCSVFile(filename) {
21 initColumns();
22}
23
24void
25CSVLeaseFile6::open(const bool seek_to_end) {
26 // Call the base class to open the file
27 VersionedCSVFile::open(seek_to_end);
28
29 // and clear any statistics we may have
31}
32
33void
35 // Bump the number of write attempts
36 ++writes_;
37
38 if (((!(lease.duid_)) || (*(lease.duid_) == DUID::EMPTY())) &&
39 (lease.state_ != Lease::STATE_DECLINED)) {
41 isc_throw(BadValue, "Lease6: " << lease.addr_.toText() << ", state: "
42 << Lease::basicStatesToText(lease.state_) << ", has no DUID");
43 }
44
46 row.writeAt(getColumnIndex("address"), lease.addr_.toText());
47 row.writeAt(getColumnIndex("duid"), lease.duid_->toText());
48 row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
49 row.writeAt(getColumnIndex("expire"), static_cast<uint64_t>(lease.cltt_) + lease.valid_lft_);
50 row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
51 row.writeAt(getColumnIndex("pref_lifetime"), lease.preferred_lft_);
52 row.writeAt(getColumnIndex("lease_type"), lease.type_);
53 row.writeAt(getColumnIndex("iaid"), lease.iaid_);
54 row.writeAt(getColumnIndex("prefix_len"),
55 static_cast<int>(lease.prefixlen_));
56 row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
57 row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
58 row.writeAtEscaped(getColumnIndex("hostname"), lease.hostname_);
59 if (lease.hwaddr_) {
60 // We may not have hardware information
61 row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
62 }
63 row.writeAt(getColumnIndex("state"), lease.state_);
64 // User context is optional.
65 if (lease.getContext()) {
66 row.writeAtEscaped(getColumnIndex("user_context"), lease.getContext()->str());
67 }
68 try {
69 VersionedCSVFile::append(row);
70 } catch (const std::exception&) {
71 // Catch any errors so we can bump the error counter than rethrow it
73 throw;
74 }
75
76 // Bump the number of leases written
78}
79
80bool
82 // Bump the number of read attempts
83 ++reads_;
84
85 // Read the CSV row and try to create a lease from the values read.
86 // This may easily result in exception. We don't want this function
87 // to throw exceptions, so we catch them all and rather return the
88 // false value.
89 try {
90 // Get the row of CSV values.
91 CSVRow row;
92 VersionedCSVFile::next(row);
93 // The empty row signals EOF.
94 if (row == CSVFile::EMPTY_ROW()) {
95 lease.reset();
96 return (true);
97 }
98
99 lease.reset(new Lease6(readType(row), readAddress(row), readDUID(row),
100 readIAID(row), readPreferred(row),
101 readValid(row),
102 readSubnetID(row),
103 readHWAddr(row),
104 readPrefixLen(row)));
105 lease->cltt_ = readCltt(row);
106 lease->fqdn_fwd_ = readFqdnFwd(row);
107 lease->fqdn_rev_ = readFqdnRev(row);
108 lease->hostname_ = readHostname(row);
109 lease->state_ = readState(row);
110 if ((*lease->duid_ == DUID::EMPTY())
111 && lease->state_ != Lease::STATE_DECLINED) {
112 isc_throw(isc::BadValue, "The Empty DUID is"
113 "only valid for declined leases");
114 }
115 ConstElementPtr ctx = readContext(row);
116 if (ctx) {
117 lease->setContext(ctx);
118 }
119 } catch (const std::exception& ex) {
120 // bump the read error count
121 ++read_errs_;
122
123 // The lease might have been created, so let's set it back to NULL to
124 // signal that lease hasn't been parsed.
125 lease.reset();
126 setReadMsg(ex.what());
127 return (false);
128 }
129
130 // bump the number of leases read
131 ++read_leases_;
132
133 return (true);
134}
135
136void
137CSVLeaseFile6::initColumns() {
138 addColumn("address", "1.0");
139 addColumn("duid", "1.0");
140 addColumn("valid_lifetime", "1.0");
141 addColumn("expire", "1.0");
142 addColumn("subnet_id", "1.0");
143 addColumn("pref_lifetime", "1.0");
144 addColumn("lease_type", "1.0");
145 addColumn("iaid", "1.0");
146 addColumn("prefix_len", "1.0");
147 addColumn("fqdn_fwd", "1.0");
148 addColumn("fqdn_rev", "1.0");
149 addColumn("hostname", "1.0");
150 addColumn("hwaddr", "2.0");
151 addColumn("state", "3.0", "0");
152 addColumn("user_context", "3.1");
153 // Any file with less than hostname is invalid
154 setMinimumValidColumns("hostname");
155}
156
158CSVLeaseFile6::readType(const CSVRow& row) {
159 return (static_cast<Lease::Type>
160 (row.readAndConvertAt<int>(getColumnIndex("lease_type"))));
161}
162
164CSVLeaseFile6::readAddress(const CSVRow& row) {
165 IOAddress address(row.readAt(getColumnIndex("address")));
166 return (address);
167}
168
170CSVLeaseFile6::readDUID(const util::CSVRow& row) {
171 DuidPtr duid(new DUID(DUID::fromText(row.readAt(getColumnIndex("duid")))));
172 return (duid);
173}
174
175uint32_t
176CSVLeaseFile6::readIAID(const CSVRow& row) {
177 uint32_t iaid = row.readAndConvertAt<uint32_t>(getColumnIndex("iaid"));
178 return (iaid);
179}
180
181uint32_t
182CSVLeaseFile6::readPreferred(const CSVRow& row) {
183 uint32_t pref =
184 row.readAndConvertAt<uint32_t>(getColumnIndex("pref_lifetime"));
185 return (pref);
186}
187
188uint32_t
189CSVLeaseFile6::readValid(const CSVRow& row) {
190 uint32_t valid =
191 row.readAndConvertAt<uint32_t>(getColumnIndex("valid_lifetime"));
192 return (valid);
193}
194
195uint32_t
196CSVLeaseFile6::readCltt(const CSVRow& row) {
197 time_t cltt =
198 static_cast<time_t>(row.readAndConvertAt<uint64_t>(getColumnIndex("expire"))
199 - readValid(row));
200 return (cltt);
201}
202
204CSVLeaseFile6::readSubnetID(const CSVRow& row) {
205 SubnetID subnet_id =
206 row.readAndConvertAt<SubnetID>(getColumnIndex("subnet_id"));
207 return (subnet_id);
208}
209
210uint8_t
211CSVLeaseFile6::readPrefixLen(const CSVRow& row) {
212 int prefixlen = row.readAndConvertAt<int>(getColumnIndex("prefix_len"));
213 return (static_cast<uint8_t>(prefixlen));
214}
215
216bool
217CSVLeaseFile6::readFqdnFwd(const CSVRow& row) {
218 bool fqdn_fwd = row.readAndConvertAt<bool>(getColumnIndex("fqdn_fwd"));
219 return (fqdn_fwd);
220}
221
222bool
223CSVLeaseFile6::readFqdnRev(const CSVRow& row) {
224 bool fqdn_rev = row.readAndConvertAt<bool>(getColumnIndex("fqdn_rev"));
225 return (fqdn_rev);
226}
227
228std::string
229CSVLeaseFile6::readHostname(const CSVRow& row) {
230 std::string hostname = row.readAtEscaped(getColumnIndex("hostname"));
231 return (hostname);
232}
233
235CSVLeaseFile6::readHWAddr(const CSVRow& row) {
236
237 try {
238 const HWAddr& hwaddr = HWAddr::fromText(row.readAt(getColumnIndex("hwaddr")));
239 if (hwaddr.hwaddr_.empty()) {
240 return (HWAddrPtr());
241 }
242
245
246 // Let's return a pointer to new freshly created copy.
247 return (HWAddrPtr(new HWAddr(hwaddr)));
248
249 } catch (const std::exception& ex) {
250 // That's worse. There was something in the file, but its conversion
251 // to HWAddr failed. Let's log it on warning and carry on.
253 .arg(ex.what());
254
255 return (HWAddrPtr());
256 }
257}
258
259uint32_t
260CSVLeaseFile6::readState(const util::CSVRow& row) {
261 uint32_t state = row.readAndConvertAt<uint32_t>(getColumnIndex("state"));
262 return (state);
263}
264
266CSVLeaseFile6::readContext(const util::CSVRow& row) {
267 std::string user_context = row.readAtEscaped(getColumnIndex("user_context"));
268 if (user_context.empty()) {
269 return (ConstElementPtr());
270 }
271 ConstElementPtr ctx = Element::fromJSON(user_context);
272 if (!ctx || (ctx->getType() != Element::map)) {
273 isc_throw(isc::BadValue, "user context '" << user_context
274 << "' is not a JSON map");
275 }
276 return (ctx);
277}
278
279} // end of namespace isc::dhcp
280} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
bool next(Lease6Ptr &lease)
Reads next lease from the CSV file.
void append(const Lease6 &lease)
Appends the lease record to the CSV file.
virtual void open(const bool seek_to_end=false)
Opens a lease file.
CSVLeaseFile6(const std::string &filename)
Constructor.
static DUID fromText(const std::string &text)
Create DUID from the textual format.
Definition: duid.cc:62
static const DUID & EMPTY()
Defines the constant "empty" DUID.
Definition: duid.cc:69
uint32_t write_leases_
Number of lease written.
uint32_t read_leases_
Number of leases read.
uint32_t reads_
Number of attempts to read a lease.
void clearStatistics()
Clears the statistics.
uint32_t writes_
Number of attempts to write a lease.
uint32_t write_errs_
Number of errors when writing.
uint32_t read_errs_
Number of errors when reading.
size_t getColumnCount() const
Returns the number of columns in the file.
Definition: csv_file.h:403
void setReadMsg(const std::string &read_msg)
Sets error message after row validation.
Definition: csv_file.h:486
size_t getColumnIndex(const std::string &col_name) const
Returns the index of the column having specified name.
Definition: csv_file.cc:237
Represents a single row of the CSV file.
Definition: csv_file.h:51
T readAndConvertAt(const size_t at) const
Retrieves a value from the internal container.
Definition: csv_file.h:156
std::string readAtEscaped(const size_t at) const
Retrieves a value from the internal container, free of escaped characters.
Definition: csv_file.cc:66
void writeAt(const size_t at, const char *value)
Replaces the value at specified index.
Definition: csv_file.cc:84
std::string readAt(const size_t at) const
Retrieves a value from the internal container.
Definition: csv_file.cc:60
void writeAtEscaped(const size_t at, const std::string &value)
Replaces the value at the specified index with a value that has had special characters escaped.
Definition: csv_file.cc:90
Implements a CSV file that supports multiple versions of the file's "schema".
void setMinimumValidColumns(const std::string &column_name)
Sets the minimum number of valid columns based on a given column.
void addColumn(const std::string &col_name, const std::string &version, const std::string &default_value="")
Adds metadata for a single column to the schema.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
const isc::log::MessageID DHCPSRV_MEMFILE_READ_HWADDR_FAIL
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:20
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:492
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.
data::ConstElementPtr getContext() const
Returns const pointer to the user context.
Definition: user_context.h:24
static HWAddr fromText(const std::string &text, const uint16_t htype=HTYPE_ETHER)
Creates instance of the hardware address from textual format.
Definition: hwaddr.cc:70
Structure that holds a lease for IPv6 address and/or prefix.
Definition: lease.h:503
Lease::Type type_
Lease type.
Definition: lease.h:508
uint32_t iaid_
Identity Association Identifier (IAID)
Definition: lease.h:520
uint32_t preferred_lft_
Preferred lifetime.
Definition: lease.h:529
DuidPtr duid_
Client identifier.
Definition: lease.h:523
uint8_t prefixlen_
IPv6 prefix length.
Definition: lease.h:513
SubnetID subnet_id_
Subnet identifier.
Definition: lease.h:153
uint32_t valid_lft_
Valid lifetime.
Definition: lease.h:124
static std::string basicStatesToText(const uint32_t state)
Returns name(s) of the basic lease state(s).
Definition: lease.cc:90
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:76
Type
Type of lease or pool.
Definition: lease.h:50
std::string hostname_
Client hostname.
Definition: lease.h:158
uint32_t state_
Holds the lease state(s).
Definition: lease.h:184
bool fqdn_fwd_
Forward zone updated?
Definition: lease.h:163
time_t cltt_
Client last transmission time.
Definition: lease.h:142
HWAddrPtr hwaddr_
Client's MAC/hardware address.
Definition: lease.h:173
bool fqdn_rev_
Reverse zone updated?
Definition: lease.h:168
isc::asiolink::IOAddress addr_
IPv4 ot IPv6 address.
Definition: lease.h:119