mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-04 16:05:17 +00:00
[2342] Added deleteLease6 functionality
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
#include <string>
|
||||
#include <config.h>
|
||||
#include <time.h>
|
||||
#include <mysql/mysqld_error.h>
|
||||
|
||||
#include <dhcp/mysql_lease_mgr.h>
|
||||
#include <asiolink/io_address.h>
|
||||
|
||||
@@ -155,7 +157,7 @@ public:
|
||||
/// valid only for as long as this MySqlLease6Exchange object is
|
||||
/// in existence.
|
||||
MYSQL_BIND* createBindForReceive() {
|
||||
std::cout << "createBindForReceive\n";
|
||||
|
||||
// Ensure bind array clear.
|
||||
memset(bind_, 0, sizeof(bind_));
|
||||
memset(error_, 0, sizeof(error_));
|
||||
@@ -188,9 +190,8 @@ public:
|
||||
bind_[2].error = &error_[2];
|
||||
|
||||
// lease_time: unsigned int
|
||||
unsigned lease_time;
|
||||
bind_[3].buffer_type = MYSQL_TYPE_LONG;
|
||||
bind_[3].buffer = reinterpret_cast<char*>(&lease_time);
|
||||
bind_[3].buffer = reinterpret_cast<char*>(&lease_time_);
|
||||
bind_[3].is_unsigned = true_;
|
||||
bind_[3].error = &error_[3];
|
||||
|
||||
@@ -343,8 +344,9 @@ MySqlLeaseMgr::convertToDatabaseTime(time_t cltt, uint32_t valid_lft,
|
||||
}
|
||||
|
||||
void
|
||||
MySqlLeaseMgr::convertFromDatabaseTime(const MYSQL_TIME& expire, uint32_t lease_time,
|
||||
time_t& cltt, uint32_t& valid_lft) {
|
||||
MySqlLeaseMgr::convertFromDatabaseTime(const MYSQL_TIME& expire,
|
||||
uint32_t lease_time, time_t& cltt,
|
||||
uint32_t& valid_lft) {
|
||||
valid_lft = lease_time;
|
||||
|
||||
// Copy across fields from MYSQL_TIME structure.
|
||||
@@ -508,20 +510,30 @@ MySqlLeaseMgr::addLease(const Lease4Ptr& /* lease */) {
|
||||
|
||||
bool
|
||||
MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
|
||||
|
||||
// Create the MYSQL_BIND array for the lease
|
||||
MySqlLease6Exchange exchange;
|
||||
MYSQL_BIND* bind = exchange.CreateBindForSend(lease);
|
||||
|
||||
// Bind the parameters to the statement
|
||||
my_bool status = mysql_stmt_bind_param(statements_[INSERT_LEASE6], bind);
|
||||
int status = mysql_stmt_bind_param(statements_[INSERT_LEASE6], bind);
|
||||
checkError(status, INSERT_LEASE6, "unable to bind parameters");
|
||||
|
||||
// Execute the statement
|
||||
status = mysql_stmt_execute(statements_[INSERT_LEASE6]);
|
||||
checkError(status, INSERT_LEASE6, "unable to execute");
|
||||
if (status != 0) {
|
||||
|
||||
// ... and find out whether a row as inserted.
|
||||
return (mysql_stmt_affected_rows(statements_[INSERT_LEASE6]) == 1);
|
||||
// Failure: check for the special case of duplicate entry. If this is
|
||||
// the case, we return false to indicate that the row was not added.
|
||||
// Otherwise we throw an exception.
|
||||
if (mysql_errno(mysql_) == ER_DUP_ENTRY) {
|
||||
return (false);
|
||||
}
|
||||
checkError(status, INSERT_LEASE6, "unable to execute");
|
||||
}
|
||||
|
||||
// Insert succeeded
|
||||
return (true);
|
||||
}
|
||||
|
||||
Lease4Ptr
|
||||
@@ -576,7 +588,7 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
|
||||
MYSQL_BIND* outbind = exchange.createBindForReceive();
|
||||
|
||||
// Bind the input parameters to the statement
|
||||
my_bool status = mysql_stmt_bind_param(statements_[GET_LEASE6], inbind);
|
||||
int status = mysql_stmt_bind_param(statements_[GET_LEASE6], inbind);
|
||||
checkError(status, GET_LEASE6, "unable to bind WHERE clause parameter");
|
||||
|
||||
// Bind the output parameters to the statement
|
||||
@@ -612,8 +624,6 @@ MySqlLeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
|
||||
checkError(status, GET_LEASE6, "unable to fetch results");
|
||||
|
||||
} else {
|
||||
std::cout << "In the truncation clause\n";
|
||||
|
||||
// We are ignoring truncation for now, so the only other result is
|
||||
// no data was found. In that case, we return a null Lease6 structure.
|
||||
// This has already been set, so ther action is a no-op.
|
||||
@@ -648,8 +658,33 @@ MySqlLeaseMgr::deleteLease4(const isc::asiolink::IOAddress& /* addr */) {
|
||||
}
|
||||
|
||||
bool
|
||||
MySqlLeaseMgr::deleteLease6(const isc::asiolink::IOAddress& /* addr */) {
|
||||
return (false);
|
||||
MySqlLeaseMgr::deleteLease6(const isc::asiolink::IOAddress& addr) {
|
||||
|
||||
// Set up the WHERE clause value
|
||||
MYSQL_BIND inbind[1];
|
||||
memset(inbind, 0, sizeof(inbind));
|
||||
|
||||
std::string addr6 = addr.toText();
|
||||
unsigned long addr6_length = addr6.size();
|
||||
|
||||
inbind[0].buffer_type = MYSQL_TYPE_STRING;
|
||||
inbind[0].buffer = const_cast<char*>(addr6.c_str());
|
||||
inbind[0].buffer_length = addr6_length;
|
||||
inbind[0].length = &addr6_length;
|
||||
|
||||
// Bind the input parameters to the statement
|
||||
int status = mysql_stmt_bind_param(statements_[DELETE_LEASE6], inbind);
|
||||
checkError(status, DELETE_LEASE6, "unable to bind WHERE clause parameter");
|
||||
|
||||
// Execute
|
||||
status = mysql_stmt_execute(statements_[DELETE_LEASE6]);
|
||||
checkError(status, DELETE_LEASE6, "unable to execute");
|
||||
|
||||
// See how many rows were affected. Note that the statement may delete
|
||||
// multiple rows.
|
||||
return (mysql_stmt_affected_rows(statements_[DELETE_LEASE6]) > 0);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string
|
||||
|
@@ -97,6 +97,7 @@ public:
|
||||
/// @return smart pointer to the lease (or NULL if a lease is not found)
|
||||
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress& addr) const;
|
||||
|
||||
|
||||
/// @brief Returns existing IPv4 leases for specified hardware address.
|
||||
///
|
||||
/// Although in the usual case there will be only one lease, for mobile
|
||||
@@ -314,6 +315,7 @@ private:
|
||||
///
|
||||
/// The contents of the enum are indexes into the list of SQL statements
|
||||
enum StatementIndex {
|
||||
DELETE_LEASE6, // Delete from lease6 by address
|
||||
GET_LEASE6, // Get lease 6 by address
|
||||
GET_VERSION, // Obtain version number
|
||||
INSERT_LEASE6, // Add entry to lease6 table
|
||||
@@ -360,12 +362,13 @@ private:
|
||||
/// @param what High-level description of the error
|
||||
///
|
||||
/// @exception DbOperationError Error doing a database operation
|
||||
inline void checkError(my_bool status, StatementIndex index,
|
||||
inline void checkError(int status, StatementIndex index,
|
||||
const char* what) const {
|
||||
if (status != 0) {
|
||||
isc_throw(DbOperationError, what << " for <" <<
|
||||
raw_statements_[index] << ">, reason: " <<
|
||||
mysql_error(mysql_));
|
||||
mysql_error(mysql_) << " (error code " <<
|
||||
mysql_errno(mysql_) << ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -151,36 +151,72 @@ TEST_F(MySqlLeaseMgrTest, CheckVersion) {
|
||||
EXPECT_EQ(1, version.second);
|
||||
}
|
||||
|
||||
/// @brief Print Elements of Lease6 Structure
|
||||
///
|
||||
/// @param lease Pointer to lease to print
|
||||
/// @param title Title to print before the lease information
|
||||
void
|
||||
printLease6(const Lease6Ptr& lease, const char* title = NULL) {
|
||||
if (title != NULL) {
|
||||
cout << title << "\n";
|
||||
}
|
||||
|
||||
cout << " Type: ";
|
||||
switch (lease->type_) {
|
||||
case Lease6::LEASE_IA_NA:
|
||||
cout << "IA_NA\n";
|
||||
break;
|
||||
case Lease6::LEASE_IA_TA:
|
||||
cout << "IA_TA\n";
|
||||
break;
|
||||
case Lease6::LEASE_IA_PD:
|
||||
cout << "IA_PD\n";
|
||||
break;
|
||||
default:
|
||||
cout << "unknown (" << static_cast<int>(lease->type_) << ")\n";
|
||||
}
|
||||
cout << " Address: " << lease->addr_.toText() << "\n";
|
||||
cout << " Prefix length: " << static_cast<int>(lease->prefixlen_) << "\n";
|
||||
cout << " IAID: " << lease->iaid_ << "\n";
|
||||
cout << " Pref life: " << lease->preferred_lft_ << "\n";
|
||||
cout << " Valid life: " << lease->valid_lft_ << "\n";
|
||||
cout << " Cltt: " << lease->cltt_ << "\n";
|
||||
cout << " Subnet ID: " << lease->subnet_id_ << "\n";
|
||||
}
|
||||
|
||||
/// @brief Compare Lease4 Structure
|
||||
bool
|
||||
compareLease6(const Lease6Ptr& l1, const Lease6Ptr& l2) {
|
||||
compareLease6(const Lease6Ptr& first, const Lease6Ptr& second) {
|
||||
return (
|
||||
l1->type_ == l2->type_ &&
|
||||
l1->addr_ == l2->addr_ &&
|
||||
l1->prefixlen_ == l2->prefixlen_ &&
|
||||
l1->iaid_ == l2->iaid_ &&
|
||||
l1->hwaddr_ == l2->hwaddr_ &&
|
||||
*l1->duid_ == *l2->duid_ &&
|
||||
l1->preferred_lft_ == l2->preferred_lft_ &&
|
||||
l1->valid_lft_ == l2->valid_lft_ &&
|
||||
l1->cltt_ == l2->cltt_ &&
|
||||
l1->subnet_id_ == l2->subnet_id_
|
||||
first->type_ == second->type_ &&
|
||||
first->addr_ == second->addr_ &&
|
||||
first->prefixlen_ == second->prefixlen_ &&
|
||||
first->iaid_ == second->iaid_ &&
|
||||
first->hwaddr_ == second->hwaddr_ &&
|
||||
*first->duid_ == *second->duid_ &&
|
||||
first->preferred_lft_ == second->preferred_lft_ &&
|
||||
first->valid_lft_ == second->valid_lft_ &&
|
||||
first->cltt_ == second->cltt_ &&
|
||||
first->subnet_id_ == second->subnet_id_
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
detailCompareLease6(const Lease6Ptr& l1, const Lease6Ptr& l2) {
|
||||
EXPECT_EQ(l1->type_, l2->type_);
|
||||
EXPECT_EQ(l1->addr_, l2->addr_);
|
||||
EXPECT_EQ(l1->prefixlen_, l2->prefixlen_);
|
||||
EXPECT_EQ(l1->iaid_, l2->iaid_);
|
||||
EXPECT_TRUE(l1->hwaddr_ == l2->hwaddr_);
|
||||
EXPECT_TRUE(*l1->duid_ == *l2->duid_);
|
||||
EXPECT_EQ(l1->preferred_lft_, l2->preferred_lft_);
|
||||
EXPECT_EQ(l1->valid_lft_, l2->valid_lft_);
|
||||
EXPECT_EQ(l1->cltt_, l2->cltt_);
|
||||
EXPECT_EQ(l1->subnet_id_, l2->subnet_id_);
|
||||
detailCompareLease6(const Lease6Ptr& first, const Lease6Ptr& second) {
|
||||
EXPECT_EQ(first->type_, second->type_);
|
||||
|
||||
// Compare address strings - odd things happen when they are different
|
||||
// as the EXPECT_EQ appears to call the operator uint32_t() function,
|
||||
// which causes an exception to be thrown for IPv6 addresses.
|
||||
EXPECT_EQ(first->addr_.toText(), second->addr_.toText());
|
||||
EXPECT_EQ(first->prefixlen_, second->prefixlen_);
|
||||
EXPECT_EQ(first->iaid_, second->iaid_);
|
||||
EXPECT_TRUE(first->hwaddr_ == second->hwaddr_);
|
||||
EXPECT_TRUE(*first->duid_ == *second->duid_);
|
||||
EXPECT_EQ(first->preferred_lft_, second->preferred_lft_);
|
||||
EXPECT_EQ(first->valid_lft_, second->valid_lft_);
|
||||
EXPECT_EQ(first->cltt_, second->cltt_);
|
||||
EXPECT_EQ(first->subnet_id_, second->subnet_id_);
|
||||
}
|
||||
|
||||
/// @brief Initialize Lease
|
||||
@@ -219,7 +255,7 @@ TEST_F(MySqlLeaseMgrTest, BasicLease6) {
|
||||
l1->hwaddr_ = std::vector<uint8_t>(6, 0x42); // Six hex 42's
|
||||
l1->duid_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x42)));
|
||||
l1->preferred_lft_ = 3600; // Preferred lifetime
|
||||
l1->valid_lft_ = 3600; // Actual lifetime
|
||||
l1->valid_lft_ = 3677; // Actual lifetime
|
||||
l1->cltt_ = 123456; // Current time of day
|
||||
l1->subnet_id_ = 73; // Arbitrary number
|
||||
|
||||
@@ -227,47 +263,49 @@ TEST_F(MySqlLeaseMgrTest, BasicLease6) {
|
||||
Lease6Ptr l2(new Lease6());
|
||||
initializeUnusedLease6(l2);
|
||||
|
||||
l2->type_ = Lease6::LEASE_IA_TA;
|
||||
l2->addr_ = L1_ADDRESS;
|
||||
l2->prefixlen_ = 0;
|
||||
l2->type_ = Lease6::LEASE_IA_PD;
|
||||
l2->addr_ = L2_ADDRESS;
|
||||
l2->prefixlen_ = 7;
|
||||
l2->iaid_ = 89;
|
||||
l2->hwaddr_ = std::vector<uint8_t>(6, 0xf43); // Six hex 42's
|
||||
l2->duid_ = boost::shared_ptr<DUID>(new DUID(vector<uint8_t>(8, 0x3a)));
|
||||
l2->preferred_lft_ = 1800; // Preferred lifetime
|
||||
l2->valid_lft_ = 5400; // Actual lifetime
|
||||
l2->valid_lft_ = 5412; // Actual lifetime
|
||||
l2->cltt_ = 234567; // Current time of day
|
||||
l2->subnet_id_ = l1->subnet_id_; // Same as l1
|
||||
|
||||
// Sanity check that the leases are different
|
||||
ASSERT_FALSE(compareLease6(l1, l2));
|
||||
|
||||
// Start the tests. Add the first lease to the database. Then read it
|
||||
// back to see whether it is what we think it is.
|
||||
// Start the tests. Add two leases to the database, read them back and
|
||||
// check they are what we think they are.
|
||||
Lease6Ptr l_returned;
|
||||
|
||||
ASSERT_TRUE(lmptr_->addLease(l1));
|
||||
lmptr_->commit();
|
||||
EXPECT_TRUE(lmptr_->addLease(l1));
|
||||
EXPECT_TRUE(lmptr_->addLease(l2));
|
||||
|
||||
l_returned = lmptr_->getLease6(L1_ADDRESS);
|
||||
EXPECT_TRUE(l_returned);
|
||||
detailCompareLease6(l1, l_returned);
|
||||
lmptr_->rollback();
|
||||
/*
|
||||
// Delete the lease and check that it has been deleted.
|
||||
|
||||
l_returned = lmptr_->getLease6(L2_ADDRESS);
|
||||
EXPECT_TRUE(l_returned);
|
||||
detailCompareLease6(l2, l_returned);
|
||||
|
||||
// Check that we can't add a second lease with the same address
|
||||
EXPECT_FALSE(lmptr_->addLease(l1));
|
||||
|
||||
// Delete a lease, check that it's gone, and that we can't delete it
|
||||
// a second time.
|
||||
EXPECT_TRUE(lmptr_->deleteLease6(L1_ADDRESS));
|
||||
l_returned = lmptr_->getLease6(L1_ADDRESS);
|
||||
EXPECT_FALSE(l_returned);
|
||||
|
||||
// Add the address again and check that we can't add it a second time
|
||||
ASSERT_TRUE(lmptr_->addLease(l1));
|
||||
ASSERT_FALSE(lmptr_->addLease(l1));
|
||||
|
||||
// Add the second lease
|
||||
ASSERT_TRUE(lmptr_->addLease(l2));
|
||||
|
||||
// Finally, delete the lease and check we can't delete it again.
|
||||
EXPECT_TRUE(lmptr_->deleteLease6(L1_ADDRESS));
|
||||
EXPECT_FALSE(lmptr_->deleteLease6(L1_ADDRESS));
|
||||
*/
|
||||
|
||||
// Check that the second address is still there.
|
||||
l_returned = lmptr_->getLease6(L2_ADDRESS);
|
||||
EXPECT_TRUE(l_returned);
|
||||
detailCompareLease6(l2, l_returned);
|
||||
}
|
||||
|
||||
}; // end of anonymous namespace
|
||||
|
Reference in New Issue
Block a user