123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- // Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #include <config.h>
- #include <dhcpsrv/dhcpsrv_log.h>
- #include <dhcpsrv/csv_lease_file6.h>
- using namespace isc::asiolink;
- using namespace isc::util;
- namespace isc {
- namespace dhcp {
- CSVLeaseFile6::CSVLeaseFile6(const std::string& filename)
- : VersionedCSVFile(filename) {
- initColumns();
- }
- void
- CSVLeaseFile6::open(const bool seek_to_end) {
- // Call the base class to open the file
- VersionedCSVFile::open(seek_to_end);
- // and clear any statistics we may have
- clearStatistics();
- }
- void
- CSVLeaseFile6::append(const Lease6& lease) {
- // Bump the number of write attempts
- ++writes_;
- CSVRow row(getColumnCount());
- row.writeAt(getColumnIndex("address"), lease.addr_.toText());
- row.writeAt(getColumnIndex("duid"), lease.duid_->toText());
- row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
- row.writeAt(getColumnIndex("expire"), lease.cltt_ + lease.valid_lft_);
- row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
- row.writeAt(getColumnIndex("pref_lifetime"), lease.preferred_lft_);
- row.writeAt(getColumnIndex("lease_type"), lease.type_);
- row.writeAt(getColumnIndex("iaid"), lease.iaid_);
- row.writeAt(getColumnIndex("prefix_len"),
- static_cast<int>(lease.prefixlen_));
- row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
- row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
- row.writeAt(getColumnIndex("hostname"), lease.hostname_);
- if (lease.hwaddr_) {
- // We may not have hardware information
- row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
- }
- row.writeAt(getColumnIndex("state"), lease.state_);
- try {
- VersionedCSVFile::append(row);
- } catch (const std::exception&) {
- // Catch any errors so we can bump the error counter than rethrow it
- ++write_errs_;
- throw;
- }
- // Bump the number of leases written
- ++write_leases_;
- }
- bool
- CSVLeaseFile6::next(Lease6Ptr& lease) {
- // Bump the number of read attempts
- ++reads_;
- // Read the CSV row and try to create a lease from the values read.
- // This may easily result in exception. We don't want this function
- // to throw exceptions, so we catch them all and rather return the
- // false value.
- try {
- // Get the row of CSV values.
- CSVRow row;
- VersionedCSVFile::next(row);
- // The empty row signals EOF.
- if (row == CSVFile::EMPTY_ROW()) {
- lease.reset();
- return (true);
- }
- lease.reset(new Lease6(readType(row), readAddress(row), readDUID(row),
- readIAID(row), readPreferred(row),
- readValid(row), 0, 0, // t1, t2 = 0
- readSubnetID(row),
- readHWAddr(row),
- readPrefixLen(row)));
- lease->cltt_ = readCltt(row);
- lease->fqdn_fwd_ = readFqdnFwd(row);
- lease->fqdn_rev_ = readFqdnRev(row);
- lease->hostname_ = readHostname(row);
- lease->state_ = readState(row);
- if ((*lease->duid_ == DUID::EMPTY())
- && lease->state_ != Lease::STATE_DECLINED) {
- isc_throw(isc::BadValue, "The Empty DUID is"
- "only valid for declined leases");
- }
- } catch (std::exception& ex) {
- // bump the read error count
- ++read_errs_;
- // The lease might have been created, so let's set it back to NULL to
- // signal that lease hasn't been parsed.
- lease.reset();
- setReadMsg(ex.what());
- return (false);
- }
- // bump the number of leases read
- ++read_leases_;
- return (true);
- }
- void
- CSVLeaseFile6::initColumns() {
- addColumn("address", "1.0");
- addColumn("duid", "1.0");
- addColumn("valid_lifetime", "1.0");
- addColumn("expire", "1.0");
- addColumn("subnet_id", "1.0");
- addColumn("pref_lifetime", "1.0");
- addColumn("lease_type", "1.0");
- addColumn("iaid", "1.0");
- addColumn("prefix_len", "1.0");
- addColumn("fqdn_fwd", "1.0");
- addColumn("fqdn_rev", "1.0");
- addColumn("hostname", "1.0");
- addColumn("hwaddr", "2.0");
- addColumn("state", "3.0", "0");
- // Any file with less than hostname is invalid
- setMinimumValidColumns("hostname");
- }
- Lease::Type
- CSVLeaseFile6::readType(const CSVRow& row) {
- return (static_cast<Lease::Type>
- (row.readAndConvertAt<int>(getColumnIndex("lease_type"))));
- }
- IOAddress
- CSVLeaseFile6::readAddress(const CSVRow& row) {
- IOAddress address(row.readAt(getColumnIndex("address")));
- return (address);
- }
- DuidPtr
- CSVLeaseFile6::readDUID(const util::CSVRow& row) {
- DuidPtr duid(new DUID(DUID::fromText(row.readAt(getColumnIndex("duid")))));
- return (duid);
- }
- uint32_t
- CSVLeaseFile6::readIAID(const CSVRow& row) {
- uint32_t iaid = row.readAndConvertAt<uint32_t>(getColumnIndex("iaid"));
- return (iaid);
- }
- uint32_t
- CSVLeaseFile6::readPreferred(const CSVRow& row) {
- uint32_t pref =
- row.readAndConvertAt<uint32_t>(getColumnIndex("pref_lifetime"));
- return (pref);
- }
- uint32_t
- CSVLeaseFile6::readValid(const CSVRow& row) {
- uint32_t valid =
- row.readAndConvertAt<uint32_t>(getColumnIndex("valid_lifetime"));
- return (valid);
- }
- uint32_t
- CSVLeaseFile6::readCltt(const CSVRow& row) {
- uint32_t cltt = row.readAndConvertAt<uint32_t>(getColumnIndex("expire"))
- - readValid(row);
- return (cltt);
- }
- SubnetID
- CSVLeaseFile6::readSubnetID(const CSVRow& row) {
- SubnetID subnet_id =
- row.readAndConvertAt<SubnetID>(getColumnIndex("subnet_id"));
- return (subnet_id);
- }
- uint8_t
- CSVLeaseFile6::readPrefixLen(const CSVRow& row) {
- int prefixlen = row.readAndConvertAt<int>(getColumnIndex("prefix_len"));
- return (static_cast<uint8_t>(prefixlen));
- }
- bool
- CSVLeaseFile6::readFqdnFwd(const CSVRow& row) {
- bool fqdn_fwd = row.readAndConvertAt<bool>(getColumnIndex("fqdn_fwd"));
- return (fqdn_fwd);
- }
- bool
- CSVLeaseFile6::readFqdnRev(const CSVRow& row) {
- bool fqdn_rev = row.readAndConvertAt<bool>(getColumnIndex("fqdn_rev"));
- return (fqdn_rev);
- }
- std::string
- CSVLeaseFile6::readHostname(const CSVRow& row) {
- std::string hostname = row.readAt(getColumnIndex("hostname"));
- return (hostname);
- }
- HWAddrPtr
- CSVLeaseFile6::readHWAddr(const CSVRow& row) {
- try {
- const HWAddr& hwaddr = HWAddr::fromText(row.readAt(getColumnIndex("hwaddr")));
- if (hwaddr.hwaddr_.empty()) {
- return (HWAddrPtr());
- }
- /// @todo: HWAddr returns an object, not a pointer. Without HWAddr
- /// refactoring, at least one copy is unavoidable.
- // Let's return a pointer to new freshly created copy.
- return (HWAddrPtr(new HWAddr(hwaddr)));
- } catch (const std::exception& ex) {
- // That's worse. There was something in the file, but its conversion
- // to HWAddr failed. Let's log it on warning and carry on.
- LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_READ_HWADDR_FAIL)
- .arg(ex.what());
- return (HWAddrPtr());
- }
- }
- uint32_t
- CSVLeaseFile6::readState(const util::CSVRow& row) {
- uint32_t state = row.readAndConvertAt<uint32_t>(getColumnIndex("state"));
- return (state);
- }
- } // end of namespace isc::dhcp
- } // end of namespace isc
|