Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Kea
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
446
Issues
446
List
Boards
Labels
Service Desk
Milestones
Merge Requests
71
Merge Requests
71
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
Kea
Commits
af71689e
Commit
af71689e
authored
Nov 21, 2012
by
Stephen Morris
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2404] Add getLease4(const IOAddress&, SubnetId)
Add ability to select IPv4 leases by address and Subnet ID.
parent
61071513
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
145 additions
and
58 deletions
+145
-58
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.cc
+60
-39
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
+85
-19
No files found.
src/lib/dhcpsrv/mysql_lease_mgr.cc
View file @
af71689e
...
...
@@ -110,8 +110,6 @@ TaggedStatement tagged_statements[] = {
namespace
isc
{
namespace
dhcp
{
/// @brief Exchange MySQL and Lease4 Data
///
/// On any MySQL operation, arrays of MYSQL_BIND structures must be built to
...
...
@@ -306,9 +304,9 @@ private:
MYSQL_TIME
expire_
;
///< Lease expiry time
const
my_bool
false_
;
///< "false" for MySql
Lease4Ptr
lease_
;
///< Pointer to lease object
uint32_t
valid_lifetime_
;
///< Lease time
uint32_t
subnet_id_
;
///< Subnet identification
const
my_bool
true_
;
///< "true_" for MySql
uint32_t
valid_lifetime_
;
///< Lease time
};
...
...
@@ -598,12 +596,12 @@ private:
const
my_bool
false_
;
///< "false" for MySql
uint32_t
iaid_
;
///< Identity association ID
Lease6Ptr
lease_
;
///< Pointer to lease object
uint32_t
valid_lifetime_
;
///< Lease time
uint8_t
lease_type_
;
///< Lease type
uint8_t
prefixlen_
;
///< Prefix length
uint32_t
pref_lifetime_
;
///< Preferred lifetime
uint32_t
subnet_id_
;
///< Subnet identification
const
my_bool
true_
;
///< "true_" for MySql
uint32_t
valid_lifetime_
;
///< Lease time
};
...
...
@@ -611,7 +609,7 @@ private:
///
/// When a MySQL statement is exected, to fetch the results the function
/// mysql_stmt_fetch() must be called. As well as getting data, this
/// allocate
d
internal state. Subsequent calls to mysql_stmt_fetch
/// allocate
s
internal state. Subsequent calls to mysql_stmt_fetch
/// can be made, but when all the data is retrieved, mysql_stmt_free_result
/// must be called to free up the resources allocated.
///
...
...
@@ -648,7 +646,7 @@ private:
};
// MySqlLeaseMgr
Methods
// MySqlLeaseMgr
Constructor and Destructor
MySqlLeaseMgr
::
MySqlLeaseMgr
(
const
LeaseMgr
::
ParameterMap
&
parameters
)
:
LeaseMgr
(
parameters
),
mysql_
(
NULL
)
{
...
...
@@ -751,6 +749,9 @@ MySqlLeaseMgr::convertFromDatabaseTime(const MYSQL_TIME& expire,
}
// Database acess method
void
MySqlLeaseMgr
::
openDatabase
()
{
...
...
@@ -812,7 +813,7 @@ MySqlLeaseMgr::openDatabase() {
// changed and so the "affected rows" (retrievable from MySQL) is zero.
// This makes it hard to distinguish whether the UPDATE changed no rows
// because no row matching the WHERE clause was found, or because a
// row was found b
y
no data was altered.
// row was found b
ut
no data was altered.
MYSQL
*
status
=
mysql_real_connect
(
mysql_
,
host
,
user
,
password
,
name
,
0
,
NULL
,
CLIENT_FOUND_ROWS
);
if
(
status
!=
mysql_
)
{
...
...
@@ -820,6 +821,12 @@ MySqlLeaseMgr::openDatabase() {
}
}
// Prepared statement setup. The textual form of the SQL statement is stored
// in a vector of strings (text_statements_) and is used in the output of
// error messages. The SQL statement is also compiled into a "prepared
// statement" (stored in statements_), which avoids the overhead of compilation
// during use. As these allocate resources, the class destructor explicitly
// destroys the prepared statements.
void
MySqlLeaseMgr
::
prepareStatement
(
StatementIndex
index
,
const
char
*
text
)
{
...
...
@@ -865,7 +872,7 @@ MySqlLeaseMgr::prepareStatements() {
}
//
Common add lease cod
e
//
Add leases to the databas
e
bool
MySqlLeaseMgr
::
addLease
(
StatementIndex
stindex
,
std
::
vector
<
MYSQL_BIND
>&
bind
)
{
...
...
@@ -909,6 +916,36 @@ MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
return
(
addLease
(
INSERT_LEASE6
,
bind
));
}
// A convenience function used in the various getLease() methods. It binds
// the selection parameters to the prepared statement, and binds the variables
// that will receive the data. These are stored in the MySqlLease6Exchange
// object associated with the lease manager and converted to a Lease6 object
// when retrieved.
template
<
typename
Exchange
>
void
MySqlLeaseMgr
::
bindAndExecute
(
StatementIndex
stindex
,
Exchange
&
exchange
,
MYSQL_BIND
*
inbind
)
const
{
// Bind the input parameters to the statement
int
status
=
mysql_stmt_bind_param
(
statements_
[
stindex
],
inbind
);
checkError
(
status
,
stindex
,
"unable to bind WHERE clause parameter"
);
// Set up the SELECT clause
std
::
vector
<
MYSQL_BIND
>
outbind
=
exchange
->
createBindForReceive
();
// Bind the output parameters to the statement
status
=
mysql_stmt_bind_result
(
statements_
[
stindex
],
&
outbind
[
0
]);
checkError
(
status
,
stindex
,
"unable to bind SELECT caluse parameters"
);
// Execute the statement
status
=
mysql_stmt_execute
(
statements_
[
stindex
]);
checkError
(
status
,
stindex
,
"unable to execute"
);
}
// Extraction of leases from the database. Much the code has common logic
// with the difference between V4 and V6 being the data types of the
// objects involved. For this reason, the common logic is inside a
// template method.
template
<
typename
Exchange
,
typename
LeasePtr
>
void
MySqlLeaseMgr
::
getLease
(
StatementIndex
stindex
,
MYSQL_BIND
*
inbind
,
...
...
@@ -918,7 +955,7 @@ void MySqlLeaseMgr::getLease(StatementIndex stindex, MYSQL_BIND* inbind,
// to fields in the exchange object, then execute the prepared statement.
bindAndExecute
(
stindex
,
exchange
,
inbind
);
// Fetch the data and set up the "
release
" object to release associated
// Fetch the data and set up the "
free result
" object to release associated
// resources when this method exits.
MySqlFreeResult
fetch_release
(
statements_
[
stindex
]);
int
status
=
mysql_stmt_fetch
(
statements_
[
stindex
]);
...
...
@@ -967,11 +1004,20 @@ MySqlLeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
Lease4Ptr
MySqlLeaseMgr
::
getLease4
(
const
isc
::
asiolink
::
IOAddress
&
/* addr */
,
SubnetID
/* subnet_id */
)
const
{
isc_throw
(
NotImplemented
,
"MySqlLeaseMgr::getLease4(const IOAddress&, SubnetID) "
"not implemented yet"
);
return
(
Lease4Ptr
());
MySqlLeaseMgr
::
getLease4
(
const
isc
::
asiolink
::
IOAddress
&
addr
,
SubnetID
subnet_id
)
const
{
// As the address is the unique primary key of the lease4 table, there can
// only be one lease with a given address. Therefore we will get that
// lease and do the filtering on subnet ID here.
Lease4Ptr
result
=
getLease4
(
addr
);
if
(
result
&&
(
result
->
subnet_id_
!=
subnet_id
))
{
// Lease found but IDs do not match. Return null pointer
result
.
reset
();
}
return
(
result
);
}
...
...
@@ -1009,31 +1055,6 @@ MySqlLeaseMgr::getLease4(const ClientId& /* clientid */,
}
// A convenience function used in the various getLease() methods. It binds
// the selection parameters to the prepared statement, and binds the variables
// that will receive the data. These are stored in the MySqlLease6Exchange
// object associated with the lease manager and converted to a Lease6 object
// when retrieved.
template
<
typename
Exchange
>
void
MySqlLeaseMgr
::
bindAndExecute
(
StatementIndex
stindex
,
Exchange
&
exchange
,
MYSQL_BIND
*
inbind
)
const
{
// Bind the input parameters to the statement
int
status
=
mysql_stmt_bind_param
(
statements_
[
stindex
],
inbind
);
checkError
(
status
,
stindex
,
"unable to bind WHERE clause parameter"
);
// Set up the SELECT clause
std
::
vector
<
MYSQL_BIND
>
outbind
=
exchange
->
createBindForReceive
();
// Bind the output parameters to the statement
status
=
mysql_stmt_bind_result
(
statements_
[
stindex
],
&
outbind
[
0
]);
checkError
(
status
,
stindex
,
"unable to bind SELECT caluse parameters"
);
// Execute the statement
status
=
mysql_stmt_execute
(
statements_
[
stindex
]);
checkError
(
status
,
stindex
,
"unable to execute"
);
}
Lease6Ptr
...
...
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
View file @
af71689e
...
...
@@ -477,13 +477,13 @@ public:
// Check they were created
for
(
int
i
=
0
;
i
<
leases
.
size
();
++
i
)
{
EXPEC
T_TRUE
(
leases
[
i
]);
ASSER
T_TRUE
(
leases
[
i
]);
}
// Check they are different
for
(
int
i
=
0
;
i
<
(
leases
.
size
()
-
1
);
++
i
)
{
for
(
int
j
=
(
i
+
1
);
j
<
leases
.
size
();
++
j
)
{
EXPEC
T_TRUE
(
leases
[
i
]
!=
leases
[
j
]);
ASSER
T_TRUE
(
leases
[
i
]
!=
leases
[
j
]);
}
}
}
...
...
@@ -731,15 +731,15 @@ TEST_F(MySqlLeaseMgrTest, basicLease4) {
reopen
();
Lease4Ptr
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
1
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
2
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
2
],
l_returned
);
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
3
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
3
],
l_returned
);
// Check that we can't add a second lease with the same address
...
...
@@ -754,7 +754,7 @@ TEST_F(MySqlLeaseMgrTest, basicLease4) {
// Check that the second address is still there.
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
2
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
2
],
l_returned
);
}
...
...
@@ -782,15 +782,15 @@ TEST_F(MySqlLeaseMgrTest, basicLease6) {
reopen
();
Lease6Ptr
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
1
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
2
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
2
],
l_returned
);
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
3
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
3
],
l_returned
);
// Check that we can't add a second lease with the same address
...
...
@@ -805,18 +805,84 @@ TEST_F(MySqlLeaseMgrTest, basicLease6) {
// Check that the second address is still there.
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
2
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
2
],
l_returned
);
}
// @brief Check GetLease4 methods - Access by Address and SubnetID
//
// Adds leases to the database and checks that they can be accessed via
// a combination of Address, SubnetID
TEST_F
(
MySqlLeaseMgrTest
,
getLease4AddressSubnetId
)
{
// Get the leases to be used for the test.
vector
<
Lease4Ptr
>
leases
=
createLeases4
();
// Add just one to the database.
EXPECT_TRUE
(
lmptr_
->
addLease
(
leases
[
1
]));
// Look for a known lease with a valid Subnet ID
Lease4Ptr
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
1
],
73
);
ASSERT_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
// Look for a lease known to be in the database with an invalid Subnet ID
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
1
],
74
);
EXPECT_FALSE
(
l_returned
);
// Look for a lease known not to be in the database with a valid Subnet ID
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
2
],
73
);
EXPECT_FALSE
(
l_returned
);
// Look for a lease known not to be in the database with and invalid
l_returned
=
lmptr_
->
getLease4
(
ioaddress4_
[
2
],
74
);
EXPECT_FALSE
(
l_returned
);
}
// @brief Check GetLease4 methods - Access by Hardware Address
//
// Adds leases to the database and checks that they can be accessed via
// hardware address
TEST_F
(
MySqlLeaseMgrTest
,
getLease4AddressHwaddr
)
{
FAIL
()
<<
"Test not complete"
;
/*
// Get the leases to be used for the test and add to the database.
vector<Lease4Ptr> leases = createLeases4();
for (int i = 0; i < leases.size(); ++i) {
EXPECT_TRUE(lmptr_->addLease(leases[i]));
}
// Get a known hardware address
vector<uint8_t> hwaddr = leases[1]->hwaddr_;
EXPECT_FALSE(hwaddr.empty());
// Look for a lease with a valid hardware address
Lease4Ptr l_returned = lmptr_->getLease4(hwaddr);
ASSERT_TRUE(l_returned);
detailCompareLease(leases[1], l_returned);
// Look for a lease with an invalid valid hardware address
hwaddr[0] += 1;
Lease4Ptr l_returned = lmptr_->getLease4(hwaddr);
EXPECT_FALSE(l_returned);
// Check it handles an empty hardware address
hwaddr.clear();
Lease4Ptr l_returned = lmptr_->getLease4(hwaddr);
EXPECT_FALSE(l_returned);
// Add a lease with an empty hardware address to the database and
// check that it find that.
*/
}
// @brief Check GetLease6 methods - Access by DUID/IAID
//
// Adds leases to the database and checks that they can be accessed via
// a combination of DIUID and IAID.
TEST_F
(
MySqlLeaseMgrTest
,
getLease6
Extended1
)
{
TEST_F
(
MySqlLeaseMgrTest
,
getLease6
DuidIaid
)
{
// Get the leases to be used for the test.
vector
<
Lease6Ptr
>
leases
=
createLeases6
();
EXPEC
T_LE
(
6
,
leases
.
size
());
// Expect to access leases 0 through 5
ASSER
T_LE
(
6
,
leases
.
size
());
// Expect to access leases 0 through 5
// Add them to the database
for
(
int
i
=
0
;
i
<
leases
.
size
();
++
i
)
{
...
...
@@ -860,10 +926,10 @@ TEST_F(MySqlLeaseMgrTest, getLease6Extended1) {
//
// Adds leases to the database and checks that they can be accessed via
// a combination of DIUID and IAID.
TEST_F
(
MySqlLeaseMgrTest
,
getLease6
Extended2
)
{
TEST_F
(
MySqlLeaseMgrTest
,
getLease6
DuidIaidSubnetId
)
{
// Get the leases to be used for the test.
vector
<
Lease6Ptr
>
leases
=
createLeases6
();
EXPEC
T_LE
(
6
,
leases
.
size
());
// Expect to access leases 0 through 5
ASSER
T_LE
(
6
,
leases
.
size
());
// Expect to access leases 0 through 5
// Add them to the database
for
(
int
i
=
0
;
i
<
leases
.
size
();
++
i
)
{
...
...
@@ -904,7 +970,7 @@ TEST_F(MySqlLeaseMgrTest, getLease6Extended2) {
TEST_F
(
MySqlLeaseMgrTest
,
updateLease6
)
{
// Get the leases to be used for the test.
vector
<
Lease6Ptr
>
leases
=
createLeases6
();
EXPECT_LE
(
3
,
leases
.
size
());
// Expect to access leases 0 through 5
ASSERT_LE
(
3
,
leases
.
size
());
// Expect to access leases 0 through 2
// Add a lease to the database and check that the lease is there.
EXPECT_TRUE
(
lmptr_
->
addLease
(
leases
[
1
]));
...
...
@@ -912,7 +978,7 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
reopen
();
Lease6Ptr
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
1
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
// Modify some fields in lease 1 (not the address) and update it.
...
...
@@ -926,7 +992,7 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
// ... and check what is returned is what is expected.
l_returned
.
reset
();
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
1
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
// Alter the lease again and check.
...
...
@@ -938,14 +1004,14 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
l_returned
.
reset
();
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
1
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
// Check we can do an update without changing data.
lmptr_
->
updateLease6
(
leases
[
1
]);
l_returned
.
reset
();
l_returned
=
lmptr_
->
getLease6
(
ioaddress6_
[
1
]);
EXPEC
T_TRUE
(
l_returned
);
ASSER
T_TRUE
(
l_returned
);
detailCompareLease
(
leases
[
1
],
l_returned
);
// Try updating a lease not in the database.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment