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
450
Issues
450
List
Boards
Labels
Service Desk
Milestones
Merge Requests
75
Merge Requests
75
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
32e13fbf
Commit
32e13fbf
authored
Dec 28, 2012
by
Tomek Mrugalski
🛰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2320] Allocation Engine for IPv4 implemented
parent
92e4f34d
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
724 additions
and
46 deletions
+724
-46
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/alloc_engine.cc
+189
-0
src/lib/dhcpsrv/alloc_engine.h
src/lib/dhcpsrv/alloc_engine.h
+11
-4
src/lib/dhcpsrv/lease_mgr.h
src/lib/dhcpsrv/lease_mgr.h
+4
-3
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.cc
+49
-12
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/memfile_lease_mgr.h
+16
-0
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.cc
+2
-1
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
+440
-18
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
+5
-0
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
+3
-3
tests/tools/perfdhcp/test_control.cc
tests/tools/perfdhcp/test_control.cc
+5
-5
No files found.
src/lib/dhcpsrv/alloc_engine.cc
View file @
32e13fbf
...
...
@@ -260,6 +260,114 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
<<
" tries"
);
}
Lease4Ptr
AllocEngine
::
allocateAddress4
(
const
SubnetPtr
&
subnet
,
const
ClientIdPtr
&
clientid
,
const
HWAddrPtr
&
hwaddr
,
const
IOAddress
&
hint
,
bool
fake_allocation
/* = false */
)
{
// That check is not necessary. We create allocator in AllocEngine
// constructor
if
(
!
allocator_
)
{
isc_throw
(
InvalidOperation
,
"No allocator selected"
);
}
// check if there's existing lease for that subnet/clientid/hwaddr combination.
Lease4Ptr
existing
=
LeaseMgrFactory
::
instance
().
getLease4
(
hwaddr
->
hwaddr_
,
subnet
->
getID
());
if
(
existing
)
{
// we have a lease already. This is a returning client, probably after
// his reboot.
return
(
existing
);
}
existing
=
LeaseMgrFactory
::
instance
().
getLease4
(
*
clientid
,
subnet
->
getID
());
if
(
existing
)
{
// we have a lease already. This is a returning client, probably after
// his reboot.
// @todo: produce a warning. We haven't found him using MAC address, but
// we found him using client-id
return
(
existing
);
}
// check if the hint is in pool and is available
if
(
subnet
->
inPool
(
hint
))
{
existing
=
LeaseMgrFactory
::
instance
().
getLease4
(
hint
);
if
(
!
existing
)
{
/// @todo: check if the hint is reserved once we have host support
/// implemented
// the hint is valid and not currently used, let's create a lease for it
Lease4Ptr
lease
=
createLease4
(
subnet
,
clientid
,
hwaddr
,
hint
,
fake_allocation
);
// It can happen that the lease allocation failed (we could have lost
// the race condition. That means that the hint is lo longer usable and
// we need to continue the regular allocation path.
if
(
lease
)
{
return
(
lease
);
}
}
else
{
if
(
existing
->
expired
())
{
return
(
reuseExpiredLease
(
existing
,
subnet
,
clientid
,
hwaddr
,
fake_allocation
));
}
}
}
// Hint is in the pool but is not available. Search the pool until first of
// the following occurs:
// - we find a free address
// - we find an address for which the lease has expired
// - we exhaust number of tries
//
// @todo: Current code does not handle pool exhaustion well. It will be
// improved. Current problems:
// 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
// 10 addresses), we will iterate over it 100 times before giving up
// 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
// 3. the whole concept of infinite attempts is just asking for infinite loop
// We may consider some form or reference counting (this pool has X addresses
// left), but this has one major problem. We exactly control allocation
// moment, but we currently do not control expiration time at all
unsigned
int
i
=
attempts_
;
do
{
IOAddress
candidate
=
allocator_
->
pickAddress
(
subnet
,
clientid
,
hint
);
/// @todo: check if the address is reserved once we have host support
/// implemented
Lease4Ptr
existing
=
LeaseMgrFactory
::
instance
().
getLease4
(
candidate
);
if
(
!
existing
)
{
// there's no existing lease for selected candidate, so it is
// free. Let's allocate it.
Lease4Ptr
lease
=
createLease4
(
subnet
,
clientid
,
hwaddr
,
candidate
,
fake_allocation
);
if
(
lease
)
{
return
(
lease
);
}
// Although the address was free just microseconds ago, it may have
// been taken just now. If the lease insertion fails, we continue
// allocation attempts.
}
else
{
if
(
existing
->
expired
())
{
return
(
reuseExpiredLease
(
existing
,
subnet
,
clientid
,
hwaddr
,
fake_allocation
));
}
}
// continue trying allocation until we run out of attempts
// (or attempts are set to 0, which means infinite)
--
i
;
}
while
(
i
||
!
attempts_
);
isc_throw
(
AllocFailed
,
"Failed to allocate address after "
<<
attempts_
<<
" tries"
);
}
Lease6Ptr
AllocEngine
::
reuseExpiredLease
(
Lease6Ptr
&
expired
,
const
Subnet6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
...
...
@@ -300,6 +408,45 @@ Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
return
(
expired
);
}
Lease4Ptr
AllocEngine
::
reuseExpiredLease
(
Lease4Ptr
&
expired
,
const
SubnetPtr
&
subnet
,
const
ClientIdPtr
&
clientid
,
const
HWAddrPtr
&
hwaddr
,
bool
fake_allocation
/*= false */
)
{
if
(
!
expired
->
expired
())
{
isc_throw
(
BadValue
,
"Attempt to recycle lease that is still valid"
);
}
// address, lease type and prefixlen (0) stay the same
expired
->
client_id_
=
clientid
;
expired
->
hwaddr_
=
hwaddr
->
hwaddr_
;
expired
->
valid_lft_
=
subnet
->
getValid
();
expired
->
t1_
=
subnet
->
getT1
();
expired
->
t2_
=
subnet
->
getT2
();
expired
->
cltt_
=
time
(
NULL
);
expired
->
subnet_id_
=
subnet
->
getID
();
expired
->
fixed_
=
false
;
expired
->
hostname_
=
std
::
string
(
""
);
expired
->
fqdn_fwd_
=
false
;
expired
->
fqdn_rev_
=
false
;
/// @todo: log here that the lease was reused (there's ticket #2524 for
/// logging in libdhcpsrv)
if
(
!
fake_allocation
)
{
// for REQUEST we do update the lease
LeaseMgrFactory
::
instance
().
updateLease4
(
expired
);
}
// We do nothing for SOLICIT. We'll just update database when
// the client gets back to us with REQUEST message.
// it's not really expired at this stage anymore - let's return it as
// an updated lease
return
(
expired
);
}
Lease6Ptr
AllocEngine
::
createLease6
(
const
Subnet6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
uint32_t
iaid
,
...
...
@@ -338,6 +485,48 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
}
}
Lease4Ptr
AllocEngine
::
createLease4
(
const
SubnetPtr
&
subnet
,
const
DuidPtr
&
clientid
,
const
HWAddrPtr
&
hwaddr
,
const
IOAddress
&
addr
,
bool
fake_allocation
/*= false */
)
{
if
(
!
hwaddr
)
{
isc_throw
(
BadValue
,
"Can't create a lease with NULL HW address"
);
}
time_t
now
=
time
(
NULL
);
Lease4Ptr
lease
(
new
Lease4
(
addr
,
&
hwaddr
->
hwaddr_
[
0
],
hwaddr
->
hwaddr_
.
size
(),
&
clientid
->
getDuid
()[
0
],
clientid
->
getDuid
().
size
(),
subnet
->
getValid
(),
subnet
->
getT1
(),
subnet
->
getT2
(),
now
,
subnet
->
getID
()));
if
(
!
fake_allocation
)
{
// That is a real (REQUEST) allocation
bool
status
=
LeaseMgrFactory
::
instance
().
addLease
(
lease
);
if
(
status
)
{
return
(
lease
);
}
else
{
// One of many failures with LeaseMgr (e.g. lost connection to the
// database, database failed etc.). One notable case for that
// is that we are working in multi-process mode and we lost a race
// (some other process got that address first)
return
(
Lease4Ptr
());
}
}
else
{
// That is only fake (DISCOVER) allocation
// It is for OFFER only. We should not insert the lease into LeaseMgr,
// but rather check that we could have inserted it.
Lease4Ptr
existing
=
LeaseMgrFactory
::
instance
().
getLease4
(
addr
);
if
(
!
existing
)
{
return
(
lease
);
}
else
{
return
(
Lease4Ptr
());
}
}
}
AllocEngine
::~
AllocEngine
()
{
// no need to delete allocator. smart_ptr will do the trick for us
}
...
...
src/lib/dhcpsrv/alloc_engine.h
View file @
32e13fbf
...
...
@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/lease_mgr.h>
...
...
@@ -182,13 +183,15 @@ protected:
///
/// @param subnet subnet the allocation should come from
/// @param clientid Client identifier
/// @param hwaddr client's hardware address info
/// @param hint a hint that the client provided
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for DISCOVER that is not really allocated (true)
/// @return Allocated IPv4 lease (or NULL if allocation failed)
Lease4Ptr
allocateAddress4
(
const
SubnetPtr
&
subnet
,
const
DuidPtr
&
clientid
,
const
ClientIdPtr
&
clientid
,
const
HWAddrPtr
&
hwaddr
,
const
isc
::
asiolink
::
IOAddress
&
hint
,
bool
fake_allocation
);
...
...
@@ -224,12 +227,14 @@ private:
///
/// @param subnet subnet the lease is allocated from
/// @param clientid client identifier
/// @param hwaddr client's hardware address
/// @param addr an address that was selected and is confirmed to be available
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for DISCOVER that is not really allocated (true)
/// @return allocated lease (or NULL in the unlikely case of the lease just
/// becomed unavailable)
Lease4Ptr
createLease4
(
const
Subnet4Ptr
&
subnet
,
const
DuidPtr
&
clientid
,
Lease4Ptr
createLease4
(
const
SubnetPtr
&
subnet
,
const
DuidPtr
&
clientid
,
const
HWAddrPtr
&
hwaddr
,
const
isc
::
asiolink
::
IOAddress
&
addr
,
bool
fake_allocation
=
false
);
...
...
@@ -260,12 +265,14 @@ private:
/// @param expired old, expired lease
/// @param subnet subnet the lease is allocated from
/// @param clientid client identifier
/// @param hwaddr client's hardware address
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for DISCOVER that is not really allocated (true)
/// @return refreshed lease
/// @throw BadValue if trying to recycle lease that is still valid
Lease4Ptr
reuseExpiredLease
(
Lease4Ptr
&
expired
,
const
Subnet4Ptr
&
subnet
,
const
DuidPtr
&
clientid
,
Lease4Ptr
reuseExpiredLease
(
Lease4Ptr
&
expired
,
const
SubnetPtr
&
subnet
,
const
ClientIdPtr
&
clientid
,
const
HWAddrPtr
&
hwaddr
,
bool
fake_allocation
=
false
);
/// @brief reuses expired IPv6 lease
...
...
src/lib/dhcpsrv/lease_mgr.h
View file @
32e13fbf
...
...
@@ -233,10 +233,10 @@ struct Lease4 : public Lease {
/// @param valid_lft Lifetime of the lease
/// @param cltt Client last transmission time
/// @param subnet_id Subnet identification
Lease4
(
uint32_t
addr
,
const
uint8_t
*
hwaddr
,
size_t
hwaddr_len
,
Lease4
(
const
isc
::
asiolink
::
IOAddress
&
addr
,
const
uint8_t
*
hwaddr
,
size_t
hwaddr_len
,
const
uint8_t
*
clientid
,
size_t
clientid_len
,
uint32_t
valid_lft
,
time_t
cltt
,
uint32_t
subnet_id
)
:
Lease
(
addr
,
0
,
0
,
valid_lft
,
subnet_id
,
cltt
),
uint32_t
t1
,
uint32_t
t2
,
time_t
cltt
,
uint32_t
subnet_id
)
:
Lease
(
addr
,
t1
,
t2
,
valid_lft
,
subnet_id
,
cltt
),
ext_
(
0
),
hwaddr_
(
hwaddr
,
hwaddr
+
hwaddr_len
),
client_id_
(
new
ClientId
(
clientid
,
clientid_len
))
{
}
...
...
@@ -370,6 +370,7 @@ typedef std::vector<Lease6Ptr> Lease6Collection;
class
LeaseMgr
{
public:
/// Client hardware address
/// @todo: migrate to HWAddr structure
typedef
std
::
vector
<
uint8_t
>
HWAddr
;
/// Database configuration parameter map
...
...
src/lib/dhcpsrv/memfile_lease_mgr.cc
View file @
32e13fbf
...
...
@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/memfile_lease_mgr.h>
#include <exceptions/exceptions.h>
#include <iostream>
...
...
@@ -27,8 +28,13 @@ Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
Memfile_LeaseMgr
::~
Memfile_LeaseMgr
()
{
}
bool
Memfile_LeaseMgr
::
addLease
(
const
Lease4Ptr
&
)
{
return
(
false
);
bool
Memfile_LeaseMgr
::
addLease
(
const
Lease4Ptr
&
lease
)
{
if
(
getLease4
(
lease
->
addr_
))
{
// there is a lease with specified address already
return
(
false
);
}
storage4_
.
insert
(
lease
);
return
(
true
);
}
bool
Memfile_LeaseMgr
::
addLease
(
const
Lease6Ptr
&
lease
)
{
...
...
@@ -40,27 +46,51 @@ bool Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
return
(
true
);
}
Lease4Ptr
Memfile_LeaseMgr
::
getLease4
(
const
isc
::
asiolink
::
IOAddress
&
)
const
{
return
(
Lease4Ptr
());
Lease4Ptr
Memfile_LeaseMgr
::
getLease4
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
Lease4Storage
::
iterator
l
=
storage4_
.
find
(
addr
);
if
(
l
==
storage4_
.
end
())
{
return
(
Lease4Ptr
());
}
else
{
return
(
*
l
);
}
}
Lease4Collection
Memfile_LeaseMgr
::
getLease4
(
const
HWAddr
&
)
const
{
isc_throw
(
NotImplemented
,
"getLease4(HWaddr x) method not implemented yet"
);
return
(
Lease4Collection
());
}
Lease4Ptr
Memfile_LeaseMgr
::
getLease4
(
const
HWAddr
&
,
SubnetID
)
const
{
Lease4Ptr
Memfile_LeaseMgr
::
getLease4
(
const
HWAddr
&
hwaddr
,
SubnetID
id
)
const
{
Lease4Storage
::
iterator
l
;
for
(
l
=
storage4_
.
begin
();
l
!=
storage4_
.
end
();
++
l
)
{
if
(
((
*
l
)
->
hwaddr_
==
hwaddr
)
&&
((
*
l
)
->
subnet_id_
==
id
))
{
return
(
*
l
);
}
}
// not found
return
(
Lease4Ptr
());
}
Lease4Ptr
Memfile_LeaseMgr
::
getLease4
(
const
ClientId
&
,
SubnetID
)
const
{
Lease4Ptr
Memfile_LeaseMgr
::
getLease4
(
const
ClientId
&
client_id
,
SubnetID
subnet_id
)
const
{
Lease4Storage
::
iterator
l
;
for
(
l
=
storage4_
.
begin
();
l
!=
storage4_
.
end
();
++
l
)
{
if
(
(
*
(
*
l
)
->
client_id_
==
client_id
)
&&
((
*
l
)
->
subnet_id_
==
subnet_id
))
{
return
(
*
l
);
}
}
// not found
return
(
Lease4Ptr
());
}
Lease4Collection
Memfile_LeaseMgr
::
getLease4
(
const
ClientId
&
)
const
{
return
(
Lease4Collection
()
);
isc_throw
(
NotImplemented
,
"getLease4(ClientId) not implemented"
);
}
Lease6Ptr
Memfile_LeaseMgr
::
getLease6
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
const
{
...
...
@@ -98,11 +128,18 @@ void Memfile_LeaseMgr::updateLease6(const Lease6Ptr& ) {
bool
Memfile_LeaseMgr
::
deleteLease
(
const
isc
::
asiolink
::
IOAddress
&
addr
)
{
if
(
addr
.
isV4
())
{
// V4 not implemented yet
return
(
false
);
// v4 lease
Lease4Storage
::
iterator
l
=
storage4_
.
find
(
addr
);
if
(
l
==
storage4_
.
end
())
{
// No such lease
return
(
false
);
}
else
{
storage4_
.
erase
(
l
);
return
(
true
);
}
}
else
{
//
V
6 lease
//
v
6 lease
Lease6Storage
::
iterator
l
=
storage6_
.
find
(
addr
);
if
(
l
==
storage6_
.
end
())
{
// No such lease
...
...
src/lib/dhcpsrv/memfile_lease_mgr.h
View file @
32e13fbf
...
...
@@ -231,6 +231,22 @@ protected:
>
>
Lease6Storage
;
// Let the whole contraption be called Lease6Storage.
typedef
boost
::
multi_index_container
<
// this is a multi-index container...
Lease4Ptr
,
// it will hold shared_ptr to leases6
boost
::
multi_index
::
indexed_by
<
// and will be sorted by
// IPv6 address that are unique. That particular key is a member
// of the Lease6 structure, is of type IOAddress and can be accessed
// by doing &Lease6::addr_
boost
::
multi_index
::
ordered_unique
<
boost
::
multi_index
::
member
<
Lease
,
isc
::
asiolink
::
IOAddress
,
&
Lease
::
addr_
>
>
>
>
Lease4Storage
;
// Let the whole contraption be called Lease6Storage.
/// @brief stores IPv4 leases
Lease4Storage
storage4_
;
/// @brief stores IPv6 leases
Lease6Storage
storage6_
;
};
...
...
src/lib/dhcpsrv/mysql_lease_mgr.cc
View file @
32e13fbf
...
...
@@ -448,9 +448,10 @@ public:
time_t
cltt
=
0
;
MySqlLeaseMgr
::
convertFromDatabaseTime
(
expire_
,
valid_lifetime_
,
cltt
);
// note that T1 and T2 are not stored
return
(
Lease4Ptr
(
new
Lease4
(
addr4_
,
hwaddr_buffer_
,
hwaddr_length_
,
client_id_buffer_
,
client_id_length_
,
valid_lifetime_
,
cltt
,
subnet_id_
)));
valid_lifetime_
,
0
,
0
,
cltt
,
subnet_id_
)));
}
/// @brief Return columns in error
...
...
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
View file @
32e13fbf
This diff is collapsed.
Click to expand it.
src/lib/dhcpsrv/tests/cfgmgr_unittest.cc
View file @
32e13fbf
...
...
@@ -39,9 +39,14 @@ namespace {
class
CfgMgrTest
:
public
::
testing
::
Test
{
public:
CfgMgrTest
()
{
// make sure we start with a clean configuration
CfgMgr
::
instance
().
deleteSubnets4
();
CfgMgr
::
instance
().
deleteSubnets6
();
}
~
CfgMgrTest
()
{
// clean up after the test
CfgMgr
::
instance
().
deleteSubnets4
();
CfgMgr
::
instance
().
deleteSubnets6
();
}
};
...
...
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
View file @
32e13fbf
...
...
@@ -272,7 +272,7 @@ TEST(Lease4, Lease4Constructor) {
// Create the lease
Lease4
lease
(
ADDRESS
[
i
],
HWADDR
,
sizeof
(
HWADDR
),
CLIENTID
,
sizeof
(
CLIENTID
),
VALID_LIFETIME
,
current_time
,
CLIENTID
,
sizeof
(
CLIENTID
),
VALID_LIFETIME
,
0
,
0
,
current_time
,
SUBNET_ID
);
EXPECT_EQ
(
ADDRESS
[
i
],
static_cast
<
uint32_t
>
(
lease
.
addr_
));
...
...
@@ -312,10 +312,10 @@ TEST(Lease4, OperatorEquals) {
// Check when the leases are equal.
Lease4
lease1
(
ADDRESS
,
HWADDR
,
sizeof
(
HWADDR
),
CLIENTID
,
sizeof
(
CLIENTID
),
VALID_LIFETIME
,
current_time
,
CLIENTID
,
sizeof
(
CLIENTID
),
VALID_LIFETIME
,
current_time
,
0
,
0
,
SUBNET_ID
);
Lease4
lease2
(
ADDRESS
,
HWADDR
,
sizeof
(
HWADDR
),
CLIENTID
,
sizeof
(
CLIENTID
),
VALID_LIFETIME
,
current_time
,
CLIENTID
,
sizeof
(
CLIENTID
),
VALID_LIFETIME
,
current_time
,
0
,
0
,
SUBNET_ID
);
EXPECT_TRUE
(
lease1
==
lease2
);
EXPECT_FALSE
(
lease1
!=
lease2
);
...
...
tests/tools/perfdhcp/test_control.cc
View file @
32e13fbf
...
...
@@ -1414,9 +1414,7 @@ TestControl::sendRequest4(const TestControlSocket& socket,
setDefaults4
(
socket
,
pkt4
);
// Set hardware address
const
uint8_t
*
chaddr
=
offer_pkt4
->
getChaddr
();
std
::
vector
<
uint8_t
>
mac_address
(
chaddr
,
chaddr
+
HW_ETHER_LEN
);
pkt4
->
setHWAddr
(
HTYPE_ETHER
,
mac_address
.
size
(),
mac_address
);
pkt4
->
setHWAddr
(
offer_pkt4
->
getHWAddr
());
// Set elapsed time.
uint32_t
elapsed_time
=
getElapsedTime
<
Pkt4Ptr
>
(
discover_pkt4
,
offer_pkt4
);
pkt4
->
setSecs
(
static_cast
<
uint16_t
>
(
elapsed_time
/
1000
));
...
...
@@ -1461,8 +1459,10 @@ TestControl::sendRequest4(const TestControlSocket& socket,
transid
));
// Set hardware address from OFFER packet received.
const
uint8_t
*
chaddr
=
offer_pkt4
->
getChaddr
();
std
::
vector
<
uint8_t
>
mac_address
(
chaddr
,
chaddr
+
HW_ETHER_LEN
);
HWAddrPtr
hwaddr
=
offer_pkt4
->
getHWAddr
();
std
::
vector
<
uint8_t
>
mac_address
(
HW_ETHER_LEN
,
0
);
uint8_t
hw_len
=
hwaddr
->
hwaddr_
.
size
();
memcpy
(
&
mac_address
[
0
],
&
hwaddr
->
hwaddr_
[
0
],
hw_len
>
16
?
16
:
hw_len
);
pkt4
->
writeAt
(
rand_offset
,
mac_address
.
begin
(),
mac_address
.
end
());
// Set elapsed time.
...
...
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