Kea 1.5.0
csv_lease_file6.cc
Go to the documentation of this file.
1// Copyright (C) 2014-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#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
39 row.writeAt(getColumnIndex("address"), lease.addr_.toText());
40 row.writeAt(getColumnIndex("duid"), lease.duid_->toText());
41 row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
42 row.writeAt(getColumnIndex("expire"), static_cast<uint64_t>(lease.cltt_ + lease.valid_lft_));
43 row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
44 row.writeAt(getColumnIndex("pref_lifetime"), lease.preferred_lft_);
45 row.writeAt(getColumnIndex("lease_type"), lease.type_);
46 row.writeAt(getColumnIndex("iaid"), lease.iaid_);
47 row.writeAt(getColumnIndex("prefix_len"),
48 static_cast<int>(lease.prefixlen_));
49 row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
50 row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
51 row.writeAt(getColumnIndex("hostname"), lease.hostname_);
52 if (lease.hwaddr_) {
53 // We may not have hardware information
54 row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
55 }
56 row.writeAt(getColumnIndex("state"), lease.state_);
57 // User context is optional.
58 if (lease.getContext()) {
59 row.writeAt(getColumnIndex("user_context"), lease.getContext()->str());
60 }
61 try {
62 VersionedCSVFile::append(row);
63 } catch (const std::exception&) {
64 // Catch any errors so we can bump the error counter than rethrow it
66 throw;
67 }
68
69 // Bump the number of leases written
71}
72
73bool
75 // Bump the number of read attempts
76 ++reads_;
77
78 // Read the CSV row and try to create a lease from the values read.
79 // This may easily result in exception. We don't want this function
80 // to throw exceptions, so we catch them all and rather return the
81 // false value.
82 try {
83 // Get the row of CSV values.
84 CSVRow row;
86 // The empty row signals EOF.
87 if (row == CSVFile::EMPTY_ROW()) {
88 lease.reset();
89 return (true);
90 }
91
92 lease.reset(new Lease6(readType(row), readAddress(row), readDUID(row),
93 readIAID(row), readPreferred(row),
94 readValid(row), 0, 0, // t1, t2 = 0
95 readSubnetID(row),
96 readHWAddr(row),
97 readPrefixLen(row)));
98 lease->cltt_ = readCltt(row);
99 lease->fqdn_fwd_ = readFqdnFwd(row);
100 lease->fqdn_rev_ = readFqdnRev(row);
101 lease->hostname_ = readHostname(row);
102 lease->state_ = readState(row);
103 if ((*lease->duid_ == DUID::EMPTY())
104 && lease->state_ != Lease::STATE_DECLINED) {
105 isc_throw(isc::BadValue, "The Empty DUID is"
106 "only valid for declined leases");
107 }
108 ConstElementPtr ctx = readContext(row);
109 if (ctx) {
110 lease->setContext(ctx);
111 }
112 } catch (std::exception& ex) {
113 // bump the read error count
114 ++read_errs_;
115
116 // The lease might have been created, so let's set it back to NULL to
117 // signal that lease hasn't been parsed.
118 lease.reset();
119 setReadMsg(ex.what());
120 return (false);
121 }
122
123 // bump the number of leases read
124 ++read_leases_;
125
126 return (true);
127}
128
129void
130CSVLeaseFile6::initColumns() {
131 addColumn("address", "1.0");
132 addColumn("duid", "1.0");
133 addColumn("valid_lifetime", "1.0");
134 addColumn("expire", "1.0");
135 addColumn("subnet_id", "1.0");
136 addColumn("pref_lifetime", "1.0");
137 addColumn("lease_type", "1.0");
138 addColumn("iaid", "1.0");
139 addColumn("prefix_len", "1.0");
140 addColumn("fqdn_fwd", "1.0");
141 addColumn("fqdn_rev", "1.0");
142 addColumn("hostname", "1.0");
143 addColumn("hwaddr", "2.0");
144 addColumn("state", "3.0", "0");
145 addColumn("user_context", "3.1");
146 // Any file with less than hostname is invalid
147 setMinimumValidColumns("hostname");
148}
149
151CSVLeaseFile6::readType(const CSVRow& row) {
152 return (static_cast<Lease::Type>
153 (row.readAndConvertAt<int>(getColumnIndex("lease_type"))));
154}
155
157CSVLeaseFile6::readAddress(const CSVRow& row) {
158 IOAddress address(row.readAt(getColumnIndex("address")));
159 return (address);
160}
161
163CSVLeaseFile6::readDUID(const util::CSVRow& row) {
164 DuidPtr duid(new DUID(DUID::fromText(row.readAt(getColumnIndex("duid")))));
165 return (duid);
166}
167
168uint32_t
169CSVLeaseFile6::readIAID(const CSVRow& row) {
170 uint32_t iaid = row.readAndConvertAt<uint32_t>(getColumnIndex("iaid"));
171 return (iaid);
172}
173
174uint32_t
175CSVLeaseFile6::readPreferred(const CSVRow& row) {
176 uint32_t pref =
177 row.readAndConvertAt<uint32_t>(getColumnIndex("pref_lifetime"));
178 return (pref);
179}
180
181uint32_t
182CSVLeaseFile6::readValid(const CSVRow& row) {
183 uint32_t valid =
184 row.readAndConvertAt<uint32_t>(getColumnIndex("valid_lifetime"));
185 return (valid);
186}
187
188uint32_t
189CSVLeaseFile6::readCltt(const CSVRow& row) {
190 time_t cltt =
191 static_cast<time_t>(row.readAndConvertAt<uint64_t>(getColumnIndex("expire"))
192 - readValid(row));
193 return (cltt);
194}
195
197CSVLeaseFile6::readSubnetID(const CSVRow& row) {
198 SubnetID subnet_id =
199 row.readAndConvertAt<SubnetID>(getColumnIndex("subnet_id"));
200 return (subnet_id);
201}
202
203uint8_t
204CSVLeaseFile6::readPrefixLen(const CSVRow& row) {
205 int prefixlen = row.readAndConvertAt<int>(getColumnIndex("prefix_len"));
206 return (static_cast<uint8_t>(prefixlen));
207}
208
209bool
210CSVLeaseFile6::readFqdnFwd(const CSVRow& row) {
211 bool fqdn_fwd = row.readAndConvertAt<bool>(getColumnIndex("fqdn_fwd"));
212 return (fqdn_fwd);
213}
214
215bool
216CSVLeaseFile6::readFqdnRev(const CSVRow& row) {
217 bool fqdn_rev = row.readAndConvertAt<bool>(getColumnIndex("fqdn_rev"));
218 return (fqdn_rev);
219}
220
221std::string
222CSVLeaseFile6::readHostname(const CSVRow& row) {
223 std::string hostname = row.readAt(getColumnIndex("hostname"));
224 return (hostname);
225}
226
228CSVLeaseFile6::readHWAddr(const CSVRow& row) {
229
230 try {
231 const HWAddr& hwaddr = HWAddr::fromText(row.readAt(getColumnIndex("hwaddr")));
232 if (hwaddr.hwaddr_.empty()) {
233 return (HWAddrPtr());
234 }
235
238
239 // Let's return a pointer to new freshly created copy.
240 return (HWAddrPtr(new HWAddr(hwaddr)));
241
242 } catch (const std::exception& ex) {
243 // That's worse. There was something in the file, but its conversion
244 // to HWAddr failed. Let's log it on warning and carry on.
245 LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_READ_HWADDR_FAIL)
246 .arg(ex.what());
247
248 return (HWAddrPtr());
249 }
250}
251
252uint32_t
253CSVLeaseFile6::readState(const util::CSVRow& row) {
254 uint32_t state = row.readAndConvertAt<uint32_t>(getColumnIndex("state"));
255 return (state);
256}
257
259CSVLeaseFile6::readContext(const util::CSVRow& row) {
260 std::string user_context = row.readAt(getColumnIndex("user_context"));
261 if (user_context.empty()) {
262 return (ConstElementPtr());
263 }
264 ConstElementPtr ctx = Element::fromJSON(user_context);
265 if (!ctx || (ctx->getType() != Element::map)) {
266 isc_throw(isc::BadValue, "user context '" << user_context
267 << "' is not a JSON map");
268 }
269 return (ctx);
270}
271
272} // end of namespace isc::dhcp
273} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
Definition: data.cc:750
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:61
static const DUID & EMPTY()
Defines the constant "empty" DUID.
Definition: duid.cc:68
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:335
static CSVRow EMPTY_ROW()
Represents empty row.
Definition: csv_file.h:423
void setReadMsg(const std::string &read_msg)
Sets error message after row validation.
Definition: csv_file.h:418
size_t getColumnIndex(const std::string &col_name) const
Returns the index of the column having specified name.
Definition: csv_file.cc:206
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:135
void writeAt(const size_t at, const char *value)
Replaces the value at specified index.
Definition: csv_file.cc:58
std::string readAt(const size_t at) const
Retrieves a value from the internal container.
Definition: csv_file.cc:39
Implements a CSV file that supports multiple versions of the file's "schema".
virtual void open(const bool seek_to_end=false)
Opens existing file or creates a new one.
void setMinimumValidColumns(const std::string &column_name)
Sets the minimum number of valid columns based on a given column.
bool next(CSVRow &row)
Reads next row from the file file.
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:23
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
boost::shared_ptr< DUID > DuidPtr
Definition: duid.h:21
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:463
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-dhcp-ddns.
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:471
Lease::Type type_
Lease type.
Definition: lease.h:476
uint32_t iaid_
Identity Association Identifier (IAID)
Definition: lease.h:488
uint32_t preferred_lft_
preferred lifetime
Definition: lease.h:497
DuidPtr duid_
Client identifier.
Definition: lease.h:491
uint8_t prefixlen_
IPv6 prefix length.
Definition: lease.h:481
SubnetID subnet_id_
Subnet identifier.
Definition: lease.h:136
uint32_t valid_lft_
Valid lifetime.
Definition: lease.h:125
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:64
Type
Type of lease or pool.
Definition: lease.h:38
std::string hostname_
Client hostname.
Definition: lease.h:141
uint32_t state_
Holds the lease state(s).
Definition: lease.h:167
bool fqdn_fwd_
Forward zone updated?
Definition: lease.h:146
time_t cltt_
Client last transmission time.
Definition: lease.h:131
HWAddrPtr hwaddr_
Client's MAC/hardware address.
Definition: lease.h:156
bool fqdn_rev_
Reverse zone updated?
Definition: lease.h:151
isc::asiolink::IOAddress addr_
IPv4 ot IPv6 address.
Definition: lease.h:102