Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
667de2ef
Commit
667de2ef
authored
Jan 14, 2015
by
Marcin Siodelski
Browse files
[master] Merge branch 'trac3671'
parents
f8b8d39b
a13e1e0d
Changes
12
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcpsrv/Makefile.am
View file @
667de2ef
...
...
@@ -82,11 +82,13 @@ libkea_dhcpsrv_la_SOURCES += host_container.h
libkea_dhcpsrv_la_SOURCES
+=
host_mgr.cc host_mgr.h
libkea_dhcpsrv_la_SOURCES
+=
key_from_key.h
libkea_dhcpsrv_la_SOURCES
+=
lease.cc lease.h
libkea_dhcpsrv_la_SOURCES
+=
lease_file_loader.h
libkea_dhcpsrv_la_SOURCES
+=
lease_mgr.cc lease_mgr.h
libkea_dhcpsrv_la_SOURCES
+=
lease_mgr_factory.cc lease_mgr_factory.h
libkea_dhcpsrv_la_SOURCES
+=
logging.cc logging.h
libkea_dhcpsrv_la_SOURCES
+=
logging_info.cc logging_info.h
libkea_dhcpsrv_la_SOURCES
+=
memfile_lease_mgr.cc memfile_lease_mgr.h
libkea_dhcpsrv_la_SOURCES
+=
memfile_lease_storage.h
if
HAVE_MYSQL
libkea_dhcpsrv_la_SOURCES
+=
mysql_lease_mgr.cc mysql_lease_mgr.h
...
...
src/lib/dhcpsrv/dhcpsrv_messages.mes
View file @
667de2ef
# Copyright (C) 2012-201
4
Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2012-201
5
Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
...
...
@@ -284,23 +284,13 @@ subnet ID and hardware address.
A debug message issued when the server is about to obtain schema version
information from the memory file database.
% DHCPSRV_MEMFILE_LEASE
S_RELOAD4 re
loading leases from %1
An info message issued when the server is about to start reading DHCP
v4
leases
% DHCPSRV_MEMFILE_LEASE
_FILE_LOAD
loading leases from
file
%1
An info message issued when the server is about to start reading DHCP leases
from the lease file. All leases currently held in the memory will be
replaced by those read from the file.
% DHCPSRV_MEMFILE_LEASES_RELOAD6 reloading leases from %1
An info message issued when the server is about to start reading DHCPv6 leases
from the lease file. All leases currently held in the memory will be
replaced by those read from the file.
% DHCPSRV_MEMFILE_LEASE_LOAD4 loading lease %1
A debug message issued when DHCPv4 lease is being loaded from the file to
memory.
% DHCPSRV_MEMFILE_LEASE_LOAD6 loading lease %1
A debug message issued when DHCPv6 lease is being loaded from the file to
memory.
% DHCPSRV_MEMFILE_LEASE_LOAD loading lease %1
A debug message issued when DHCP lease is being loaded from the file to memory.
% DHCPSRV_MEMFILE_NO_STORAGE running in non-persistent mode, leases will be lost after restart
A warning message issued when writes of leases to disk have been disabled
...
...
src/lib/dhcpsrv/lease_file_loader.h
0 → 100644
View file @
667de2ef
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef LEASE_FILE_LOADER_H
#define LEASE_FILE_LOADER_H
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/memfile_lease_storage.h>
#include <util/csv_file.h>
#include <boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
/// @brief Utility class to manage bulk of leases in the lease files.
///
/// This class exposes methods which allow for bulk loading leases from
/// the lease file and dumping the leases held in memory into the
/// lease file. There are two major use cases for this class:
/// - load leases by the DHCP server when the server starts up or
/// reloads configuration,
/// - an application performing a lease file cleanup rewrites the whole
/// lease file to remove the redundant lease entries.
///
/// In the former case, this class is used by the @c MemFile_LeaseMgr.
/// In the latter case, this class is used by the standalone application
/// which reads the whole lease file into memory (storage) and then
/// dumps the leases held in the storage to another file.
///
/// The methods in this class are templated so as they can be used both
/// with the @c Lease4Storage and @c Lease6Storage to process the DHCPv4
/// and DHCPv6 leases respectively.
///
/// @todo Add a method which dumps all leases from the storage to a
/// specified lease file.
class
LeaseFileLoader
{
public:
/// @brief Load leases from the lease file into the specified storage.
///
/// This method iterates over the entries in the lease file in the
/// CSV format, creates @c Lease4 or @c Lease6 objects and inserts
/// them into the storage to which reference is specified as an
/// argument. If there are multiple entries for the particular lease
/// in the lease file the entries further in the lease file override
/// the previous entries.
///
/// If the method finds the entry with the valid lifetime of 0 it
/// means that the particular lease was released and the method
/// removes an existing lease from the container.
///
/// @param lease_file A reference to the @c CSVLeaseFile4 or
/// @c CSVLeaseFile6 object representing the lease file. The file
/// doesn't need to be open because the method re-opens the file.
/// @param storage A reference to the container to which leases
/// should be inserted.
/// @param max_errors Maximum number of corrupted leases in the
/// lease file. The method will skip corrupted leases but after
/// exceeding the specified number of errors it will throw an
/// exception.
/// @param close_file_on_exit A boolean flag which indicates if
/// the file should be closed after it has been successfully parsed.
/// One case when the file is not opened is when the server starts
/// up, reads the leases in the file and then leaves the file open
/// for writing future lease updates.
/// @tparam LeaseObjectType A @c Lease4 or @c Lease6.
/// @tparam LeaseFileType A @c CSVLeaseFile4 or @c CSVLeaseFile6.
/// @tparam StorageType A @c Lease4Storage or @c Lease6Storage.
///
/// @throw isc::util::CSVFileError when the maximum number of errors
/// has been exceeded.
template
<
typename
LeaseObjectType
,
typename
LeaseFileType
,
typename
StorageType
>
static
void
load
(
LeaseFileType
&
lease_file
,
StorageType
&
storage
,
const
uint32_t
max_errors
=
0xFFFFFFFF
,
const
bool
close_file_on_exit
=
true
)
{
LOG_INFO
(
dhcpsrv_logger
,
DHCPSRV_MEMFILE_LEASE_FILE_LOAD
)
.
arg
(
lease_file
.
getFilename
());
// Reopen the file, as we don't know whether the file is open
// and we also don't know its current state.
lease_file
.
close
();
lease_file
.
open
();
boost
::
shared_ptr
<
LeaseObjectType
>
lease
;
// Track the number of corrupted leases.
uint32_t
errcnt
=
0
;
while
(
true
)
{
// Unable to parse the lease.
if
(
!
lease_file
.
next
(
lease
))
{
// A value of 0xFFFFFFFF indicates that we don't return
// until the whole file is parsed, even if errors occur.
// Otherwise, check if we have exceeded the maximum number
// of errors and throw an exception if we have.
if
(
++
errcnt
>
max_errors
)
{
// If we break parsing the CSV file because of too many
// errors, it doesn't make sense to keep the file open.
// This is because the caller wouldn't know where we
// stopped parsing and where the internal file pointer
// is. So, there are probably no cases when the caller
// would continue to use the open file.
lease_file
.
close
();
isc_throw
(
util
::
CSVFileError
,
"exceeded maximum number of"
" failures "
<<
max_errors
<<
" to read a lease"
" from the lease file "
<<
lease_file
.
getFilename
());
}
// Skip the corrupted lease.
continue
;
}
// Lease was found and we successfully parsed it.
if
(
lease
)
{
LOG_DEBUG
(
dhcpsrv_logger
,
DHCPSRV_DBG_TRACE_DETAIL_DATA
,
DHCPSRV_MEMFILE_LEASE_LOAD
)
.
arg
(
lease
->
toText
());
// Check if this lease exists.
typename
StorageType
::
iterator
lease_it
=
storage
.
find
(
lease
->
addr_
);
// The lease doesn't exist yet. Insert the lease if
// it has a positive valid lifetime.
if
(
lease_it
==
storage
.
end
())
{
if
(
lease
->
valid_lft_
>
0
)
{
storage
.
insert
(
lease
);
}
}
else
{
// The lease exists. If the new entry has a valid
// lifetime of 0 it is an indication to remove the
// existing entry. Otherwise, we update the lease.
if
(
lease
->
valid_lft_
==
0
)
{
storage
.
erase
(
lease_it
);
}
else
{
**
lease_it
=
*
lease
;
}
}
}
else
{
// Being here means that we hit the end of file.
break
;
}
}
if
(
close_file_on_exit
)
{
lease_file
.
close
();
}
}
};
}
}
#endif // LEASE_FILE_LOADER_H
src/lib/dhcpsrv/memfile_lease_mgr.cc
View file @
667de2ef
// Copyright (C) 2012-201
4
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-201
5
Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -14,10 +14,18 @@
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/lease_file_loader.h>
#include <dhcpsrv/memfile_lease_mgr.h>
#include <exceptions/exceptions.h>
#include <iostream>
#include <sstream>
namespace
{
/// @brief Maximum number of errors to read the leases from the lease file.
const
uint32_t
MAX_LEASE_ERRORS
=
100
;
}
// end of anonymous namespace
using
namespace
isc
::
dhcp
;
...
...
@@ -28,16 +36,14 @@ Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
if
(
universe
==
"4"
)
{
std
::
string
file4
=
initLeaseFilePath
(
V4
);
if
(
!
file4
.
empty
())
{
lease_file4_
.
reset
(
new
CSVLeaseFile4
(
file4
));
lease_file4_
->
open
();
load4
();
loadLeasesFromFiles
<
Lease4
,
CSVLeaseFile4
>
(
file4
,
lease_file4_
,
storage4_
);
}
}
else
{
std
::
string
file6
=
initLeaseFilePath
(
V6
);
if
(
!
file6
.
empty
())
{
lease_file6_
.
reset
(
new
CSVLeaseFile6
(
file6
));
lease_file6_
->
open
();
load6
();
loadLeasesFromFiles
<
Lease6
,
CSVLeaseFile6
>
(
file6
,
lease_file6_
,
storage6_
);
}
}
...
...
@@ -165,7 +171,7 @@ Lease4Collection
Memfile_LeaseMgr
::
getLease4
(
const
ClientId
&
client_id
)
const
{
LOG_DEBUG
(
dhcpsrv_logger
,
DHCPSRV_DBG_TRACE_DETAIL
,
DHCPSRV_MEMFILE_GET_CLIENTID
).
arg
(
client_id
.
toText
());
typedef
Memfile_LeaseMgr
::
Lease4Storage
::
nth_index
<
0
>::
type
SearchIndex
;
typedef
Lease4Storage
::
nth_index
<
0
>::
type
SearchIndex
;
Lease4Collection
collection
;
const
SearchIndex
&
idx
=
storage4_
.
get
<
0
>
();
for
(
SearchIndex
::
const_iterator
lease
=
idx
.
begin
();
...
...
@@ -468,127 +474,42 @@ Memfile_LeaseMgr::initLeaseFilePath(Universe u) {
return
(
lease_file
);
}
void
Memfile_LeaseMgr
::
load4
()
{
// If lease file hasn't been opened, we are working in non-persistent mode.
// That's fine, just leave.
if
(
!
persistLeases
(
V4
))
{
return
;
}
template
<
typename
LeaseObjectType
,
typename
LeaseFileType
,
typename
StorageType
>
void
Memfile_LeaseMgr
::
loadLeasesFromFiles
(
const
std
::
string
&
filename
,
boost
::
shared_ptr
<
LeaseFileType
>&
lease_file
,
StorageType
&
storage
)
{
storage
.
clear
();
LOG_INFO
(
dhcpsrv_logger
,
DHCPSRV_MEMFILE_LEASES_RELOAD4
)
.
arg
(
lease_file4_
->
getFilename
());
// Remove existing leases (if any). We will recreate them based on the
// data on disk.
storage4_
.
clear
();
Lease4Ptr
lease
;
do
{
/// @todo Currently we stop parsing on first failure. It is possible
/// that only one (or a few) leases are bad, so in theory we could
/// continue parsing but that would require some error counters to
/// prevent endless loops. That is enhancement for later time.
if
(
!
lease_file4_
->
next
(
lease
))
{
isc_throw
(
DbOperationError
,
"Failed to parse the DHCPv6 lease in"
" the lease file: "
<<
lease_file4_
->
getReadMsg
());
}
// If we got the lease, we update the internal container holding
// leases. Otherwise, we reached the end of file and we leave.
if
(
lease
)
{
LOG_DEBUG
(
dhcpsrv_logger
,
DHCPSRV_DBG_TRACE_DETAIL_DATA
,
DHCPSRV_MEMFILE_LEASE_LOAD4
)
.
arg
(
lease
->
toText
());
loadLease4
(
lease
);
}
}
while
(
lease
);
}
// Load the leasefile.completed, if exists.
lease_file
.
reset
(
new
LeaseFileType
(
std
::
string
(
filename
+
".completed"
)));
if
(
lease_file
->
exists
())
{
LeaseFileLoader
::
load
<
LeaseObjectType
>
(
*
lease_file
,
storage
,
MAX_LEASE_ERRORS
);
void
Memfile_LeaseMgr
::
loadLease4
(
Lease4Ptr
&
lease
)
{
// Check if the lease already exists.
Lease4Storage
::
iterator
lease_it
=
storage4_
.
find
(
lease
->
addr_
);
// Lease doesn't exist.
if
(
lease_it
==
storage4_
.
end
())
{
// Add the lease only if valid lifetime is greater than 0.
// We use valid lifetime of 0 to indicate that lease should
// be removed.
if
(
lease
->
valid_lft_
>
0
)
{
storage4_
.
insert
(
lease
);
}
}
else
{
// We use valid lifetime of 0 to indicate that the lease is
// to be removed. In such case, erase the lease.
if
(
lease
->
valid_lft_
==
0
)
{
storage4_
.
erase
(
lease_it
);
}
else
{
// Update existing lease.
**
lease_it
=
*
lease
;
// If the leasefile.completed doesn't exist, let's load the leases
// from leasefile.2 and leasefile.1, if they exist.
lease_file
.
reset
(
new
LeaseFileType
(
std
::
string
(
filename
+
".2"
)));
if
(
lease_file
->
exists
())
{
LeaseFileLoader
::
load
<
LeaseObjectType
>
(
*
lease_file
,
storage
,
MAX_LEASE_ERRORS
);
}
}
}
void
Memfile_LeaseMgr
::
load6
()
{
// If lease file hasn't been opened, we are working in non-persistent mode.
// That's fine, just leave.
if
(
!
persistLeases
(
V6
))
{
return
;
}
LOG_INFO
(
dhcpsrv_logger
,
DHCPSRV_MEMFILE_LEASES_RELOAD6
)
.
arg
(
lease_file6_
->
getFilename
());
// Remove existing leases (if any). We will recreate them based on the
// data on disk.
storage6_
.
clear
();
Lease6Ptr
lease
;
do
{
/// @todo Currently we stop parsing on first failure. It is possible
/// that only one (or a few) leases are bad, so in theory we could
/// continue parsing but that would require some error counters to
/// prevent endless loops. That is enhancement for later time.
if
(
!
lease_file6_
->
next
(
lease
))
{
isc_throw
(
DbOperationError
,
"Failed to parse the DHCPv6 lease in"
" the lease file: "
<<
lease_file6_
->
getReadMsg
());
}
// If we got the lease, we update the internal container holding
// leases. Otherwise, we reached the end of file and we leave.
if
(
lease
)
{
LOG_DEBUG
(
dhcpsrv_logger
,
DHCPSRV_DBG_TRACE_DETAIL_DATA
,
DHCPSRV_MEMFILE_LEASE_LOAD6
)
.
arg
(
lease
->
toText
());
loadLease6
(
lease
);
}
}
while
(
lease
);
}
void
Memfile_LeaseMgr
::
loadLease6
(
Lease6Ptr
&
lease
)
{
// Check if the lease already exists.
Lease6Storage
::
iterator
lease_it
=
storage6_
.
find
(
lease
->
addr_
);
// Lease doesn't exist.
if
(
lease_it
==
storage6_
.
end
())
{
// Add the lease only if valid lifetime is greater than 0.
// We use valid lifetime of 0 to indicate that lease should
// be removed.
if
(
lease
->
valid_lft_
>
0
)
{
storage6_
.
insert
(
lease
);
}
}
else
{
// We use valid lifetime of 0 to indicate that the lease is
// to be removed. In such case, erase the lease.
if
(
lease
->
valid_lft_
==
0
)
{
storage6_
.
erase
(
lease_it
);
}
else
{
// Update existing lease.
**
lease_it
=
*
lease
;
lease_file
.
reset
(
new
LeaseFileType
(
std
::
string
(
filename
+
".1"
)));
if
(
lease_file
->
exists
())
{
LeaseFileLoader
::
load
<
LeaseObjectType
>
(
*
lease_file
,
storage
,
MAX_LEASE_ERRORS
);
}
}
// Always load leases from the primary lease file. If the lease file
// doesn't exist it will be created by the LeaseFileLoader. Note
// that the false value passed as the last parameter to load
// function causes the function to leave the file open after
// it is parsed. This file will be used by the backend to record
// future lease updates.
lease_file
.
reset
(
new
LeaseFileType
(
filename
));
LeaseFileLoader
::
load
<
LeaseObjectType
>
(
*
lease_file
,
storage
,
MAX_LEASE_ERRORS
,
false
);;
}
src/lib/dhcpsrv/memfile_lease_mgr.h
View file @
667de2ef
// Copyright (C) 2012-201
4
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-201
5
Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -18,13 +18,10 @@
#include <dhcp/hwaddr.h>
#include <dhcpsrv/csv_lease_file4.h>
#include <dhcpsrv/csv_lease_file6.h>
#include <dhcpsrv/memfile_lease_storage.h>
#include <dhcpsrv/lease_mgr.h>
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/shared_ptr.hpp>
namespace
isc
{
namespace
dhcp
{
...
...
@@ -333,51 +330,7 @@ public:
/// server shut down.
bool
persistLeases
(
Universe
u
)
const
;
protected:
/// @brief Load all DHCPv4 leases from the file.
///
/// This method loads all DHCPv4 leases from a file to memory. It removes
/// existing leases before reading a file.
///
/// @throw isc::DbOperationError If failed to read a lease from the lease
/// file.
void
load4
();
/// @brief Loads a single DHCPv4 lease from the file.
///
/// This method reads a single lease record from the lease file. If the
/// corresponding record doesn't exist in the in-memory container, the
/// lease is added to the container (except for a lease which valid lifetime
/// is 0). If the corresponding lease exists, the lease being read updates
/// the existing lease. If the lease being read from the lease file has
/// valid lifetime of 0 and the corresponding lease exists in the in-memory
/// database, the existing lease is removed.
///
/// @param lease Pointer to the lease read from the lease file.
void
loadLease4
(
Lease4Ptr
&
lease
);
/// @brief Load all DHCPv6 leases from the file.
///
/// This method loads all DHCPv6 leases from a file to memory. It removes
/// existing leases before reading a file.
///
/// @throw isc::DbOperationError If failed to read a lease from the lease
/// file.
void
load6
();
/// @brief Loads a single DHCPv6 lease from the file.
///
/// This method reads a single lease record from the lease file. If the
/// corresponding record doesn't exist in the in-memory container, the
/// lease is added to the container (except for a lease which valid lifetime
/// is 0). If the corresponding lease exists, the lease being read updates
/// the existing lease. If the lease being read from the lease file has
/// valid lifetime of 0 and the corresponding lease exists in the in-memory
/// database, the existing lease is removed.
///
/// @param lease Pointer to the lease read from the lease file.
void
loadLease6
(
Lease6Ptr
&
lease
);
private:
/// @brief Initialize the location of the lease file.
///
...
...
@@ -396,111 +349,45 @@ protected:
/// argument to this function.
std
::
string
initLeaseFilePath
(
Universe
u
);
// This is a multi-index container, which holds elements that can
// be accessed using different search indexes.
typedef
boost
::
multi_index_container
<
// It holds pointers to Lease6 objects.
Lease6Ptr
,
boost
::
multi_index
::
indexed_by
<
// Specification of the first index starts here.
// This index sorts leases by IPv6 addresses represented as
// IOAddress objects.
boost
::
multi_index
::
ordered_unique
<
boost
::
multi_index
::
member
<
Lease
,
isc
::
asiolink
::
IOAddress
,
&
Lease
::
addr_
>
>
,
// Specification of the second index starts here.
boost
::
multi_index
::
ordered_non_unique
<
// This is a composite index that will be used to search for
// the lease using three attributes: DUID, IAID and lease type.
boost
::
multi_index
::
composite_key
<
Lease6
,
// The DUID can be retrieved from the Lease6 object using
// a getDuidVector const function.
boost
::
multi_index
::
const_mem_fun
<
Lease6
,
const
std
::
vector
<
uint8_t
>&
,
&
Lease6
::
getDuidVector
>
,
// The two other ingredients of this index are IAID and
// lease type.
boost
::
multi_index
::
member
<
Lease6
,
uint32_t
,
&
Lease6
::
iaid_
>
,
boost
::
multi_index
::
member
<
Lease6
,
Lease
::
Type
,
&
Lease6
::
type_
>
>
>
>
>
Lease6Storage
;
// Specify the type name of this container.
// This is a multi-index container, which holds elements that can
// be accessed using different search indexes.
typedef
boost
::
multi_index_container
<
// It holds pointers to Lease4 objects.
Lease4Ptr
,
// Specification of search indexes starts here.
boost
::
multi_index
::
indexed_by
<
// Specification of the first index starts here.
// This index sorts leases by IPv4 addresses represented as
// IOAddress objects.
boost
::
multi_index
::
ordered_unique
<
// The IPv4 address are held in addr_ members that belong to
// Lease class.
boost
::
multi_index
::
member
<
Lease
,
isc
::
asiolink
::
IOAddress
,
&
Lease
::
addr_
>
>
,
// Specification of the second index starts here.
boost
::
multi_index
::
ordered_unique
<
// This is a composite index that combines two attributes of the
// Lease4 object: hardware address and subnet id.
boost
::
multi_index
::
composite_key
<
Lease4
,
// The hardware address is held in the hwaddr_ member of the
// Lease4 object, which is a HWAddr object. Boost does not
// provide a key extractor for getting a member of a member,
// so we need a simple method for that.
boost
::
multi_index
::
const_mem_fun
<
Lease
,
const
std
::
vector
<
uint8_t
>&
,
&
Lease
::
getHWAddrVector
>
,
// The subnet id is held in the subnet_id_ member of Lease4
// class. Note that the subnet_id_ is defined in the base
// class (Lease) so we have to point to this class rather
// than derived class: Lease4.
boost
::
multi_index
::
member
<
Lease
,
SubnetID
,
&
Lease
::
subnet_id_
>
>
>
,
// Specification of the third index starts here.
boost
::
multi_index
::
ordered_non_unique
<
// This is a composite index that uses two values to search for a
// lease: client id and subnet id.
boost
::
multi_index
::
composite_key
<
Lease4
,
// The client id can be retrieved from the Lease4 object by
// calling getClientIdVector const function.
boost
::
multi_index
::
const_mem_fun
<
Lease4
,
const
std
::
vector
<
uint8_t
>&
,
&
Lease4
::
getClientIdVector
>
,
// The subnet id is accessed through the subnet_id_ member.
boost
::
multi_index
::
member
<
Lease
,
uint32_t
,
&
Lease
::
subnet_id_
>
>
>
,
// Specification of the fourth index starts here.
boost
::
multi_index
::
ordered_non_unique
<
// This is a composite index that uses two values to search for a
// lease: client id and subnet id.
boost
::
multi_index
::
composite_key
<
Lease4
,
// The client id can be retrieved from the Lease4 object by
// calling getClientIdVector const function.
boost
::
multi_index
::
const_mem_fun
<
Lease4
,
const
std
::
vector
<
uint8_t
>&
,
&
Lease4
::
getClientIdVector
>
,
// The hardware address is held in the hwaddr_ object. We can
// access the raw data using lease->hwaddr_->hwaddr_, but Boost
// doesn't seem to provide a way to use member of a member for this,
// so we need a simple key extractor method (getRawHWAddr).
boost
::
multi_index
::
const_mem_fun
<
Lease
,
const
std
::
vector
<
uint8_t
>&
,
&
Lease
::
getHWAddrVector
>
,
// The subnet id is accessed through the subnet_id_ member.
boost
::
multi_index
::
member
<
Lease
,
SubnetID
,
&
Lease
::
subnet_id_
>
>
>
>
>
Lease4Storage
;
// Specify the type name for this container.
/// @brief Load leases from the persistent storage.
///
/// This method loads DHCPv4 or DHCPv6 leases from lease files in the
/// following order:
/// - If the <filename>.completed doesn't exist:
/// - leases from the <filename>.2