2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-29 13:07:50 +00:00

[#2753] Rebased with new schemas

This commit is contained in:
Francis Dupont 2023-03-30 22:51:46 +02:00
parent 5d6870557e
commit d4c3a32c8a
8 changed files with 2067 additions and 64 deletions

View File

@ -865,6 +865,16 @@ of leases beginning with the specified address.
A debug message issued when the server is attempting to obtain a page A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address. of leases beginning with the specified address.
% DHCPSRV_MYSQL_GET_RELAYID4 obtaining at most %1 IPv4 leases starting from address %2 with relay id %3 and cltt between %4 and %5
A debug message issued when the server is attempting to obtain a page of
IPv4 leases beginning with the specified address with a relay id and client
transaction time between start and end dates.
% DHCPSRV_MYSQL_GET_REMOTEID4 obtaining at most %1 IPv4 leases starting from address %2 with remote id %3 and cltt between %4 and %5
A debug message issued when the server is attempting to obtain a page of
IPv4 leases beginning with the specified address with a remote id and client
transaction time between start and end dates.
% DHCPSRV_MYSQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1 % DHCPSRV_MYSQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1
A debug message issued when the server is attempting to obtain all IPv4 A debug message issued when the server is attempting to obtain all IPv4
leases for a given subnet identifier from the MySQL database. leases for a given subnet identifier from the MySQL database.
@ -1097,6 +1107,16 @@ of leases beginning with the specified address.
A debug message issued when the server is attempting to obtain a page A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address. of leases beginning with the specified address.
% DHCPSRV_PGSQL_GET_RELAYID4 obtaining at most %1 IPv4 leases starting from address %2 with relay id %3 and cltt between %4 and %5
A debug message issued when the server is attempting to obtain a page of
IPv4 leases beginning with the specified address with a relay id and client
transaction time between start and end dates.
% DHCPSRV_PGSQL_GET_REMOTEID4 obtaining at most %1 IPv4 leases starting from address %2 with remote id %3 and cltt between %4 and %5
A debug message issued when the server is attempting to obtain a page of
IPv4 leases beginning with the specified address with a remote id and client
transaction time between start and end dates.
% DHCPSRV_PGSQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1 % DHCPSRV_PGSQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1
A debug message issued when the server is attempting to obtain all IPv4 A debug message issued when the server is attempting to obtain all IPv4
leases for a given subnet identifier from the PostgreSQL database. leases for a given subnet identifier from the PostgreSQL database.

View File

@ -116,48 +116,48 @@ tagged_statements = { {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4"}, "FROM lease4"},
{MySqlLeaseMgr::GET_LEASE4_ADDR, {MySqlLeaseMgr::GET_LEASE4_ADDR,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE address = ?"}, "WHERE address = ?"},
{MySqlLeaseMgr::GET_LEASE4_CLIENTID, {MySqlLeaseMgr::GET_LEASE4_CLIENTID,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE client_id = ?"}, "WHERE client_id = ?"},
{MySqlLeaseMgr::GET_LEASE4_CLIENTID_SUBID, {MySqlLeaseMgr::GET_LEASE4_CLIENTID_SUBID,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE client_id = ? AND subnet_id = ?"}, "WHERE client_id = ? AND subnet_id = ?"},
{MySqlLeaseMgr::GET_LEASE4_HWADDR, {MySqlLeaseMgr::GET_LEASE4_HWADDR,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE hwaddr = ?"}, "WHERE hwaddr = ?"},
{MySqlLeaseMgr::GET_LEASE4_HWADDR_SUBID, {MySqlLeaseMgr::GET_LEASE4_HWADDR_SUBID,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE hwaddr = ? AND subnet_id = ?"}, "WHERE hwaddr = ? AND subnet_id = ?"},
{MySqlLeaseMgr::GET_LEASE4_PAGE, {MySqlLeaseMgr::GET_LEASE4_PAGE,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE address > ? " "WHERE address > ? "
"ORDER BY address " "ORDER BY address "
@ -166,27 +166,123 @@ tagged_statements = { {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE subnet_id = ?"}, "WHERE subnet_id = ?"},
{MySqlLeaseMgr::GET_LEASE4_HOSTNAME, {MySqlLeaseMgr::GET_LEASE4_HOSTNAME,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE hostname = ?"}, "WHERE hostname = ?"},
{MySqlLeaseMgr::GET_LEASE4_EXPIRE, {MySqlLeaseMgr::GET_LEASE4_EXPIRE,
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE state != ? " "WHERE state != ? "
"AND valid_lifetime != 4294967295 " "AND valid_lifetime != 4294967295 "
"AND expire < ? " "AND expire < ? "
"ORDER BY expire ASC " "ORDER BY expire ASC "
"LIMIT ?"}, "LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_RELAYID,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = ? and address > ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_RELAYID_QST,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = ? and address > ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" >= ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_RELAYID_QSET,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = ? and address > ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" >= ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" <= ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_RELAYID_QET,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = ? and address > ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" <= ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_REMOTEID,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = ? and address > ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_REMOTEID_QST,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = ? and address > ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" >= ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_REMOTEID_QSET,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = ? and address > ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" >= ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" <= ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE4_REMOTEID_QET,
"SELECT address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = ? and address > ? "
" and UNIX_TIMESTAMP(expire) - IF"
"(valid_lifetime = 4294967295, 0, valid_lifetime)"
" <= ? "
"ORDER BY address "
"LIMIT ?"},
{MySqlLeaseMgr::GET_LEASE6, {MySqlLeaseMgr::GET_LEASE6,
"SELECT address, duid, valid_lifetime, " "SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, " "expire, subnet_id, pref_lifetime, "
@ -278,8 +374,8 @@ tagged_statements = { {
"INSERT INTO lease4(address, hwaddr, client_id, " "INSERT INTO lease4(address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, " "valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context) " "state, user_context, relay_id, remote_id) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"}, "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"},
{MySqlLeaseMgr::INSERT_LEASE6, {MySqlLeaseMgr::INSERT_LEASE6,
"INSERT INTO lease6(address, duid, valid_lifetime, " "INSERT INTO lease6(address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, " "expire, subnet_id, pref_lifetime, "
@ -293,7 +389,8 @@ tagged_statements = { {
"client_id = ?, valid_lifetime = ?, expire = ?, " "client_id = ?, valid_lifetime = ?, expire = ?, "
"subnet_id = ?, fqdn_fwd = ?, fqdn_rev = ?, " "subnet_id = ?, fqdn_fwd = ?, fqdn_rev = ?, "
"hostname = ?, " "hostname = ?, "
"state = ?, user_context = ? " "state = ?, user_context = ?, "
"relay_id = ?, remote_id = ? "
"WHERE address = ? AND expire = ?"}, "WHERE address = ? AND expire = ?"},
{MySqlLeaseMgr::UPDATE_LEASE6, {MySqlLeaseMgr::UPDATE_LEASE6,
"UPDATE lease6 SET address = ?, duid = ?, " "UPDATE lease6 SET address = ?, duid = ?, "
@ -426,7 +523,7 @@ public:
class MySqlLease4Exchange : public MySqlLeaseExchange { class MySqlLease4Exchange : public MySqlLeaseExchange {
/// @brief Set number of database columns for this lease structure /// @brief Set number of database columns for this lease structure
static const size_t LEASE_COLUMNS = 11; static const size_t LEASE_COLUMNS = 13;
public: public:
@ -439,11 +536,15 @@ public:
subnet_id_(0), valid_lifetime_(0), subnet_id_(0), valid_lifetime_(0),
fqdn_fwd_(false), fqdn_rev_(false), hostname_length_(0), fqdn_fwd_(false), fqdn_rev_(false), hostname_length_(0),
state_(0), user_context_length_(0), state_(0), user_context_length_(0),
user_context_null_(MLM_FALSE) { user_context_null_(MLM_FALSE),
relay_id_null_(MLM_FALSE),
remote_id_null_(MLM_FALSE) {
memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_)); memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_));
memset(client_id_buffer_, 0, sizeof(client_id_buffer_)); memset(client_id_buffer_, 0, sizeof(client_id_buffer_));
memset(hostname_buffer_, 0, sizeof(hostname_buffer_)); memset(hostname_buffer_, 0, sizeof(hostname_buffer_));
memset(user_context_, 0, sizeof(user_context_)); memset(user_context_, 0, sizeof(user_context_));
memset(relay_id_buffer_, 0, sizeof(relay_id_buffer_));
memset(remote_id_buffer_, 0, sizeof(remote_id_buffer_));
std::fill(&error_[0], &error_[LEASE_COLUMNS], MLM_FALSE); std::fill(&error_[0], &error_[LEASE_COLUMNS], MLM_FALSE);
// Set the column names (for error messages) // Set the column names (for error messages)
@ -458,7 +559,9 @@ public:
columns_[8] = "hostname"; columns_[8] = "hostname";
columns_[9] = "state"; columns_[9] = "state";
columns_[10] = "user_context"; columns_[10] = "user_context";
BOOST_STATIC_ASSERT(10 < LEASE_COLUMNS); columns_[11] = "relay_id";
columns_[12] = "remote_id";
BOOST_STATIC_ASSERT(12 < LEASE_COLUMNS);
} }
/// @brief Create MYSQL_BIND objects for Lease4 Pointer /// @brief Create MYSQL_BIND objects for Lease4 Pointer
@ -639,6 +742,36 @@ public:
bind_[10].buffer_type = MYSQL_TYPE_NULL; bind_[10].buffer_type = MYSQL_TYPE_NULL;
} }
// relay_id: varbinary(128)
relay_id_ = lease_->relay_id_;
if (!relay_id_.empty()) {
bind_[11].buffer_type = MYSQL_TYPE_BLOB;
bind_[11].buffer = reinterpret_cast<char*>(&relay_id_[0]);
relay_id_length_ = relay_id_.size();
bind_[11].buffer_length = relay_id_length_;
bind_[11].length = &relay_id_length_;
} else {
bind_[11].buffer_type = MYSQL_TYPE_NULL;
relay_id_null_ = MLM_TRUE;
bind_[11].buffer = NULL;
bind_[11].is_null = &relay_id_null_;
}
// remote_id: varbinary(128)
remote_id_ = lease_->remote_id_;
if (!remote_id_.empty()) {
bind_[12].buffer_type = MYSQL_TYPE_BLOB;
bind_[12].buffer = reinterpret_cast<char*>(&remote_id_[0]);
remote_id_length_ = remote_id_.size();
bind_[12].buffer_length = remote_id_length_;
bind_[12].length = &remote_id_length_;
} else {
bind_[12].buffer_type = MYSQL_TYPE_NULL;
remote_id_null_ = MLM_TRUE;
bind_[12].buffer = NULL;
bind_[12].is_null = &remote_id_null_;
}
// Add the error flags // Add the error flags
setErrorIndicators(bind_, error_, LEASE_COLUMNS); setErrorIndicators(bind_, error_, LEASE_COLUMNS);
@ -759,6 +892,22 @@ public:
bind_[10].length = &user_context_length_; bind_[10].length = &user_context_length_;
bind_[10].is_null = &user_context_null_; bind_[10].is_null = &user_context_null_;
// relay_id: varbinary(128)
relay_id_length_ = sizeof(relay_id_buffer_);
bind_[11].buffer_type = MYSQL_TYPE_BLOB;
bind_[11].buffer = reinterpret_cast<char*>(relay_id_buffer_);
bind_[11].buffer_length = relay_id_length_;
bind_[11].length = &relay_id_length_;
bind_[11].is_null = &relay_id_null_;
// remote_id: varbinary(128)
remote_id_length_ = sizeof(remote_id_buffer_);
bind_[12].buffer_type = MYSQL_TYPE_BLOB;
bind_[12].buffer = reinterpret_cast<char*>(remote_id_buffer_);
bind_[12].buffer_length = remote_id_length_;
bind_[12].length = &remote_id_length_;
bind_[12].is_null = &remote_id_null_;
// Add the error flags // Add the error flags
setErrorIndicators(bind_, error_, LEASE_COLUMNS); setErrorIndicators(bind_, error_, LEASE_COLUMNS);
@ -837,6 +986,18 @@ public:
lease->setContext(ctx); lease->setContext(ctx);
} }
// Set relay id if it was set.
if (relay_id_null_ == MLM_FALSE) {
lease->relay_id_.assign(relay_id_buffer_,
relay_id_buffer_ + relay_id_length_);
}
// Set remote id if it was set.
if (remote_id_null_ == MLM_FALSE) {
lease->remote_id_.assign(remote_id_buffer_,
remote_id_buffer_ + remote_id_length_);
}
return (lease); return (lease);
} }
@ -883,6 +1044,14 @@ private:
char user_context_[USER_CONTEXT_MAX_LEN]; ///< User context char user_context_[USER_CONTEXT_MAX_LEN]; ///< User context
unsigned long user_context_length_; ///< Length of user context unsigned long user_context_length_; ///< Length of user context
my_bool user_context_null_; ///< Used when user context is null my_bool user_context_null_; ///< Used when user context is null
std::vector<uint8_t> relay_id_; ///< Relay id
uint8_t relay_id_buffer_[ClientId::MAX_CLIENT_ID_LEN]; ///< Relay id buffer
unsigned long relay_id_length_; ///< Relay id length
my_bool relay_id_null_; ///< Used when Relay id is null
std::vector<uint8_t> remote_id_; ///< Remote id
uint8_t remote_id_buffer_[ClientId::MAX_CLIENT_ID_LEN]; ///< Remote id buffer
unsigned long remote_id_length_; ///< Remote id length
my_bool remote_id_null_; ///< Used when Remote id is null
}; };
/// @brief Exchange MySQL and Lease6 Data /// @brief Exchange MySQL and Lease6 Data
@ -2487,9 +2656,9 @@ MySqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address,
inbind[0].is_unsigned = MLM_TRUE; inbind[0].is_unsigned = MLM_TRUE;
// Bind page size value // Bind page size value
size_t* ps = const_cast<size_t*>(&page_size.page_size_); uint32_t ps = static_cast<uint32_t>(page_size.page_size_);
inbind[1].buffer_type = MYSQL_TYPE_LONG; inbind[1].buffer_type = MYSQL_TYPE_LONG;
inbind[1].buffer = reinterpret_cast<char*>(ps); inbind[1].buffer = reinterpret_cast<char*>(&ps);
inbind[1].is_unsigned = MLM_TRUE; inbind[1].is_unsigned = MLM_TRUE;
// Get the leases // Get the leases
@ -2784,9 +2953,9 @@ MySqlLeaseMgr::getLeases6(const IOAddress& lower_bound_address,
inbind[0].length = &lb_address_data_size; inbind[0].length = &lb_address_data_size;
// Bind page size value // Bind page size value
size_t* ps = const_cast<size_t*>(&page_size.page_size_); uint32_t ps = static_cast<uint32_t>(page_size.page_size_);
inbind[1].buffer_type = MYSQL_TYPE_LONG; inbind[1].buffer_type = MYSQL_TYPE_LONG;
inbind[1].buffer = reinterpret_cast<char*>(ps); inbind[1].buffer = reinterpret_cast<char*>(&ps);
inbind[1].is_unsigned = MLM_TRUE; inbind[1].is_unsigned = MLM_TRUE;
// Get the leases // Get the leases
@ -3461,22 +3630,249 @@ MySqlLeaseMgr::addRemoteId6(const IOAddress& /* lease_addr */,
isc_throw(NotImplemented, "MySqlLeaseMgr::addRemoteId6 not implemented"); isc_throw(NotImplemented, "MySqlLeaseMgr::addRemoteId6 not implemented");
} }
namespace {
std::string
idToText(const OptionBuffer& id) {
std::stringstream tmp;
tmp << std::hex;
bool delim = false;
for (std::vector<uint8_t>::const_iterator it = id.begin();
it != id.end(); ++it) {
if (delim) {
tmp << ":";
}
tmp << std::setw(2) << std::setfill('0')
<< static_cast<unsigned int>(*it);
delim = true;
}
return (tmp.str());
}
} // anonymous namespace
Lease4Collection Lease4Collection
MySqlLeaseMgr::getLeases4ByRelayId(const OptionBuffer& /* relay_id */, MySqlLeaseMgr::getLeases4ByRelayId(const OptionBuffer& relay_id,
const IOAddress& /* lower_bound_address */, const IOAddress& lower_bound_address,
const LeasePageSize& /* page_size */, const LeasePageSize& page_size,
const time_t& /* qry_start_time = 0 */, const time_t& qry_start_time /* = 0 */,
const time_t& /* qry_end_time = 0 */) { const time_t& qry_end_time /* = 0 */) {
isc_throw(NotImplemented, "MySqlLeaseMgr::getLeases4ByRelayId not implemented"); // Expecting IPv4 address.
if (!lower_bound_address.isV4()) {
isc_throw(InvalidAddressFamily, "expected IPv4 address while "
"retrieving leases from the lease database, got "
<< lower_bound_address);
}
// Catch 2038 bug with 32 bit time_t.
if ((qry_start_time < 0) || (qry_end_time < 0)) {
isc_throw(BadValue, "negative time value");
}
bool have_qst = (qry_start_time > 0);
bool have_qet = (qry_end_time > 0);
// Start time must be before end time.
if (have_qst && have_qet && (qry_start_time > qry_end_time)) {
isc_throw(BadValue, "start time must be before end time");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_GET_RELAYID4)
.arg(page_size.page_size_)
.arg(lower_bound_address.toText())
.arg(idToText(relay_id))
.arg(qry_start_time)
.arg(qry_end_time);
// Prepare WHERE clause
size_t bindings = 3;
if (have_qst) {
++bindings;
}
if (have_qet) {
++bindings;
}
MYSQL_BIND inbind[bindings];
memset(inbind, 0, sizeof(inbind));
std::vector<uint8_t> relay_id_data = relay_id;
unsigned long relay_id_length = relay_id.size();
// If the relay id happens to be empty, we have to create a
// 1 byte dummy buffer and pass it to the binding.
if (relay_id_data.empty()) {
relay_id_data.resize(1);
}
// Bind relay id
inbind[0].buffer_type = MYSQL_TYPE_BLOB;
inbind[0].buffer = reinterpret_cast<char*>(&relay_id_data[0]);
inbind[0].buffer_length = relay_id_length;
inbind[0].length = &relay_id_length;
// Bind lower bound address
uint32_t lb_address_data = lower_bound_address.toUint32();
inbind[1].buffer_type = MYSQL_TYPE_LONG;
inbind[1].buffer = reinterpret_cast<char*>(&lb_address_data);
inbind[1].is_unsigned = MLM_TRUE;
size_t index = 2;
// Bind query start time.
uint32_t start_time = static_cast<uint32_t>(qry_start_time);
if (have_qst) {
inbind[index].buffer_type = MYSQL_TYPE_LONG;
inbind[index].buffer = reinterpret_cast<char*>(&start_time);
inbind[index].is_unsigned = MLM_TRUE;
++index;
}
// Bind query end time.
uint32_t end_time = static_cast<uint32_t>(qry_end_time);
if (have_qet) {
inbind[index].buffer_type = MYSQL_TYPE_LONG;
inbind[index].buffer = reinterpret_cast<char*>(&end_time);
inbind[index].is_unsigned = MLM_TRUE;
++index;
}
// Bind page size value
uint32_t ps = static_cast<uint32_t>(page_size.page_size_);
inbind[index].buffer_type = MYSQL_TYPE_LONG;
inbind[index].buffer = reinterpret_cast<char*>(&ps);
inbind[index].is_unsigned = MLM_TRUE;
StatementIndex stindex = GET_LEASE4_RELAYID;
if (have_qst && !have_qet) {
stindex = GET_LEASE4_RELAYID_QST;
} else if (have_qst && have_qet) {
stindex = GET_LEASE4_RELAYID_QSET;
} else if (!have_qst && have_qet) {
stindex = GET_LEASE4_RELAYID_QET;
}
// Get the leases
Lease4Collection result;
// Get a context
MySqlLeaseContextAlloc get_context(*this);
MySqlLeaseContextPtr ctx = get_context.ctx_;
getLeaseCollection(ctx, stindex, inbind, result);
return (result);
} }
Lease4Collection Lease4Collection
MySqlLeaseMgr::getLeases4ByRemoteId(const OptionBuffer& /* remote_id */, MySqlLeaseMgr::getLeases4ByRemoteId(const OptionBuffer& remote_id,
const IOAddress& /* lower_bound_address */, const IOAddress& lower_bound_address,
const LeasePageSize& /* page_size */, const LeasePageSize& page_size,
const time_t& /* qry_start_time = 0 */, const time_t& qry_start_time /* = 0 */,
const time_t& /* qry_end_time = 0 */) { const time_t& qry_end_time /* = 0 */) {
isc_throw(NotImplemented, "MySqlLeaseMgr::getLeases4ByRemoteId not implemented"); // Expecting IPv4 address.
if (!lower_bound_address.isV4()) {
isc_throw(InvalidAddressFamily, "expected IPv4 address while "
"retrieving leases from the lease database, got "
<< lower_bound_address);
}
// Catch 2038 bug with 32 bit time_t.
if ((qry_start_time < 0) || (qry_end_time < 0)) {
isc_throw(BadValue, "negative time value");
}
bool have_qst = (qry_start_time > 0);
bool have_qet = (qry_end_time > 0);
// Start time must be before end time.
if (have_qst && have_qet && (qry_start_time > qry_end_time)) {
isc_throw(BadValue, "start time must be before end time");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_GET_REMOTEID4)
.arg(page_size.page_size_)
.arg(lower_bound_address.toText())
.arg(idToText(remote_id))
.arg(qry_start_time)
.arg(qry_end_time);
// Prepare WHERE clause
size_t bindings = 3;
if (have_qst) {
++bindings;
}
if (have_qet) {
++bindings;
}
MYSQL_BIND inbind[bindings];
memset(inbind, 0, sizeof(inbind));
std::vector<uint8_t> remote_id_data = remote_id;
unsigned long remote_id_length = remote_id.size();
// If the remote id happens to be empty, we have to create a
// 1 byte dummy buffer and pass it to the binding.
if (remote_id_data.empty()) {
remote_id_data.resize(1);
}
// Bind remote id
inbind[0].buffer_type = MYSQL_TYPE_BLOB;
inbind[0].buffer = reinterpret_cast<char*>(&remote_id_data[0]);
inbind[0].buffer_length = remote_id_length;
inbind[0].length = &remote_id_length;
// Bind lower bound address
uint32_t lb_address_data = lower_bound_address.toUint32();
inbind[1].buffer_type = MYSQL_TYPE_LONG;
inbind[1].buffer = reinterpret_cast<char*>(&lb_address_data);
inbind[1].is_unsigned = MLM_TRUE;
size_t index = 2;
// Bind query start time.
uint32_t start_time = static_cast<uint32_t>(qry_start_time);
if (have_qst) {
inbind[index].buffer_type = MYSQL_TYPE_LONG;
inbind[index].buffer = reinterpret_cast<char*>(&start_time);
inbind[index].is_unsigned = MLM_TRUE;
++index;
}
// Bind query end time.
uint32_t end_time = static_cast<uint32_t>(qry_end_time);
if (have_qet) {
inbind[index].buffer_type = MYSQL_TYPE_LONG;
inbind[index].buffer = reinterpret_cast<char*>(&end_time);
inbind[index].is_unsigned = MLM_TRUE;
++index;
}
// Bind page size value
uint32_t ps = static_cast<uint32_t>(page_size.page_size_);
inbind[index].buffer_type = MYSQL_TYPE_LONG;
inbind[index].buffer = reinterpret_cast<char*>(&ps);
inbind[index].is_unsigned = MLM_TRUE;
StatementIndex stindex = GET_LEASE4_REMOTEID;
if (have_qst && !have_qet) {
stindex = GET_LEASE4_REMOTEID_QST;
} else if (have_qst && have_qet) {
stindex = GET_LEASE4_REMOTEID_QSET;
} else if (!have_qst && have_qet) {
stindex = GET_LEASE4_REMOTEID_QET;
}
// Get the leases
Lease4Collection result;
// Get a context
MySqlLeaseContextAlloc get_context(*this);
MySqlLeaseContextPtr ctx = get_context.ctx_;
getLeaseCollection(ctx, stindex, inbind, result);
return (result);
} }
Lease6Collection Lease6Collection

View File

@ -705,6 +705,14 @@ public:
GET_LEASE4_SUBID, // Get IPv4 leases by subnet ID GET_LEASE4_SUBID, // Get IPv4 leases by subnet ID
GET_LEASE4_HOSTNAME, // Get IPv4 leases by hostname GET_LEASE4_HOSTNAME, // Get IPv4 leases by hostname
GET_LEASE4_EXPIRE, // Get lease4 by expiration. GET_LEASE4_EXPIRE, // Get lease4 by expiration.
GET_LEASE4_RELAYID, // Get page of lease by relay ID.
GET_LEASE4_RELAYID_QST, // Get page of leases by relay ID and query start time.
GET_LEASE4_RELAYID_QSET, // Get page of leases by relay ID and query start and end times.
GET_LEASE4_RELAYID_QET, // Get page of leases by relay ID and query end time.
GET_LEASE4_REMOTEID, // Get page of lease by remote ID.
GET_LEASE4_REMOTEID_QST, // Get page of leases by remote ID and query start time.
GET_LEASE4_REMOTEID_QSET, // Get page of leases by remote ID and query start and end times.
GET_LEASE4_REMOTEID_QET, // Get page of leases by remote ID and query end time.
GET_LEASE6, // Get all IPv6 leases GET_LEASE6, // Get all IPv6 leases
GET_LEASE6_ADDR, // Get lease6 by address GET_LEASE6_ADDR, // Get lease6 by address
GET_LEASE6_DUID_IAID, // Get lease6 by DUID and IAID GET_LEASE6_DUID_IAID, // Get lease6 by DUID and IAID

View File

@ -69,7 +69,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4"}, "FROM lease4"},
// GET_LEASE4_ADDR // GET_LEASE4_ADDR
@ -78,7 +78,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE address = $1"}, "WHERE address = $1"},
@ -88,7 +88,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE client_id = $1"}, "WHERE client_id = $1"},
@ -98,7 +98,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE client_id = $1 AND subnet_id = $2"}, "WHERE client_id = $1 AND subnet_id = $2"},
@ -108,7 +108,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE hwaddr = $1"}, "WHERE hwaddr = $1"},
@ -118,7 +118,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE hwaddr = $1 AND subnet_id = $2"}, "WHERE hwaddr = $1 AND subnet_id = $2"},
@ -128,7 +128,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE address > $1 " "WHERE address > $1 "
"ORDER BY address " "ORDER BY address "
@ -140,7 +140,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE subnet_id = $1"}, "WHERE subnet_id = $1"},
@ -150,7 +150,7 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE lower(hostname) = $1"}, "WHERE lower(hostname) = $1"},
@ -160,12 +160,124 @@ PgSqlTaggedStatement tagged_statements[] = {
"SELECT address, hwaddr, client_id, " "SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, " "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, " "fqdn_fwd, fqdn_rev, hostname, "
"state, user_context " "state, user_context, relay_id, remote_id "
"FROM lease4 " "FROM lease4 "
"WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 " "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
"ORDER BY expire " "ORDER BY expire "
"LIMIT $3"}, "LIMIT $3"},
// GET_LEASE4_RELAYID
{ 3, { OID_BYTEA, OID_INT8, OID_INT8 },
"get_lease4_relayid",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = $1 and address > $2 "
"ORDER BY address "
"LIMIT $3"},
// GET_LEASE4_RELAYID_QST
{ 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
"get_lease4_relayid_qst",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = $1 and address > $2 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) >= $3 "
"ORDER BY address "
"LIMIT $4"},
// GET_LEASE4_RELAYID_QSET
{ 5, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8, OID_INT8 },
"get_lease4_relayid_qset",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = $1 and address > $2 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) >= $3 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) <= $4 "
"ORDER BY address "
"LIMIT $5"},
// GET_LEASE4_RELAYID_QET
{ 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
"get_lease4_relayid_qet",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE relay_id = $1 and address > $2 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) <= $3 "
"ORDER BY address "
"LIMIT $4"},
// GET_LEASE4_REMOTEID
{ 3, { OID_BYTEA, OID_INT8, OID_INT8 },
"get_lease4_remoteid",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = $1 and address > $2 "
"ORDER BY address "
"LIMIT $3"},
// GET_LEASE4_REMOTEID_QST
{ 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
"get_lease4_remoteid_qst",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = $1 and address > $2 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) >= $3 "
"ORDER BY address "
"LIMIT $4"},
// GET_LEASE4_REMOTEID_QSET
{ 5, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8, OID_INT8 },
"get_lease4_remoteid_qset",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = $1 and address > $2 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) >= $3 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) <= $4 "
"ORDER BY address "
"LIMIT $5"},
// GET_LEASE4_REMOTEID_QET
{ 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
"get_lease4_remoteid_qet",
"SELECT address, hwaddr, client_id, "
"valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, "
"state, user_context, relay_id, remote_id "
"FROM lease4 "
"WHERE remote_id = $1 and address > $2 "
"and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
"THEN 0 ELSE valid_lifetime END) <= $3 "
"ORDER BY address "
"LIMIT $4"},
// GET_LEASE6 // GET_LEASE6
{ 0, { OID_NONE }, { 0, { OID_NONE },
"get_lease6", "get_lease6",
@ -271,13 +383,14 @@ PgSqlTaggedStatement tagged_statements[] = {
"LIMIT $3"}, "LIMIT $3"},
// INSERT_LEASE4 // INSERT_LEASE4
{ 11, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, { 13, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT }, OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT, OID_BYTEA,
OID_BYTEA },
"insert_lease4", "insert_lease4",
"INSERT INTO lease4(address, hwaddr, client_id, " "INSERT INTO lease4(address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, " "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
"state, user_context) " "state, user_context, relay_id, remote_id) "
"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)"}, "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"},
// INSERT_LEASE6 // INSERT_LEASE6
{ 17, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, { 17, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
@ -292,14 +405,15 @@ PgSqlTaggedStatement tagged_statements[] = {
"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"}, "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"},
// UPDATE_LEASE4 // UPDATE_LEASE4
{ 13, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, { 15, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT, OID_INT8, OID_TIMESTAMP }, OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT, OID_BYTEA,
OID_BYTEA, OID_INT8, OID_TIMESTAMP },
"update_lease4", "update_lease4",
"UPDATE lease4 SET address = $1, hwaddr = $2, " "UPDATE lease4 SET address = $1, hwaddr = $2, "
"client_id = $3, valid_lifetime = $4, expire = $5, " "client_id = $3, valid_lifetime = $4, expire = $5, "
"subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, " "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
"state = $10, user_context = $11 " "state = $10, user_context = $11, relay_id = $12, remote_id = $13 "
"WHERE address = $12 AND expire = $13"}, "WHERE address = $14 AND expire = $15"},
// UPDATE_LEASE6 // UPDATE_LEASE6
{ 19, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8, { 19, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8,
@ -457,19 +571,24 @@ private:
static const size_t HOSTNAME_COL = 8; static const size_t HOSTNAME_COL = 8;
static const size_t STATE_COL = 9; static const size_t STATE_COL = 9;
static const size_t USER_CONTEXT_COL = 10; static const size_t USER_CONTEXT_COL = 10;
static const size_t RELAY_ID_COL = 11;
static const size_t REMOTE_ID_COL = 12;
/// @brief Number of columns in the table holding DHCPv4 leases. /// @brief Number of columns in the table holding DHCPv4 leases.
static const size_t LEASE_COLUMNS = 11; static const size_t LEASE_COLUMNS = 13;
public: public:
/// @brief Constructor /// @brief Constructor
PgSqlLease4Exchange() PgSqlLease4Exchange()
: lease_(), addr4_(0), client_id_length_(0) { : lease_(), addr4_(0), client_id_length_(0),
relay_id_length_(0), remote_id_length_(0) {
BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS); BOOST_STATIC_ASSERT(9 < LEASE_COLUMNS);
memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_)); memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_));
memset(client_id_buffer_, 0, sizeof(client_id_buffer_)); memset(client_id_buffer_, 0, sizeof(client_id_buffer_));
memset(relay_id_buffer_, 0, sizeof(relay_id_buffer_));
memset(remote_id_buffer_, 0, sizeof(remote_id_buffer_));
// Set the column names (for error messages) // Set the column names (for error messages)
columns_.push_back("address"); columns_.push_back("address");
@ -483,6 +602,8 @@ public:
columns_.push_back("hostname"); columns_.push_back("hostname");
columns_.push_back("state"); columns_.push_back("state");
columns_.push_back("user_context"); columns_.push_back("user_context");
columns_.push_back("relay_id");
columns_.push_back("remote_id");
} }
/// @brief Creates the bind array for sending Lease4 data to the database. /// @brief Creates the bind array for sending Lease4 data to the database.
@ -565,6 +686,19 @@ public:
user_context_ = ""; user_context_ = "";
} }
bind_array.add(user_context_); bind_array.add(user_context_);
if (!lease->relay_id_.empty()) {
bind_array.add(lease->relay_id_);
} else {
bind_array.addNull();
}
if (!lease->remote_id_.empty()) {
bind_array.add(lease->remote_id_);
} else {
bind_array.addNull();
}
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
isc_throw(DbOperationError, isc_throw(DbOperationError,
"Could not create bind array from Lease4: " "Could not create bind array from Lease4: "
@ -626,6 +760,12 @@ public:
} }
} }
convertFromBytea(r, row, RELAY_ID_COL, relay_id_buffer_,
sizeof(relay_id_buffer_), relay_id_length_);
convertFromBytea(r, row, REMOTE_ID_COL, remote_id_buffer_,
sizeof(remote_id_buffer_), remote_id_length_);
Lease4Ptr result(boost::make_shared<Lease4>(addr4_, hwaddr, Lease4Ptr result(boost::make_shared<Lease4>(addr4_, hwaddr,
client_id_buffer_, client_id_buffer_,
client_id_length_, client_id_length_,
@ -639,6 +779,16 @@ public:
result->setContext(ctx); result->setContext(ctx);
} }
if (relay_id_length_) {
result->relay_id_.assign(relay_id_buffer_,
relay_id_buffer_ + relay_id_length_);
}
if (remote_id_length_) {
result->remote_id_.assign(remote_id_buffer_,
remote_id_buffer_ + remote_id_length_);
}
return (result); return (result);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
isc_throw(DbOperationError, isc_throw(DbOperationError,
@ -658,6 +808,10 @@ private:
uint32_t addr4_; uint32_t addr4_;
size_t client_id_length_; size_t client_id_length_;
uint8_t client_id_buffer_[ClientId::MAX_CLIENT_ID_LEN]; uint8_t client_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
size_t relay_id_length_;
uint8_t relay_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
size_t remote_id_length_;
uint8_t remote_id_buffer_[ClientId::MAX_CLIENT_ID_LEN];
}; };
/// @brief Supports exchanging IPv6 leases with PostgreSQL. /// @brief Supports exchanging IPv6 leases with PostgreSQL.
@ -2657,22 +2811,203 @@ PgSqlLeaseMgr::addRemoteId6(const IOAddress& /* lease_addr */,
isc_throw(NotImplemented, "PgSqlLeaseMgr::addRemoteId6 not implemented"); isc_throw(NotImplemented, "PgSqlLeaseMgr::addRemoteId6 not implemented");
} }
namespace {
std::string
idToText(const OptionBuffer& id) {
std::stringstream tmp;
tmp << std::hex;
bool delim = false;
for (std::vector<uint8_t>::const_iterator it = id.begin();
it != id.end(); ++it) {
if (delim) {
tmp << ":";
}
tmp << std::setw(2) << std::setfill('0')
<< static_cast<unsigned int>(*it);
delim = true;
}
return (tmp.str());
}
} // anonymous namespace
Lease4Collection Lease4Collection
PgSqlLeaseMgr::getLeases4ByRelayId(const OptionBuffer& /* relay_id */, PgSqlLeaseMgr::getLeases4ByRelayId(const OptionBuffer& relay_id,
const IOAddress& /* lower_bound_address */, const IOAddress& lower_bound_address,
const LeasePageSize& /* page_size */, const LeasePageSize& page_size,
const time_t& /* qry_start_time = 0 */, const time_t& qry_start_time /* = 0 */,
const time_t& /* qry_end_time = 0 */) { const time_t& qry_end_time /* = 0 */) {
isc_throw(NotImplemented, "PgSqlLeaseMgr::getLeases4ByRelayId not implemented"); // Expecting IPv4 address.
if (!lower_bound_address.isV4()) {
isc_throw(InvalidAddressFamily, "expected IPv4 address while "
"retrieving leases from the lease database, got "
<< lower_bound_address);
}
// Catch 2038 bug with 32 bit time_t.
if ((qry_start_time < 0) || (qry_end_time < 0)) {
isc_throw(BadValue, "negative time value");
}
bool have_qst = (qry_start_time > 0);
bool have_qet = (qry_end_time > 0);
// Start time must be before end time.
if (have_qst && have_qet && (qry_start_time > qry_end_time)) {
isc_throw(BadValue, "start time must be before end time");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_GET_RELAYID4)
.arg(page_size.page_size_)
.arg(lower_bound_address.toText())
.arg(idToText(relay_id))
.arg(qry_start_time)
.arg(qry_end_time);
// Prepare WHERE clause
PsqlBindArray bind_array;
// Bind relay id
if (!relay_id.empty()) {
bind_array.add(relay_id);
} else {
bind_array.add("");
}
// Bind lower bound address
std::string lb_address_data =
boost::lexical_cast<std::string>(lower_bound_address.toUint32());
bind_array.add(lb_address_data);
// Bind query start time.
std::string start_time_str;
if (have_qst) {
start_time_str = boost::lexical_cast<std::string>(qry_start_time);
bind_array.add(start_time_str);
}
// Bind query end time.
std::string end_time_str;
if (have_qet) {
end_time_str = boost::lexical_cast<std::string>(qry_end_time);
bind_array.add(end_time_str);
}
// Bind page size value
std::string page_size_data =
boost::lexical_cast<std::string>(page_size.page_size_);
bind_array.add(page_size_data);
StatementIndex stindex = GET_LEASE4_RELAYID;
if (have_qst && !have_qet) {
stindex = GET_LEASE4_RELAYID_QST;
} else if (have_qst && have_qet) {
stindex = GET_LEASE4_RELAYID_QSET;
} else if (!have_qst && have_qet) {
stindex = GET_LEASE4_RELAYID_QET;
}
// Get the leases
Lease4Collection result;
// Get a context
PgSqlLeaseContextAlloc get_context(*this);
PgSqlLeaseContextPtr ctx = get_context.ctx_;
getLeaseCollection(ctx, stindex, bind_array, result);
return (result);
} }
Lease4Collection Lease4Collection
PgSqlLeaseMgr::getLeases4ByRemoteId(const OptionBuffer& /* remote_id */, PgSqlLeaseMgr::getLeases4ByRemoteId(const OptionBuffer& remote_id,
const IOAddress& /* lower_bound_address */, const IOAddress& lower_bound_address,
const LeasePageSize& /* page_size */, const LeasePageSize& page_size,
const time_t& /* qry_start_time = 0 */, const time_t& qry_start_time /* = 0 */,
const time_t& /* qry_end_time = 0 */) { const time_t& qry_end_time /* = 0 */) {
isc_throw(NotImplemented, "PgSqlLeaseMgr::getLeases4ByRemoteId not implemented"); // Expecting IPv4 address.
if (!lower_bound_address.isV4()) {
isc_throw(InvalidAddressFamily, "expected IPv4 address while "
"retrieving leases from the lease database, got "
<< lower_bound_address);
}
// Catch 2038 bug with 32 bit time_t.
if ((qry_start_time < 0) || (qry_end_time < 0)) {
isc_throw(BadValue, "negative time value");
}
bool have_qst = (qry_start_time > 0);
bool have_qet = (qry_end_time > 0);
// Start time must be before end time.
if (have_qst && have_qet && (qry_start_time > qry_end_time)) {
isc_throw(BadValue, "start time must be before end time");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_GET_REMOTEID4)
.arg(page_size.page_size_)
.arg(lower_bound_address.toText())
.arg(idToText(remote_id))
.arg(qry_start_time)
.arg(qry_end_time);
// Prepare WHERE clause
PsqlBindArray bind_array;
// Bind remote id
if (!remote_id.empty()) {
bind_array.add(remote_id);
} else {
bind_array.add("");
}
// Bind lower bound address
std::string lb_address_data =
boost::lexical_cast<std::string>(lower_bound_address.toUint32());
bind_array.add(lb_address_data);
// Bind query start time.
std::string start_time_str;
if (have_qst) {
start_time_str = boost::lexical_cast<std::string>(qry_start_time);
bind_array.add(start_time_str);
}
// Bind query end time.
std::string end_time_str;
if (have_qet) {
end_time_str = boost::lexical_cast<std::string>(qry_end_time);
bind_array.add(end_time_str);
}
// Bind page size value
std::string page_size_data =
boost::lexical_cast<std::string>(page_size.page_size_);
bind_array.add(page_size_data);
StatementIndex stindex = GET_LEASE4_REMOTEID;
if (have_qst && !have_qet) {
stindex = GET_LEASE4_REMOTEID_QST;
} else if (have_qst && have_qet) {
stindex = GET_LEASE4_REMOTEID_QSET;
} else if (!have_qst && have_qet) {
stindex = GET_LEASE4_REMOTEID_QET;
}
// Get the leases
Lease4Collection result;
// Get a context
PgSqlLeaseContextAlloc get_context(*this);
PgSqlLeaseContextPtr ctx = get_context.ctx_;
getLeaseCollection(ctx, stindex, bind_array, result);
return (result);
} }
Lease6Collection Lease6Collection

View File

@ -681,6 +681,14 @@ public:
GET_LEASE4_SUBID, // Get IPv4 leases by subnet ID GET_LEASE4_SUBID, // Get IPv4 leases by subnet ID
GET_LEASE4_HOSTNAME, // Get IPv4 leases by hostname GET_LEASE4_HOSTNAME, // Get IPv4 leases by hostname
GET_LEASE4_EXPIRE, // Get lease4 by expiration. GET_LEASE4_EXPIRE, // Get lease4 by expiration.
GET_LEASE4_RELAYID, // Get page of lease by relay ID.
GET_LEASE4_RELAYID_QST, // Get page of leases by relay ID and query start time.
GET_LEASE4_RELAYID_QSET, // Get page of leases by relay ID and query start and end times.
GET_LEASE4_RELAYID_QET, // Get page of leases by relay ID and query end time.
GET_LEASE4_REMOTEID, // Get page of lease by remote ID.
GET_LEASE4_REMOTEID_QST, // Get page of leases by remote ID and query start time.
GET_LEASE4_REMOTEID_QSET, // Get page of leases by remote ID and query start and end times.
GET_LEASE4_REMOTEID_QET, // Get page of leases by remote ID and query end time.
GET_LEASE6, // Get all IPv6 leases GET_LEASE6, // Get all IPv6 leases
GET_LEASE6_ADDR, // Get lease6 by address GET_LEASE6_ADDR, // Get lease6 by address
GET_LEASE6_DUID_IAID, // Get lease6 by DUID and IAID GET_LEASE6_DUID_IAID, // Get lease6 by DUID and IAID

View File

@ -116,10 +116,12 @@ libdhcpsrv_unittests_SOURCES += dhcp_parsers_unittest.cc
libdhcpsrv_unittests_SOURCES += ncr_generator_unittest.cc libdhcpsrv_unittests_SOURCES += ncr_generator_unittest.cc
if HAVE_MYSQL if HAVE_MYSQL
libdhcpsrv_unittests_SOURCES += mysql_lease_mgr_unittest.cc libdhcpsrv_unittests_SOURCES += mysql_lease_mgr_unittest.cc
libdhcpsrv_unittests_SOURCES += mysql_lease_extended_info_unittest.cc
libdhcpsrv_unittests_SOURCES += mysql_host_data_source_unittest.cc libdhcpsrv_unittests_SOURCES += mysql_host_data_source_unittest.cc
endif endif
if HAVE_PGSQL if HAVE_PGSQL
libdhcpsrv_unittests_SOURCES += pgsql_lease_mgr_unittest.cc libdhcpsrv_unittests_SOURCES += pgsql_lease_mgr_unittest.cc
libdhcpsrv_unittests_SOURCES += pgsql_lease_extended_info_unittest.cc
libdhcpsrv_unittests_SOURCES += pgsql_host_data_source_unittest.cc libdhcpsrv_unittests_SOURCES += pgsql_host_data_source_unittest.cc
endif endif
libdhcpsrv_unittests_SOURCES += pool_unittest.cc libdhcpsrv_unittests_SOURCES += pool_unittest.cc

View File

@ -0,0 +1,617 @@
// Copyright (C) 2023 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 <asiolink/io_address.h>
#include <cc/data.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/mysql_lease_mgr.h>
#include <mysql/testutils/mysql_schema.h>
#include <testutils/gtest_utils.h>
#include <testutils/multi_threading_utils.h>
#include <gtest/gtest.h>
using namespace isc;
using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::db;
using namespace isc::db::test;
using namespace isc::dhcp;
using namespace isc::test;
using namespace isc::util;
using namespace std;
namespace {
/// @brief IPv4 addresses used in the tests.
const vector<string> ADDRESS4 = {
"192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3",
"192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7"
};
/// @brief DUIDs used in the tests.
const vector<string> DUIDS = {
"wwwwwwww", "BBBBBBBB", "::::::::", "0123456789acdef",
"BBBBBBBB", "$$$$$$$$", "^^^^^^^^", "\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5"
};
/// @brief Test fixture class for extended info tests.
class MySqlExtendedInfoTest : public ::testing::Test {
public:
/// @brief Constructor.
MySqlExtendedInfoTest() {
// Ensure we have the proper schema with no transient data.
createMySQLSchema();
// Connect to the database.
try {
LeaseMgrFactory::create(validMySQLConnectionString());
} catch (...) {
std::cerr << "*** ERROR: unable to open database. The test\n"
"*** environment is broken and must be fixed before\n"
"*** the MySQL tests will run correctly.\n"
"*** The reason for the problem is described in the\n"
"*** accompanying exception output.\n";
throw;
}
lease_mgr_ = &(LeaseMgrFactory::instance());
leases4.clear();
MultiThreadingMgr::instance().setMode(false);
now_ = time(0);
}
/// @brief Destructor.
~MySqlExtendedInfoTest() {
LeaseMgrFactory::destroy();
// If data wipe enabled, delete transient data otherwise destroy
// the schema.
destroyMySQLSchema();
leases4.clear();
MultiThreadingMgr::instance().setMode(false);
}
/// @brief Create and set v4 leases.
///
/// @param insert When true insert in the database.
void initLease4(bool insert = true) {
ASSERT_EQ(ADDRESS4.size(), DUIDS.size());
for (size_t i = 0; i < ADDRESS4.size(); ++i) {
Lease4Ptr lease;
vector<uint8_t> hwaddr_data(5, 0x08);
hwaddr_data.push_back(0x80 + i);
HWAddrPtr hwaddr(new HWAddr(hwaddr_data, HTYPE_ETHER));
vector<uint8_t> client_id = createFromString(DUIDS[i]);
IOAddress address(ADDRESS4[i]);
ASSERT_NO_THROW(lease.reset(new Lease4(address, hwaddr,
&client_id[0],
client_id.size(),
1000, now_,
static_cast<SubnetID>(i))));
leases4.push_back(lease);
if (insert) {
EXPECT_TRUE(lease_mgr_->addLease(lease));
}
}
ASSERT_EQ(ADDRESS4.size(), leases4.size());
}
/// @brief Create a vector of uint8_t from a string.
///
/// @param content A not empty string holding the content.
/// @return A vector of uint8_t with the given content.
inline vector<uint8_t> createFromString(const string& content) {
vector<uint8_t> v;
v.resize(content.size());
memmove(&v[0], &content[0], v.size());
return (v);
}
/// @brief Test initLease4.
void testInitLease4();
/// @brief Test getLease4ByRelayId.
void testGetLeases4ByRelayId();
/// @brief Test getLease4ByRemoteId.
void testGetLeases4ByRemoteId();
/// @brief Lease manager.
LeaseMgr* lease_mgr_;
/// @brief V4 leases.
Lease4Collection leases4;
/// @brief Current timestamp.
time_t now_;
};
/// @brief Verifies that the lease manager can add the v4 leases.
void
MySqlExtendedInfoTest::testInitLease4() {
initLease4();
EXPECT_EQ(8, leases4.size());
IOAddress zero = IOAddress::IPV4_ZERO_ADDRESS();
Lease4Collection got;
// Use the page version as it returns leases in order.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4(zero, LeasePageSize(100)));
ASSERT_EQ(leases4.size(), got.size());
for (size_t i = 0; i < leases4.size(); ++i) {
ConstElementPtr expected = leases4[i]->toElement();
LeasePtr lease = got[i];
ASSERT_TRUE(lease);
EXPECT_TRUE(expected->equals(*lease->toElement()))
<< "expected: " << expected->str() << "\n"
<< "got: " << lease->toElement()->str() << "\n";
}
}
TEST_F(MySqlExtendedInfoTest, initLease4) {
testInitLease4();
}
TEST_F(MySqlExtendedInfoTest, initLease4MultiThreading) {
MultiThreadingTest mt(true);
testInitLease4();
}
/// @brief Verifies that getLeases4ByRelayId works as expected.
void
MySqlExtendedInfoTest::testGetLeases4ByRelayId() {
// Lease manager is created with empty tables.
initLease4(false);
// Create leases.
IOAddress addr0(ADDRESS4[0]);
IOAddress addr1(ADDRESS4[1]);
IOAddress addr2(ADDRESS4[2]);
IOAddress addr3(ADDRESS4[3]);
IOAddress addr4(ADDRESS4[4]);
IOAddress zero = IOAddress::IPV4_ZERO_ADDRESS();
vector<uint8_t> relay_id0 = { 0xaa, 0xbb, 0xcc };
vector<uint8_t> relay_id1 = { 1, 2, 3, 4 };
vector<uint8_t> relay_id2 = createFromString(DUIDS[2]);
string user_context_txt0 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt0 += " \"sub-options\": \"0C03AABBCC\",";
user_context_txt0 += " \"relay-id\": \"AABBCC\" } } }";
ElementPtr user_context0;
ASSERT_NO_THROW(user_context0 = Element::fromJSON(user_context_txt0));
string user_context_txt1 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt1 += " \"sub-options\": \"0C0401020304\",";
user_context_txt1 += " \"relay-id\": \"01020304\" } } }";
ElementPtr user_context1;
ASSERT_NO_THROW(user_context1 = Element::fromJSON(user_context_txt1));
Lease4Ptr lease;
// lease0: addr0, id0, now.
lease = leases4[0];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
// lease1: addr1, id1, now.
lease = leases4[1];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id1;
lease->setContext(user_context1);
// lease2: addr2, id0, now - 500.
lease = leases4[2];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 500;
// lease3: addr3, id0, now - 800.
lease = leases4[3];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 800;
// lease4: addr4, id0, now - 100.
lease = leases4[4];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 100;
// Add leases.
for (size_t i = 0; i < leases4.size(); ++i) {
EXPECT_TRUE(lease_mgr_->addLease(leases4[i]));
}
Lease4Collection got;
// Unknown relay id #2: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id2,
zero,
LeasePageSize(100)));
EXPECT_EQ(0, got.size());
// Unknown relay id #2, now - 1000, now + 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id2,
zero,
LeasePageSize(100),
now_ - 1000,
now_ + 1000));
EXPECT_EQ(0, got.size());
// Relay id #0, now - 2000, now - 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
now_ - 2000,
now_ - 1000));
EXPECT_EQ(0, got.size());
// Relay id #0, now + 1000, now + 2000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
now_ + 1000,
now_ + 2000));
EXPECT_EQ(0, got.size());
// Relay id #0: 3 entries (0, 2, 3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100)));
ASSERT_EQ(4, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[3];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, partial: 2 entries (0, 2).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, partial from previous: 2 entries (3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr2,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, final partial: no entries.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr4,
LeasePageSize(2)));
EXPECT_EQ(0, got.size());
// Relay id #0, from now - 500: 3 entries (0, 2, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
now_ - 500));
ASSERT_EQ(3, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, to now - 200: 3 entries (2, 3).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
0, now_ - 200));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, from now - 500 to now - 100, partial: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, from now - 500 to now - 100, partial from 2: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr2,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, from now - 500 to now - 100, final partial.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr4,
LeasePageSize(1),
now_ - 500,
now_ - 100));
EXPECT_EQ(0, got.size());
}
TEST_F(MySqlExtendedInfoTest, getLeases4ByRelayId) {
testGetLeases4ByRelayId();
}
TEST_F(MySqlExtendedInfoTest, getLeases4ByRelayIdMultiThreading) {
MultiThreadingTest mt(true);
testGetLeases4ByRelayId();
}
/// @brief Verifies that getLeases4ByRemoteId works as expected.
void
MySqlExtendedInfoTest::testGetLeases4ByRemoteId() {
// Lease manager is created with empty tables.
initLease4(true);
// Update leases.
IOAddress addr0(ADDRESS4[0]);
IOAddress addr1(ADDRESS4[1]);
IOAddress addr2(ADDRESS4[2]);
IOAddress addr3(ADDRESS4[3]);
IOAddress addr4(ADDRESS4[4]);
IOAddress zero = IOAddress::IPV4_ZERO_ADDRESS();
vector<uint8_t> remote_id0 = { 1, 2, 3, 4 };
vector<uint8_t> remote_id1 = { 0xaa, 0xbb, 0xcc };
vector<uint8_t> remote_id2 = createFromString(DUIDS[2]);
string user_context_txt0 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt0 += " \"sub-options\": \"020401020304\",";
user_context_txt0 += " \"remote-id\": \"01020304\" } } }";
ElementPtr user_context0;
ASSERT_NO_THROW(user_context0 = Element::fromJSON(user_context_txt0));
string user_context_txt1 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt1 += " \"sub-options\": \"0203AABBCC\",";
user_context_txt1 += " \"remote-id\": \"AABBCC\" } } }";
ElementPtr user_context1;
ASSERT_NO_THROW(user_context1 = Element::fromJSON(user_context_txt1));
Lease4Ptr lease;
// lease0: addr0, id0, now.
lease = leases4[0];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
// lease1: addr1, id1, now.
lease = leases4[1];
lease->remote_id_ = remote_id1;
lease->setContext(user_context1);
// lease2: addr2, id0, now - 500.
lease = leases4[2];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 500;
// lease3: addr3, id0, now - 800.
lease = leases4[3];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 800;
// lease4: addr4, id0, now - 100.
lease = leases4[4];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 100;
// Update leases.
for (size_t i = 0; i < leases4.size(); ++i) {
EXPECT_NO_THROW(lease_mgr_->updateLease4(leases4[i]));
}
Lease4Collection got;
// Unknown remote id #2: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id2,
zero,
LeasePageSize(100)));
EXPECT_EQ(0, got.size());
// Unknown remote id #2, now - 1000, now + 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id2,
zero,
LeasePageSize(100),
now_ - 1000,
now_ + 1000));
EXPECT_EQ(0, got.size());
// Remote id #0, now - 2000, now - 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
now_ - 2000,
now_ - 1000));
EXPECT_EQ(0, got.size());
// Remote id #0, now + 1000, now + 2000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
now_ + 1000,
now_ + 2000));
EXPECT_EQ(0, got.size());
// Remote id #0: 3 entries (0, 2, 3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100)));
ASSERT_EQ(4, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[3];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, partial: 2 entries (0, 2).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, partial from previous: 2 entries (3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr2,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, final partial: no entries.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr4,
LeasePageSize(2)));
EXPECT_EQ(0, got.size());
// Remote id #0, from now - 500: 3 entries (0, 2, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
now_ - 500));
ASSERT_EQ(3, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, to now - 200: 3 entries (2, 3).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
0, now_ - 200));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, from now - 500 to now - 100, partial: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, from now - 500 to now - 100, partial from 2: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr2,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, from now - 500 to now - 100, final partial.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr4,
LeasePageSize(1),
now_ - 500,
now_ - 100));
EXPECT_EQ(0, got.size());
}
TEST_F(MySqlExtendedInfoTest, getLeases4ByRemoteId) {
testGetLeases4ByRemoteId();
}
TEST_F(MySqlExtendedInfoTest, getLeases4ByRemoteIdMultiThreading) {
MultiThreadingTest mt(true);
testGetLeases4ByRemoteId();
}
} // namespace

View File

@ -0,0 +1,617 @@
// Copyright (C) 2023 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 <asiolink/io_address.h>
#include <cc/data.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/pgsql_lease_mgr.h>
#include <pgsql/testutils/pgsql_schema.h>
#include <testutils/gtest_utils.h>
#include <testutils/multi_threading_utils.h>
#include <gtest/gtest.h>
using namespace isc;
using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::db;
using namespace isc::db::test;
using namespace isc::dhcp;
using namespace isc::test;
using namespace isc::util;
using namespace std;
namespace {
/// @brief IPv4 addresses used in the tests.
const vector<string> ADDRESS4 = {
"192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3",
"192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7"
};
/// @brief DUIDs used in the tests.
const vector<string> DUIDS = {
"wwwwwwww", "BBBBBBBB", "::::::::", "0123456789acdef",
"BBBBBBBB", "$$$$$$$$", "^^^^^^^^", "\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5"
};
/// @brief Test fixture class for extended info tests.
class PgSqlExtendedInfoTest : public ::testing::Test {
public:
/// @brief Constructor.
PgSqlExtendedInfoTest() {
// Ensure we have the proper schema with no transient data.
createPgSQLSchema();
// Connect to the database.
try {
LeaseMgrFactory::create(validPgSQLConnectionString());
} catch (...) {
std::cerr << "*** ERROR: unable to open database. The test\n"
"*** environment is broken and must be fixed before\n"
"*** the PostgreSQL tests will run correctly.\n"
"*** The reason for the problem is described in the\n"
"*** accompanying exception output.\n";
throw;
}
lease_mgr_ = &(LeaseMgrFactory::instance());
leases4.clear();
MultiThreadingMgr::instance().setMode(false);
now_ = time(0);
}
/// @brief Destructor.
~PgSqlExtendedInfoTest() {
LeaseMgrFactory::destroy();
// If data wipe enabled, delete transient data otherwise destroy
// the schema.
destroyPgSQLSchema();
leases4.clear();
MultiThreadingMgr::instance().setMode(false);
}
/// @brief Create and set v4 leases.
///
/// @param insert When true insert in the database.
void initLease4(bool insert = true) {
ASSERT_EQ(ADDRESS4.size(), DUIDS.size());
for (size_t i = 0; i < ADDRESS4.size(); ++i) {
Lease4Ptr lease;
vector<uint8_t> hwaddr_data(5, 0x08);
hwaddr_data.push_back(0x80 + i);
HWAddrPtr hwaddr(new HWAddr(hwaddr_data, HTYPE_ETHER));
vector<uint8_t> client_id = createFromString(DUIDS[i]);
IOAddress address(ADDRESS4[i]);
ASSERT_NO_THROW(lease.reset(new Lease4(address, hwaddr,
&client_id[0],
client_id.size(),
1000, now_,
static_cast<SubnetID>(i))));
leases4.push_back(lease);
if (insert) {
EXPECT_TRUE(lease_mgr_->addLease(lease));
}
}
ASSERT_EQ(ADDRESS4.size(), leases4.size());
}
/// @brief Create a vector of uint8_t from a string.
///
/// @param content A not empty string holding the content.
/// @return A vector of uint8_t with the given content.
inline vector<uint8_t> createFromString(const string& content) {
vector<uint8_t> v;
v.resize(content.size());
memmove(&v[0], &content[0], v.size());
return (v);
}
/// @brief Test initLease4.
void testInitLease4();
/// @brief Test getLease4ByRelayId.
void testGetLeases4ByRelayId();
/// @brief Test getLease4ByRemoteId.
void testGetLeases4ByRemoteId();
/// @brief Lease manager.
LeaseMgr* lease_mgr_;
/// @brief V4 leases.
Lease4Collection leases4;
/// @brief Current timestamp.
time_t now_;
};
/// @brief Verifies that the lease manager can add the v4 leases.
void
PgSqlExtendedInfoTest::testInitLease4() {
initLease4();
EXPECT_EQ(8, leases4.size());
IOAddress zero = IOAddress::IPV4_ZERO_ADDRESS();
Lease4Collection got;
// Use the page version as it returns leases in order.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4(zero, LeasePageSize(100)));
ASSERT_EQ(leases4.size(), got.size());
for (size_t i = 0; i < leases4.size(); ++i) {
ConstElementPtr expected = leases4[i]->toElement();
LeasePtr lease = got[i];
ASSERT_TRUE(lease);
EXPECT_TRUE(expected->equals(*lease->toElement()))
<< "expected: " << expected->str() << "\n"
<< "got: " << lease->toElement()->str() << "\n";
}
}
TEST_F(PgSqlExtendedInfoTest, initLease4) {
testInitLease4();
}
TEST_F(PgSqlExtendedInfoTest, initLease4MultiThreading) {
MultiThreadingTest mt(true);
testInitLease4();
}
/// @brief Verifies that getLeases4ByRelayId works as expected.
void
PgSqlExtendedInfoTest::testGetLeases4ByRelayId() {
// Lease manager is created with empty tables.
initLease4(false);
// Create leases.
IOAddress addr0(ADDRESS4[0]);
IOAddress addr1(ADDRESS4[1]);
IOAddress addr2(ADDRESS4[2]);
IOAddress addr3(ADDRESS4[3]);
IOAddress addr4(ADDRESS4[4]);
IOAddress zero = IOAddress::IPV4_ZERO_ADDRESS();
vector<uint8_t> relay_id0 = { 0xaa, 0xbb, 0xcc };
vector<uint8_t> relay_id1 = { 1, 2, 3, 4 };
vector<uint8_t> relay_id2 = createFromString(DUIDS[2]);
string user_context_txt0 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt0 += " \"sub-options\": \"0C03AABBCC\",";
user_context_txt0 += " \"relay-id\": \"AABBCC\" } } }";
ElementPtr user_context0;
ASSERT_NO_THROW(user_context0 = Element::fromJSON(user_context_txt0));
string user_context_txt1 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt1 += " \"sub-options\": \"0C0401020304\",";
user_context_txt1 += " \"relay-id\": \"01020304\" } } }";
ElementPtr user_context1;
ASSERT_NO_THROW(user_context1 = Element::fromJSON(user_context_txt1));
Lease4Ptr lease;
// lease0: addr0, id0, now.
lease = leases4[0];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
// lease1: addr1, id1, now.
lease = leases4[1];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id1;
lease->setContext(user_context1);
// lease2: addr2, id0, now - 500.
lease = leases4[2];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 500;
// lease3: addr3, id0, now - 800.
lease = leases4[3];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 800;
// lease4: addr4, id0, now - 100.
lease = leases4[4];
ASSERT_TRUE(lease);
lease->relay_id_ = relay_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 100;
// Add leases.
for (size_t i = 0; i < leases4.size(); ++i) {
EXPECT_TRUE(lease_mgr_->addLease(leases4[i]));
}
Lease4Collection got;
// Unknown relay id #2: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id2,
zero,
LeasePageSize(100)));
EXPECT_EQ(0, got.size());
// Unknown relay id #2, now - 1000, now + 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id2,
zero,
LeasePageSize(100),
now_ - 1000,
now_ + 1000));
EXPECT_EQ(0, got.size());
// Relay id #0, now - 2000, now - 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
now_ - 2000,
now_ - 1000));
EXPECT_EQ(0, got.size());
// Relay id #0, now + 1000, now + 2000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
now_ + 1000,
now_ + 2000));
EXPECT_EQ(0, got.size());
// Relay id #0: 3 entries (0, 2, 3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100)));
ASSERT_EQ(4, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[3];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, partial: 2 entries (0, 2).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, partial from previous: 2 entries (3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr2,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, final partial: no entries.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr4,
LeasePageSize(2)));
EXPECT_EQ(0, got.size());
// Relay id #0, from now - 500: 3 entries (0, 2, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
now_ - 500));
ASSERT_EQ(3, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, to now - 200: 3 entries (2, 3).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(100),
0, now_ - 200));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, from now - 500 to now - 100, partial: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
zero,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, from now - 500 to now - 100, partial from 2: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr2,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(relay_id0, lease->relay_id_);
// Relay id #0, from now - 500 to now - 100, final partial.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRelayId(relay_id0,
addr4,
LeasePageSize(1),
now_ - 500,
now_ - 100));
EXPECT_EQ(0, got.size());
}
TEST_F(PgSqlExtendedInfoTest, getLeases4ByRelayId) {
testGetLeases4ByRelayId();
}
TEST_F(PgSqlExtendedInfoTest, getLeases4ByRelayIdMultiThreading) {
MultiThreadingTest mt(true);
testGetLeases4ByRelayId();
}
/// @brief Verifies that getLeases4ByRemoteId works as expected.
void
PgSqlExtendedInfoTest::testGetLeases4ByRemoteId() {
// Lease manager is created with empty tables.
initLease4(true);
// Update leases.
IOAddress addr0(ADDRESS4[0]);
IOAddress addr1(ADDRESS4[1]);
IOAddress addr2(ADDRESS4[2]);
IOAddress addr3(ADDRESS4[3]);
IOAddress addr4(ADDRESS4[4]);
IOAddress zero = IOAddress::IPV4_ZERO_ADDRESS();
vector<uint8_t> remote_id0 = { 1, 2, 3, 4 };
vector<uint8_t> remote_id1 = { 0xaa, 0xbb, 0xcc };
vector<uint8_t> remote_id2 = createFromString(DUIDS[2]);
string user_context_txt0 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt0 += " \"sub-options\": \"020401020304\",";
user_context_txt0 += " \"remote-id\": \"01020304\" } } }";
ElementPtr user_context0;
ASSERT_NO_THROW(user_context0 = Element::fromJSON(user_context_txt0));
string user_context_txt1 = "{ \"ISC\": { \"relay-agent-info\": {";
user_context_txt1 += " \"sub-options\": \"0203AABBCC\",";
user_context_txt1 += " \"remote-id\": \"AABBCC\" } } }";
ElementPtr user_context1;
ASSERT_NO_THROW(user_context1 = Element::fromJSON(user_context_txt1));
Lease4Ptr lease;
// lease0: addr0, id0, now.
lease = leases4[0];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
// lease1: addr1, id1, now.
lease = leases4[1];
lease->remote_id_ = remote_id1;
lease->setContext(user_context1);
// lease2: addr2, id0, now - 500.
lease = leases4[2];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 500;
// lease3: addr3, id0, now - 800.
lease = leases4[3];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 800;
// lease4: addr4, id0, now - 100.
lease = leases4[4];
lease->remote_id_ = remote_id0;
lease->setContext(user_context0);
lease->cltt_ = now_ - 100;
// Update leases.
for (size_t i = 0; i < leases4.size(); ++i) {
EXPECT_NO_THROW(lease_mgr_->updateLease4(leases4[i]));
}
Lease4Collection got;
// Unknown remote id #2: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id2,
zero,
LeasePageSize(100)));
EXPECT_EQ(0, got.size());
// Unknown remote id #2, now - 1000, now + 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id2,
zero,
LeasePageSize(100),
now_ - 1000,
now_ + 1000));
EXPECT_EQ(0, got.size());
// Remote id #0, now - 2000, now - 1000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
now_ - 2000,
now_ - 1000));
EXPECT_EQ(0, got.size());
// Remote id #0, now + 1000, now + 2000: nothing.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
now_ + 1000,
now_ + 2000));
EXPECT_EQ(0, got.size());
// Remote id #0: 3 entries (0, 2, 3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100)));
ASSERT_EQ(4, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[3];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, partial: 2 entries (0, 2).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, partial from previous: 2 entries (3, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr2,
LeasePageSize(2)));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, final partial: no entries.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr4,
LeasePageSize(2)));
EXPECT_EQ(0, got.size());
// Remote id #0, from now - 500: 3 entries (0, 2, 4).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
now_ - 500));
ASSERT_EQ(3, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[0]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[2];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, to now - 200: 3 entries (2, 3).
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(100),
0, now_ - 200));
ASSERT_EQ(2, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
lease = got[1];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[3]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, from now - 500 to now - 100, partial: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
zero,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[2]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, from now - 500 to now - 100, partial from 2: 1 entry.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr2,
LeasePageSize(1),
now_ - 500,
now_ - 100));
ASSERT_EQ(1, got.size());
lease = got[0];
ASSERT_TRUE(lease);
EXPECT_EQ(*lease, *leases4[4]);
EXPECT_EQ(remote_id0, lease->remote_id_);
// Remote id #0, from now - 500 to now - 100, final partial.
EXPECT_NO_THROW(got = lease_mgr_->getLeases4ByRemoteId(remote_id0,
addr4,
LeasePageSize(1),
now_ - 500,
now_ - 100));
EXPECT_EQ(0, got.size());
}
TEST_F(PgSqlExtendedInfoTest, getLeases4ByRemoteId) {
testGetLeases4ByRemoteId();
}
TEST_F(PgSqlExtendedInfoTest, getLeases4ByRemoteIdMultiThreading) {
MultiThreadingTest mt(true);
testGetLeases4ByRemoteId();
}
} // namespace