From f09a4f68f8397b150a94b6f9b78da60b117a8fe1 Mon Sep 17 00:00:00 2001 From: Marcin Siodelski Date: Tue, 27 Aug 2013 13:36:00 +0200 Subject: [PATCH] [3084] Use FQDN data from the lease database to create lease instance. --- src/lib/dhcpsrv/lease_mgr.cc | 25 +++++++- src/lib/dhcpsrv/lease_mgr.h | 55 ++++++++++++++-- src/lib/dhcpsrv/mysql_lease_mgr.cc | 16 ++++- src/lib/dhcpsrv/tests/lease_mgr_unittest.cc | 64 +++++++++++++++++-- .../dhcpsrv/tests/mysql_lease_mgr_unittest.cc | 50 ++++++++++++++- src/lib/dhcpsrv/tests/test_utils.cc | 6 ++ 6 files changed, 198 insertions(+), 18 deletions(-) diff --git a/src/lib/dhcpsrv/lease_mgr.cc b/src/lib/dhcpsrv/lease_mgr.cc index 2310dd4cd5..54e97b2af2 100644 --- a/src/lib/dhcpsrv/lease_mgr.cc +++ b/src/lib/dhcpsrv/lease_mgr.cc @@ -33,15 +33,34 @@ namespace isc { namespace dhcp { Lease::Lease(const isc::asiolink::IOAddress& addr, uint32_t t1, uint32_t t2, - uint32_t valid_lft, SubnetID subnet_id, time_t cltt) + uint32_t valid_lft, SubnetID subnet_id, time_t cltt, + const bool fqdn_fwd, const bool fqdn_rev, + const std::string& hostname) :addr_(addr), t1_(t1), t2_(t2), valid_lft_(valid_lft), cltt_(cltt), - subnet_id_(subnet_id), fixed_(false), fqdn_fwd_(false), fqdn_rev_(false) { + subnet_id_(subnet_id), fixed_(false), hostname_(hostname), + fqdn_fwd_(fqdn_fwd), fqdn_rev_(fqdn_rev) { } Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1, uint32_t t2, SubnetID subnet_id, uint8_t prefixlen) - : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/), + : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/, false, false, ""), + type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid), + preferred_lft_(preferred) { + if (!duid) { + isc_throw(InvalidOperation, "DUID must be specified for a lease"); + } + + cltt_ = time(NULL); +} + +Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, + DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid, + uint32_t t1, uint32_t t2, SubnetID subnet_id, + const bool fqdn_fwd, const bool fqdn_rev, + const std::string& hostname, uint8_t prefixlen) + : Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/, + fqdn_fwd, fqdn_rev, hostname), type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid), preferred_lft_(preferred) { if (!duid) { diff --git a/src/lib/dhcpsrv/lease_mgr.h b/src/lib/dhcpsrv/lease_mgr.h index 02e517e4ab..1afb6353bb 100644 --- a/src/lib/dhcpsrv/lease_mgr.h +++ b/src/lib/dhcpsrv/lease_mgr.h @@ -122,8 +122,13 @@ struct Lease { /// @param valid_lft Lifetime of the lease /// @param subnet_id Subnet identification /// @param cltt Client last transmission time + /// @param fqdn_fwd If true, forward DNS update is performed for a lease. + /// @param fqdn_rev If true, reverse DNS update is performed for a lease. + /// @param hostname FQDN of the client which gets the lease. Lease(const isc::asiolink::IOAddress& addr, uint32_t t1, uint32_t t2, - uint32_t valid_lft, SubnetID subnet_id, time_t cltt); + uint32_t valid_lft, SubnetID subnet_id, time_t cltt, + const bool fqdn_fwd, const bool fqdn_rev, + const std::string& hostname); /// @brief Destructor virtual ~Lease() {} @@ -243,10 +248,16 @@ struct Lease4 : public Lease { /// @param t2 rebinding time /// @param cltt Client last transmission time /// @param subnet_id Subnet identification + /// @param fqdn_fwd If true, forward DNS update is performed for a lease. + /// @param fqdn_rev If true, reverse DNS update is performed for a lease. + /// @param hostname FQDN of the client which gets the lease. Lease4(const isc::asiolink::IOAddress& addr, const uint8_t* hwaddr, size_t hwaddr_len, const uint8_t* clientid, size_t clientid_len, uint32_t valid_lft, - uint32_t t1, uint32_t t2, time_t cltt, uint32_t subnet_id) - : Lease(addr, t1, t2, valid_lft, subnet_id, cltt), + uint32_t t1, uint32_t t2, time_t cltt, uint32_t subnet_id, + const bool fqdn_fwd = false, const bool fqdn_rev = false, + const std::string& hostname = "") + : Lease(addr, t1, t2, valid_lft, subnet_id, cltt, fqdn_fwd, fqdn_rev, + hostname), ext_(0), hwaddr_(hwaddr, hwaddr + hwaddr_len) { if (clientid_len) { client_id_.reset(new ClientId(clientid, clientid_len)); @@ -256,7 +267,7 @@ struct Lease4 : public Lease { /// @brief Default constructor /// /// Initialize fields that don't have a default constructor. - Lease4() : Lease(0, 0, 0, 0, 0, 0) { + Lease4() : Lease(0, 0, 0, 0, 0, 0, false, false, "") { } /// @brief Compare two leases for equality @@ -331,14 +342,46 @@ struct Lease6 : public Lease { /// @todo: Add DHCPv6 failover related fields here /// @brief Constructor + /// @param type Lease type. + /// @param addr Assigned address. + /// @param duid A pointer to an object representing DUID. + /// @param iaid IAID. + /// @param preferred Preferred lifetime. + /// @param valid Valid lifetime. + /// @param t1 A value of the T1 timer. + /// @param t2 A value of the T2 timer. + /// @param subnet_id A Subnet identifier. + /// @param prefixlen An address prefix length. Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1, - uint32_t t2, SubnetID subnet_id, uint8_t prefixlen_ = 0); + uint32_t t2, SubnetID subnet_id, uint8_t prefixlen = 0); + + /// @brief Constructor, including FQDN data. + /// + /// @param type Lease type. + /// @param addr Assigned address. + /// @param duid A pointer to an object representing DUID. + /// @param iaid IAID. + /// @param preferred Preferred lifetime. + /// @param valid Valid lifetime. + /// @param t1 A value of the T1 timer. + /// @param t2 A value of the T2 timer. + /// @param subnet_id A Subnet identifier. + /// @param fqdn_fwd If true, forward DNS update is performed for a lease. + /// @param fqdn_rev If true, reverse DNS update is performed for a lease. + /// @param hostname FQDN of the client which gets the lease. + /// @param prefixlen An address prefix length. + Lease6(LeaseType type, const isc::asiolink::IOAddress& addr, DuidPtr duid, + uint32_t iaid, uint32_t preferred, uint32_t valid, uint32_t t1, + uint32_t t2, SubnetID subnet_id, const bool fqdn_fwd, + const bool fqdn_rev, const std::string& hostname, + uint8_t prefixlen = 0); /// @brief Constructor /// /// Initialize fields that don't have a default constructor. - Lease6() : Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, 0, 0), + Lease6() : Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, 0, 0, + false, false, ""), type_(LEASE_IA_NA) { } diff --git a/src/lib/dhcpsrv/mysql_lease_mgr.cc b/src/lib/dhcpsrv/mysql_lease_mgr.cc index 210c8f25f4..2a6ad9035d 100644 --- a/src/lib/dhcpsrv/mysql_lease_mgr.cc +++ b/src/lib/dhcpsrv/mysql_lease_mgr.cc @@ -565,10 +565,16 @@ public: client_id_length_ = 0; } + // Hostname is passed to Lease4 as a string object. We have to create + // it from the buffer holding hostname and the buffer length. + std::string hostname(hostname_buffer_, + hostname_buffer_ + hostname_length_); + // note that T1 and T2 are not stored return (Lease4Ptr(new Lease4(addr4_, hwaddr_buffer_, hwaddr_length_, client_id_buffer_, client_id_length_, - valid_lifetime_, 0, 0, cltt, subnet_id_))); + valid_lifetime_, 0, 0, cltt, subnet_id_, + fqdn_fwd_, fqdn_rev_, hostname))); } /// @brief Return columns in error @@ -980,11 +986,17 @@ public: // Set up DUID, DuidPtr duid_ptr(new DUID(duid_buffer_, duid_length_)); + // Hostname is passed to Lease6 as a string object, so we have to + // create it from the hostname buffer and length. + std::string hostname(hostname_buffer_, + hostname_buffer_ + hostname_length_); + // Create the lease and set the cltt (after converting from the // expire time retrieved from the database). Lease6Ptr result(new Lease6(type, addr, duid_ptr, iaid_, pref_lifetime_, valid_lifetime_, 0, 0, - subnet_id_, prefixlen_)); + subnet_id_, fqdn_fwd_, fqdn_rev_, + hostname, prefixlen_)); time_t cltt = 0; MySqlLeaseMgr::convertFromDatabaseTime(expire_, valid_lifetime_, cltt); result->cltt_ = cltt; diff --git a/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc index d5535ae53f..7aa740ce01 100644 --- a/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/lease_mgr_unittest.cc @@ -272,8 +272,9 @@ TEST(Lease4, Lease4Constructor) { // Create the lease Lease4 lease(ADDRESS[i], HWADDR, sizeof(HWADDR), - CLIENTID, sizeof(CLIENTID), VALID_LIFETIME, 0, 0, current_time, - SUBNET_ID); + CLIENTID, sizeof(CLIENTID), VALID_LIFETIME, 0, 0, + current_time, SUBNET_ID, true, true, + "hostname.example.com."); EXPECT_EQ(ADDRESS[i], static_cast(lease.addr_)); EXPECT_EQ(0, lease.ext_); @@ -285,9 +286,9 @@ TEST(Lease4, Lease4Constructor) { EXPECT_EQ(current_time, lease.cltt_); EXPECT_EQ(SUBNET_ID, lease.subnet_id_); EXPECT_FALSE(lease.fixed_); - EXPECT_TRUE(lease.hostname_.empty()); - EXPECT_FALSE(lease.fqdn_fwd_); - EXPECT_FALSE(lease.fqdn_rev_); + EXPECT_EQ("hostname.example.com.", lease.hostname_); + EXPECT_TRUE(lease.fqdn_fwd_); + EXPECT_TRUE(lease.fqdn_rev_); EXPECT_TRUE(lease.comments_.empty()); } } @@ -427,7 +428,7 @@ TEST(Lease4, OperatorEquals) { // Lease6 is also defined in lease_mgr.h, so is tested in this file as well. // This test checks if the Lease6 structure can be instantiated correctly -TEST(Lease6, Lease6Constructor) { +TEST(Lease6, Lease6ConstructorDefault) { // check a variety of addresses with different bits set. const char* ADDRESS[] = { @@ -458,6 +459,10 @@ TEST(Lease6, Lease6Constructor) { EXPECT_TRUE(lease->valid_lft_ == 200); EXPECT_TRUE(lease->t1_ == 50); EXPECT_TRUE(lease->t2_ == 80); + EXPECT_FALSE(lease->fqdn_fwd_); + EXPECT_FALSE(lease->fqdn_rev_); + EXPECT_TRUE(lease->hostname_.empty()); + } // Lease6 must be instantiated with a DUID, not with NULL pointer @@ -468,6 +473,53 @@ TEST(Lease6, Lease6Constructor) { subnet_id)), InvalidOperation); } +// This test verifies that the Lease6 constructor which accepts FQDN data, +// sets the data correctly for the lease. +TEST(Lease6, Lease6ConstructorWithFQDN) { + + // check a variety of addresses with different bits set. + const char* ADDRESS[] = { + "::", "::1", "2001:db8:1::456", + "7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", + "8000::", "8000::1", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + }; + + // Other values + uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; + DuidPtr duid(new DUID(llt, sizeof(llt))); + uint32_t iaid = 7; // Just a number + SubnetID subnet_id = 8; // Just another number + + for (int i = 0; i < sizeof(ADDRESS) / sizeof(ADDRESS[0]); ++i) { + IOAddress addr(ADDRESS[i]); + Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, + duid, iaid, 100, 200, 50, 80, subnet_id, + true, true, "host.example.com.")); + + EXPECT_TRUE(lease->addr_ == addr); + EXPECT_TRUE(*lease->duid_ == *duid); + EXPECT_TRUE(lease->iaid_ == iaid); + EXPECT_TRUE(lease->subnet_id_ == subnet_id); + EXPECT_TRUE(lease->type_ == Lease6::LEASE_IA_NA); + EXPECT_TRUE(lease->preferred_lft_ == 100); + EXPECT_TRUE(lease->valid_lft_ == 200); + EXPECT_TRUE(lease->t1_ == 50); + EXPECT_TRUE(lease->t2_ == 80); + EXPECT_TRUE(lease->fqdn_fwd_); + EXPECT_TRUE(lease->fqdn_rev_); + EXPECT_EQ("host.example.com.", lease->hostname_); + } + + // Lease6 must be instantiated with a DUID, not with NULL pointer + IOAddress addr(ADDRESS[0]); + Lease6Ptr lease2; + EXPECT_THROW(lease2.reset(new Lease6(Lease6::LEASE_IA_NA, addr, + DuidPtr(), iaid, 100, 200, 50, 80, + subnet_id)), InvalidOperation); +} + + /// @brief Lease6 Equality Test /// /// Checks that the operator==() correctly compares two leases for equality. diff --git a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc index 5b2fa9ee18..2086284279 100644 --- a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -249,6 +249,9 @@ public: lease->valid_lft_ = 8677; lease->cltt_ = 168256; lease->subnet_id_ = 23; + lease->fqdn_rev_ = true; + lease->fqdn_fwd_ = false; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress4_[1]) { lease->hwaddr_ = vector(6, 0x19); @@ -257,6 +260,9 @@ public: lease->valid_lft_ = 3677; lease->cltt_ = 123456; lease->subnet_id_ = 73; + lease->fqdn_rev_ = true; + lease->fqdn_fwd_ = true; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress4_[2]) { lease->hwaddr_ = vector(6, 0x2a); @@ -265,6 +271,9 @@ public: lease->valid_lft_ = 5412; lease->cltt_ = 234567; lease->subnet_id_ = 73; // Same as lease 1 + lease->fqdn_rev_ = false; + lease->fqdn_fwd_ = false; + lease->hostname_ = ""; } else if (address == straddress4_[3]) { lease->hwaddr_ = vector(6, 0x19); // Same as lease 1 @@ -278,6 +287,9 @@ public: lease->valid_lft_ = 7000; lease->cltt_ = 234567; lease->subnet_id_ = 37; + lease->fqdn_rev_ = true; + lease->fqdn_fwd_ = true; + lease->hostname_ = "otherhost.example.com."; } else if (address == straddress4_[4]) { lease->hwaddr_ = vector(6, 0x4c); @@ -287,6 +299,9 @@ public: lease->valid_lft_ = 7736; lease->cltt_ = 222456; lease->subnet_id_ = 85; + lease->fqdn_rev_ = true; + lease->fqdn_fwd_ = true; + lease->hostname_ = "otherhost.example.com."; } else if (address == straddress4_[5]) { lease->hwaddr_ = vector(6, 0x19); // Same as lease 1 @@ -296,6 +311,9 @@ public: lease->valid_lft_ = 7832; lease->cltt_ = 227476; lease->subnet_id_ = 175; + lease->fqdn_rev_ = false; + lease->fqdn_fwd_ = false; + lease->hostname_ = "otherhost.example.com."; } else if (address == straddress4_[6]) { lease->hwaddr_ = vector(6, 0x6e); @@ -305,6 +323,9 @@ public: lease->valid_lft_ = 1832; lease->cltt_ = 627476; lease->subnet_id_ = 112; + lease->fqdn_rev_ = false; + lease->fqdn_fwd_ = true; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress4_[7]) { lease->hwaddr_ = vector(); // Empty @@ -312,6 +333,9 @@ public: lease->valid_lft_ = 7975; lease->cltt_ = 213876; lease->subnet_id_ = 19; + lease->fqdn_rev_ = true; + lease->fqdn_fwd_ = true; + lease->hostname_ = "myhost.example.com."; } else { // Unknown address, return an empty pointer. @@ -358,6 +382,9 @@ public: lease->valid_lft_ = 8677; lease->cltt_ = 168256; lease->subnet_id_ = 23; + lease->fqdn_fwd_ = true; + lease->fqdn_rev_ = true; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress6_[1]) { lease->type_ = Lease6::LEASE_IA_TA; @@ -368,6 +395,9 @@ public: lease->valid_lft_ = 3677; lease->cltt_ = 123456; lease->subnet_id_ = 73; + lease->fqdn_fwd_ = false; + lease->fqdn_rev_ = true; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress6_[2]) { lease->type_ = Lease6::LEASE_IA_PD; @@ -378,6 +408,9 @@ public: lease->valid_lft_ = 5412; lease->cltt_ = 234567; lease->subnet_id_ = 73; // Same as lease 1 + lease->fqdn_fwd_ = false; + lease->fqdn_rev_ = false; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress6_[3]) { lease->type_ = Lease6::LEASE_IA_NA; @@ -397,6 +430,9 @@ public: lease->valid_lft_ = 7000; lease->cltt_ = 234567; lease->subnet_id_ = 37; + lease->fqdn_fwd_ = true; + lease->fqdn_rev_ = false; + lease->hostname_ = "myhost.example.com."; } else if (address == straddress6_[4]) { // Same DUID and IAID as straddress6_1 @@ -408,6 +444,9 @@ public: lease->valid_lft_ = 7736; lease->cltt_ = 222456; lease->subnet_id_ = 671; + lease->fqdn_fwd_ = true; + lease->fqdn_rev_ = true; + lease->hostname_ = "otherhost.example.com."; } else if (address == straddress6_[5]) { // Same DUID and IAID as straddress6_1 @@ -420,6 +459,9 @@ public: lease->valid_lft_ = 7832; lease->cltt_ = 227476; lease->subnet_id_ = 175; + lease->fqdn_fwd_ = false; + lease->fqdn_rev_ = true; + lease->hostname_ = "hostname.example.com."; } else if (address == straddress6_[6]) { // Same DUID as straddress6_1 @@ -432,6 +474,9 @@ public: lease->valid_lft_ = 1832; lease->cltt_ = 627476; lease->subnet_id_ = 112; + lease->fqdn_fwd_ = false; + lease->fqdn_rev_ = true; + lease->hostname_ = "hostname.example.com."; } else if (address == straddress6_[7]) { // Same IAID as straddress6_1 @@ -443,6 +488,9 @@ public: lease->valid_lft_ = 7975; lease->cltt_ = 213876; lease->subnet_id_ = 19; + lease->fqdn_fwd_ = false; + lease->fqdn_rev_ = true; + lease->hostname_ = "hostname.example.com."; } else { // Unknown address, return an empty pointer. diff --git a/src/lib/dhcpsrv/tests/test_utils.cc b/src/lib/dhcpsrv/tests/test_utils.cc index ea62225c82..d8794fbff9 100644 --- a/src/lib/dhcpsrv/tests/test_utils.cc +++ b/src/lib/dhcpsrv/tests/test_utils.cc @@ -47,6 +47,9 @@ detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) { EXPECT_EQ(first->valid_lft_, second->valid_lft_); EXPECT_EQ(first->cltt_, second->cltt_); EXPECT_EQ(first->subnet_id_, second->subnet_id_); + EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_); + EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_); + EXPECT_EQ(first->hostname_, second->hostname_); } void @@ -67,6 +70,9 @@ detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) { EXPECT_EQ(first->valid_lft_, second->valid_lft_); EXPECT_EQ(first->cltt_, second->cltt_); EXPECT_EQ(first->subnet_id_, second->subnet_id_); + EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_); + EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_); + EXPECT_EQ(first->hostname_, second->hostname_); } };