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
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
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
Adam Osuchowski
Kea
Commits
abee3e73
Commit
abee3e73
authored
Apr 05, 2016
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Plain Diff
[master] Merge branch 'trac4300'
parents
12320a72
7741ab8c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
646 additions
and
376 deletions
+646
-376
src/lib/dhcpsrv/host.cc
src/lib/dhcpsrv/host.cc
+97
-58
src/lib/dhcpsrv/host.h
src/lib/dhcpsrv/host.h
+35
-32
src/lib/dhcpsrv/mysql_host_data_source.cc
src/lib/dhcpsrv/mysql_host_data_source.cc
+24
-51
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
+51
-108
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h
+17
-21
src/lib/dhcpsrv/tests/host_unittest.cc
src/lib/dhcpsrv/tests/host_unittest.cc
+328
-93
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
+16
-10
src/lib/util/strutil.cc
src/lib/util/strutil.cc
+19
-1
src/lib/util/strutil.h
src/lib/util/strutil.h
+20
-1
src/lib/util/tests/strutil_unittest.cc
src/lib/util/tests/strutil_unittest.cc
+39
-1
No files found.
src/lib/dhcpsrv/host.cc
View file @
abee3e73
...
...
@@ -75,14 +75,15 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len,
const
std
::
string
&
hostname
,
const
std
::
string
&
dhcp4_client_classes
,
const
std
::
string
&
dhcp6_client_classes
)
:
hw_address_
(),
duid_
(),
ipv4_subnet_id_
(
ipv4_subnet_id
),
:
identifier_type_
(
identifier_type
),
identifier_value_
(),
ipv4_subnet_id_
(
ipv4_subnet_id
),
ipv6_subnet_id_
(
ipv6_subnet_id
),
ipv4_reservation_
(
asiolink
::
IOAddress
::
IPV4_ZERO_ADDRESS
()),
hostname_
(
hostname
),
dhcp4_client_classes_
(
dhcp4_client_classes
),
dhcp6_client_classes_
(
dhcp6_client_classes
),
host_id_
(
0
),
cfg_option4_
(),
cfg_option6_
()
{
// Initialize
HWAddr or DUID
// Initialize
host identifier.
setIdentifier
(
identifier
,
identifier_len
,
identifier_type
);
if
(
!
ipv4_reservation
.
isV4Zero
())
{
...
...
@@ -97,14 +98,15 @@ Host::Host(const std::string& identifier, const std::string& identifier_name,
const
std
::
string
&
hostname
,
const
std
::
string
&
dhcp4_client_classes
,
const
std
::
string
&
dhcp6_client_classes
)
:
hw_address_
(),
duid_
(),
ipv4_subnet_id_
(
ipv4_subnet_id
),
:
identifier_type_
(
IDENT_HWADDR
),
identifier_value_
(),
ipv4_subnet_id_
(
ipv4_subnet_id
),
ipv6_subnet_id_
(
ipv6_subnet_id
),
ipv4_reservation_
(
asiolink
::
IOAddress
::
IPV4_ZERO_ADDRESS
()),
hostname_
(
hostname
),
dhcp4_client_classes_
(
dhcp4_client_classes
),
dhcp6_client_classes_
(
dhcp6_client_classes
),
host_id_
(
0
),
cfg_option4_
(
new
CfgOption
()),
cfg_option6_
(
new
CfgOption
())
{
// Initialize
HWAddr or DUID
// Initialize
host identifier.
setIdentifier
(
identifier
,
identifier_name
);
if
(
!
ipv4_reservation
.
isV4Zero
())
{
...
...
@@ -115,51 +117,36 @@ Host::Host(const std::string& identifier, const std::string& identifier_name,
const
std
::
vector
<
uint8_t
>&
Host
::
getIdentifier
()
const
{
if
(
hw_address_
)
{
return
(
hw_address_
->
hwaddr_
);
}
else
if
(
duid_
)
{
return
(
duid_
->
getDuid
());
}
static
std
::
vector
<
uint8_t
>
empty_vector
;
return
(
empty_vector
);
return
(
identifier_value_
);
}
Host
::
IdentifierType
Host
::
getIdentifierType
()
const
{
if
(
hw_address_
)
{
return
(
IDENT_HWADDR
);
}
return
(
IDENT_DUID
);
return
(
identifier_type_
);
}
std
::
string
Host
::
getIdentifierAsText
()
const
{
std
::
string
txt
;
if
(
hw_address_
)
{
txt
=
getIdentifierAsText
(
IDENT_HWADDR
,
&
hw_address_
->
hwaddr_
[
0
],
hw_address_
->
hwaddr_
.
size
());
}
else
if
(
duid_
)
{
txt
=
getIdentifierAsText
(
IDENT_DUID
,
&
duid_
->
getDuid
()[
0
],
duid_
->
getDuid
().
size
());
}
else
{
txt
=
"(none)"
;
}
HWAddrPtr
Host
::
getHWAddress
()
const
{
return
((
identifier_type_
==
IDENT_HWADDR
)
?
HWAddrPtr
(
new
HWAddr
(
identifier_value_
,
HTYPE_ETHER
))
:
HWAddrPtr
());
}
DuidPtr
Host
::
getDuid
()
const
{
return
((
identifier_type_
==
IDENT_DUID
)
?
DuidPtr
(
new
DUID
(
identifier_value_
))
:
DuidPtr
());
}
return
(
txt
);
std
::
string
Host
::
getIdentifierAsText
()
const
{
return
(
getIdentifierAsText
(
identifier_type_
,
&
identifier_value_
[
0
],
identifier_value_
.
size
()));
}
std
::
string
Host
::
getIdentifierAsText
(
const
IdentifierType
&
type
,
const
uint8_t
*
value
,
const
size_t
length
)
{
// Length 0 doesn't make sense.
if
(
length
==
0
)
{
isc_throw
(
BadValue
,
"invalid length 0 of the host identifier while"
" converting the identifier to a textual form"
);
}
// Convert identifier into <type>=<value> form.
std
::
ostringstream
s
;
switch
(
type
)
{
...
...
@@ -169,46 +156,98 @@ Host::getIdentifierAsText(const IdentifierType& type, const uint8_t* value,
case
IDENT_DUID
:
s
<<
"duid"
;
break
;
case
IDENT_CIRCUIT_ID
:
s
<<
"circuit-id"
;
break
;
default:
isc_throw
(
BadValue
,
"requested conversion of the unsupported"
" identifier into textual form"
);
// This should never happen actually, unless we add new identifier
// and forget to add a case for it above.
s
<<
"(invalid-type)"
;
}
std
::
vector
<
uint8_t
>
vec
(
value
,
value
+
length
);
s
<<
"="
<<
util
::
encode
::
encodeHex
(
vec
);
s
<<
"="
<<
(
length
>
0
?
util
::
encode
::
encodeHex
(
vec
)
:
"(null)"
);
return
(
s
.
str
());
}
std
::
string
Host
::
getIdentifierName
(
const
IdentifierType
&
type
)
{
switch
(
type
)
{
case
Host
::
IDENT_HWADDR
:
return
(
"hw-address"
);
case
Host
::
IDENT_DUID
:
return
(
"duid"
);
case
Host
::
IDENT_CIRCUIT_ID
:
return
(
"circuit-id"
);
default:
;
}
return
(
"(unknown)"
);
}
void
Host
::
setIdentifier
(
const
uint8_t
*
identifier
,
const
size_t
len
,
const
IdentifierType
&
type
)
{
switch
(
type
)
{
case
IDENT_HWADDR
:
hw_address_
=
HWAddrPtr
(
new
HWAddr
(
identifier
,
len
,
HTYPE_ETHER
));
duid_
.
reset
();
break
;
case
IDENT_DUID
:
duid_
=
DuidPtr
(
new
DUID
(
identifier
,
len
));
hw_address_
.
reset
();
break
;
default:
isc_throw
(
isc
::
BadValue
,
"invalid client identifier type '"
<<
static_cast
<
int
>
(
type
)
<<
"' when creating host "
" instance"
);
if
(
len
<
1
)
{
isc_throw
(
BadValue
,
"invalid client identifier length 0"
);
}
identifier_type_
=
type
;
identifier_value_
.
assign
(
identifier
,
identifier
+
len
);
}
void
Host
::
setIdentifier
(
const
std
::
string
&
identifier
,
const
std
::
string
&
name
)
{
// HW address and DUID are special cases because they are typically
// specified as values with colons between consecutive octets. Thus,
// we use the HWAddr and DUID classes to validate them and to
// convert them into binary format.
if
(
name
==
"hw-address"
)
{
hw_address_
=
HWAddrPtr
(
new
HWAddr
(
HWAddr
::
fromText
(
identifier
)));
duid_
.
reset
();
HWAddr
hwaddr
(
HWAddr
::
fromText
(
identifier
));
identifier_type_
=
IDENT_HWADDR
;
identifier_value_
=
hwaddr
.
hwaddr_
;
}
else
if
(
name
==
"duid"
)
{
duid_
=
DuidPtr
(
new
DUID
(
DUID
::
fromText
(
identifier
)));
hw_address_
.
reset
();
identifier_type_
=
IDENT_DUID
;
DUID
duid
(
DUID
::
fromText
(
identifier
));
identifier_value_
=
duid
.
getDuid
();
}
else
{
isc_throw
(
isc
::
BadValue
,
"invalid client identifier type '"
<<
name
<<
"' when creating host instance"
);
if
(
name
==
"circuit-id"
)
{
identifier_type_
=
IDENT_CIRCUIT_ID
;
}
else
{
isc_throw
(
isc
::
BadValue
,
"invalid client identifier type '"
<<
name
<<
"' when creating host instance"
);
}
// Here we're converting values other than DUID and HW address. These
// values can either be specified as strings of hexadecimal digits or
// strings in quotes. The latter are copied to a vector excluding quote
// characters.
// Try to convert the values in quotes into a vector of ASCII codes.
// If the identifier lacks opening and closing quote, this will return
// an empty value, in which case we'll try to decode it as a string of
// hexadecimal digits.
std
::
vector
<
uint8_t
>
binary
=
util
::
str
::
quotedStringToBinary
(
identifier
);
if
(
binary
.
empty
())
{
try
{
util
::
encode
::
decodeHex
(
identifier
,
binary
);
}
catch
(...)
{
// The string doesn't match any known pattern, so we have to
// report an error at this point.
isc_throw
(
isc
::
BadValue
,
"invalid host identifier value '"
<<
identifier
<<
"'"
);
}
}
// Successfully decoded the identifier, so let's use it.
identifier_value_
.
swap
(
binary
);
}
}
...
...
src/lib/dhcpsrv/host.h
View file @
abee3e73
...
...
@@ -179,7 +179,8 @@ public:
/// DHCPv6 client's DUID are supported.
enum
IdentifierType
{
IDENT_HWADDR
,
IDENT_DUID
IDENT_DUID
,
IDENT_CIRCUIT_ID
};
/// @brief Constructor.
...
...
@@ -222,11 +223,19 @@ public:
/// is useful in cases when the reservation is specified in the server
/// configuration file, where:
/// - MAC address is specified as: "01:02:03:04:05:06"
/// - DUID is specified as: "010203040506abcd"
/// - DUID can be specified as: "01:02:03:04:05:06:ab:cd" or "010203040506abcd".
/// - Other identifiers are specified as: "010203040506abcd" or as
/// "'some identfier'".
///
/// In case of identifiers other than HW address and DUID it is possible to use
/// textual representation, e.g. 'some identifier', which is converted to a
/// vector of ASCII codes representing characters in a given string, excluding
/// quotes. This is useful in cases when specific identifiers, e.g. circuit-id
/// are manually assigned user friendly values.
///
/// @param identifier Identifier in the textual format. The expected formats
/// for the hardware address and
DUID have been shown
above.
/// @param identifier_name One of "hw-address"
or "duid"
/// for the hardware address and
other identifiers are provided
above.
/// @param identifier_name One of "hw-address"
, "duid", "circuit-id".
/// @param ipv4_subnet_id Identifier of the IPv4 subnet to which the host
/// is connected.
/// @param ipv6_subnet_id Identifier of the IPv6 subnet to which the host
...
...
@@ -251,13 +260,10 @@ public:
/// @brief Replaces currently used identifier with a new identifier.
///
/// This method initializes hardware address or DUID (@c hw_address_ or
/// @c duid_ respectively). The other (not initialized member) is
/// deallocated.
///
/// This method sets a new identifier type and value for a host.
/// This method is called by the @c Host constructor.
///
/// @param identifier Pointer to
the new identifier in the textual format
.
/// @param identifier Pointer to
a buffer holding an identifier
.
/// @param len Length of the identifier that the @c identifier points to.
/// @param type Identifier type.
///
...
...
@@ -267,14 +273,11 @@ public:
/// @brief Replaces currently used identifier with a new identifier.
///
/// This method initializes hardware address or DUID (@c hw_address_ or
/// @c duid_ respectively). The other (not initialized member) is
/// deallocated.
///
/// This method sets a new identifier type and value for a host.
/// This method is called by the @c Host constructor.
///
/// @param identifier
Pointer to the
new identifier in the textual format.
/// @param name One of "hw-address"
or "du
id".
/// @param identifier
Reference to a
new identifier in the textual format.
/// @param name One of "hw-address"
, "duid", "circuit-
id".
///
/// @throw BadValue if the identifier is invalid.
void
setIdentifier
(
const
std
::
string
&
identifier
,
const
std
::
string
&
name
);
...
...
@@ -283,30 +286,32 @@ public:
///
/// @return Pointer to the @c HWAddr structure or null if the reservation
/// is not associated with a hardware address.
HWAddrPtr
getHWAddress
()
const
{
return
(
hw_address_
);
}
HWAddrPtr
getHWAddress
()
const
;
/// @brief Returns DUID for which the reservations are made.
///
/// @return Pointer to the @c DUID structure or null if the reservation
/// is not associated with a DUID.
DuidPtr
getDuid
()
const
{
return
(
duid_
);
}
DuidPtr
getDuid
()
const
;
/// @brief Returns the identifier (MAC or DUID) in binary form.
/// @return const reference to MAC or DUID in vector<uint8_t> form
/// @brief Returns the identifier in a binary form.
///
/// @return const reference to a vector<uint8_t> holding an identifier
/// value.
const
std
::
vector
<
uint8_t
>&
getIdentifier
()
const
;
/// @brief Returns the identifier type.
///
@return the identifier type
///
IdentifierType
getIdentifierType
()
const
;
/// @brief Returns host identifier (mac or DUID) in printer friendly form.
/// @return text form of the identifier, including (duid= or mac=).
/// @brief Returns host identifier in a textual form.
///
/// @return Identifier in the form of <type>=<value>.
std
::
string
getIdentifierAsText
()
const
;
/// @brief Returns name of the identifier of a specified type.
static
std
::
string
getIdentifierName
(
const
IdentifierType
&
type
);
/// @brief Returns host identifier in textual form.
///
/// @param type Identifier type.
...
...
@@ -487,12 +492,10 @@ private:
void
addClientClassInternal
(
ClientClasses
&
classes
,
const
std
::
string
&
class_name
);
/// @brief Pointer to the hardware address associated with the reservations
/// for the host.
HWAddrPtr
hw_address_
;
/// @brief Pointer to the DUID associated with the reservations for the
/// host.
DuidPtr
duid_
;
/// @brief Identifier type.
IdentifierType
identifier_type_
;
/// @brief Vector holding identifier value.
std
::
vector
<
uint8_t
>
identifier_value_
;
/// @brief Subnet identifier for the DHCPv4 client.
SubnetID
ipv4_subnet_id_
;
/// @brief Subnet identifier for the DHCPv6 client.
...
...
src/lib/dhcpsrv/mysql_host_data_source.cc
View file @
abee3e73
...
...
@@ -42,6 +42,11 @@ const size_t CLIENT_CLASSES_MAX_LEN = 255;
/// in the Client FQDN %Option (see RFC4702 and RFC4704).
const
size_t
HOSTNAME_MAX_LEN
=
255
;
/// @brief Numeric value representing last supported identifier.
///
/// This value is used to validate whether the identifier type stored in
/// a database is within bounds. of supported identifiers.
const
uint8_t
MAX_IDENTIFIER_TYPE
=
static_cast
<
uint8_t
>
(
Host
::
IDENT_CIRCUIT_ID
);
/// @brief Prepared MySQL statements used by the backend to insert and
/// retrieve hosts from the database.
...
...
@@ -299,42 +304,21 @@ public:
bind_
[
0
].
is_unsigned
=
MLM_TRUE
;
// dhcp_identifier : VARBINARY(128) NOT NULL
// Check which of the identifiers is used and set values accordingly
if
(
host
->
getDuid
())
{
dhcp_identifier_length_
=
host
->
getDuid
()
->
getDuid
().
size
();
bind_
[
1
].
buffer_type
=
MYSQL_TYPE_BLOB
;
bind_
[
1
].
buffer
=
reinterpret_cast
<
char
*>
(
const_cast
<
uint8_t
*>
(
&
(
host
->
getDuid
()
->
getDuid
()[
0
])));
bind_
[
1
].
buffer_length
=
dhcp_identifier_length_
;
bind_
[
1
].
length
=
&
dhcp_identifier_length_
;
}
else
if
(
host
->
getHWAddress
()){
dhcp_identifier_length_
=
host
->
getHWAddress
()
->
hwaddr_
.
size
();
bind_
[
1
].
buffer_type
=
MYSQL_TYPE_BLOB
;
bind_
[
1
].
buffer
=
reinterpret_cast
<
char
*>
(
&
(
host
->
getHWAddress
()
->
hwaddr_
[
0
]));
bind_
[
1
].
buffer_length
=
dhcp_identifier_length_
;
bind_
[
1
].
length
=
&
dhcp_identifier_length_
;
}
else
{
isc_throw
(
DbOperationError
,
"Host object doesn't contain any"
" identifier which can be used to retrieve information"
" from the database about its static reservations"
);
}
dhcp_identifier_length_
=
host
->
getIdentifier
().
size
();
memcpy
(
static_cast
<
void
*>
(
dhcp_identifier_buffer_
),
&
(
host
->
getIdentifier
())[
0
],
host
->
getIdentifier
().
size
());
bind_
[
1
].
buffer_type
=
MYSQL_TYPE_BLOB
;
bind_
[
1
].
buffer
=
dhcp_identifier_buffer_
;
bind_
[
1
].
buffer_length
=
dhcp_identifier_length_
;
bind_
[
1
].
length
=
&
dhcp_identifier_length_
;
// dhcp_identifier_type : TINYINT NOT NULL
// Check which of the identifier types is used and set values accordingly
if
(
host
->
getHWAddress
())
{
dhcp_identifier_type_
=
BaseHostDataSource
::
ID_HWADDR
;
// 0
bind_
[
2
].
buffer_type
=
MYSQL_TYPE_TINY
;
bind_
[
2
].
buffer
=
reinterpret_cast
<
char
*>
(
&
dhcp_identifier_type_
);
bind_
[
2
].
is_unsigned
=
MLM_TRUE
;
}
else
if
(
host
->
getDuid
())
{
dhcp_identifier_type_
=
BaseHostDataSource
::
ID_DUID
;
// 1
bind_
[
2
].
buffer_type
=
MYSQL_TYPE_TINY
;
bind_
[
2
].
buffer
=
reinterpret_cast
<
char
*>
(
&
dhcp_identifier_type_
);
bind_
[
2
].
is_unsigned
=
MLM_TRUE
;
}
dhcp_identifier_type_
=
static_cast
<
uint8_t
>
(
host
->
getIdentifierType
());
bind_
[
2
].
buffer_type
=
MYSQL_TYPE_TINY
;
bind_
[
2
].
buffer
=
reinterpret_cast
<
char
*>
(
&
dhcp_identifier_type_
);
bind_
[
2
].
is_unsigned
=
MLM_TRUE
;
// dhcp4_subnet_id : INT UNSIGNED NULL
// Can't take an address of intermediate object, so let's store it
...
...
@@ -495,25 +479,14 @@ public:
/// @return Host Pointer to a @ref HostPtr object holding a pointer to the
/// @ref Host object returned.
HostPtr
retrieveHost
()
{
// Set the dhcp identifier type in a variable of the appropriate data type,
// which has been initialized with an arbitrary (but valid) value.
Host
::
IdentifierType
type
=
Host
::
IDENT_HWADDR
;
switch
(
dhcp_identifier_type_
)
{
case
0
:
type
=
Host
::
IDENT_HWADDR
;
break
;
case
1
:
type
=
Host
::
IDENT_DUID
;
break
;
default:
// Check if the identifier stored in the database is correct.
if
(
dhcp_identifier_type_
>
MAX_IDENTIFIER_TYPE
)
{
isc_throw
(
BadValue
,
"invalid dhcp identifier type returned: "
<<
static_cast
<
int
>
(
dhcp_identifier_type_
)
<<
". Only 0 or 1 are supported."
);
<<
static_cast
<
int
>
(
dhcp_identifier_type_
));
}
// Set the dhcp identifier type in a variable of the appropriate data type.
Host
::
IdentifierType
type
=
static_cast
<
Host
::
IdentifierType
>
(
dhcp_identifier_type_
);
// Set DHCPv4 subnet ID to the value returned. If NULL returned, set to 0.
SubnetID
ipv4_subnet_id
(
0
);
...
...
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc
View file @
abee3e73
...
...
@@ -26,7 +26,7 @@ GenericHostDataSourceTest::GenericHostDataSourceTest()
GenericHostDataSourceTest
::~
GenericHostDataSourceTest
()
{
}
std
::
string
std
::
vector
<
uint8_t
>
GenericHostDataSourceTest
::
generateHWAddr
(
const
bool
new_identifier
)
{
/// @todo: Consider moving this somewhere to lib/testutils.
...
...
@@ -34,15 +34,6 @@ GenericHostDataSourceTest::generateHWAddr(const bool new_identifier) {
// if you need to enter MySQL queries by hand.
static
uint8_t
hwaddr
[]
=
{
65
,
66
,
67
,
68
,
69
,
70
};
stringstream
tmp
;
for
(
int
i
=
0
;
i
<
sizeof
(
hwaddr
);
++
i
)
{
if
(
i
)
{
tmp
<<
":"
;
}
tmp
<<
std
::
setw
(
2
)
<<
std
::
hex
<<
std
::
setfill
(
'0'
)
<<
static_cast
<
unsigned
int
>
(
hwaddr
[
i
]);
}
if
(
new_identifier
)
{
// Increase the address for the next time we use it.
// This is primitive, but will work for 65k unique
...
...
@@ -52,46 +43,38 @@ GenericHostDataSourceTest::generateHWAddr(const bool new_identifier) {
hwaddr
[
sizeof
(
hwaddr
)
-
2
]
++
;
}
}
return
(
tmp
.
str
(
));
return
(
std
::
vector
<
uint8_t
>
(
hwaddr
,
hwaddr
+
sizeof
(
hwaddr
)
));
}
std
::
string
GenericHostDataSourceTest
::
generate
Duid
(
const
bool
new_identifier
)
{
std
::
vector
<
uint8_t
>
GenericHostDataSourceTest
::
generate
Identifier
(
const
bool
new_identifier
)
{
/// @todo: Consider moving this somewhere to lib/testutils.
// Let's use something that is easily printable. That's convenient
// if you need to enter MySQL queries by hand.
static
uint8_t
duid
[]
=
{
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
};
static
uint8_t
ident
[]
=
{
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
,
73
,
74
};
stringstream
tmp
;
for
(
int
i
=
0
;
i
<
sizeof
(
duid
);
++
i
)
{
tmp
<<
std
::
setw
(
2
)
<<
std
::
hex
<<
std
::
setfill
(
'0'
)
<<
static_cast
<
unsigned
int
>
(
duid
[
i
]);
}
// Increase the DUID for the next time we use it.
// Increase the identifier for the next time we use it.
// This is primitive, but will work for 65k unique
//
DUID
s.
//
identifier
s.
if
(
new_identifier
)
{
duid
[
sizeof
(
duid
)
-
1
]
++
;
if
(
duid
[
sizeof
(
duid
)
-
1
]
==
0
)
{
duid
[
sizeof
(
duid
)
-
2
]
++
;
ident
[
sizeof
(
ident
)
-
1
]
++
;
if
(
ident
[
sizeof
(
ident
)
-
1
]
==
0
)
{
ident
[
sizeof
(
ident
)
-
2
]
++
;
}
}
return
(
tmp
.
str
(
));
return
(
std
::
vector
<
uint8_t
>
(
ident
,
ident
+
sizeof
(
ident
)
));
}
HostPtr
GenericHostDataSourceTest
::
initializeHost4
(
std
::
string
address
,
bool
hwaddr
)
{
string
ident
;
string
ident_type
;
if
(
hwaddr
)
{
HostPtr
GenericHostDataSourceTest
::
initializeHost4
(
const
std
::
string
&
address
,
const
Host
::
IdentifierType
&
id
)
{
std
::
vector
<
uint8_t
>
ident
;
if
(
id
==
Host
::
IDENT_HWADDR
)
{
ident
=
generateHWAddr
();
ident_type
=
"hw-address"
;
}
else
{
ident
=
generateDuid
();
ident_type
=
"duid"
;
ident
=
generateIdentifier
();
}
// Let's create ever increasing subnet-ids. Let's keep those different,
...
...
@@ -103,7 +86,7 @@ HostPtr GenericHostDataSourceTest::initializeHost4(std::string address,
subnet6
++
;
IOAddress
addr
(
address
);
HostPtr
host
(
new
Host
(
ident
,
ident_type
,
subnet4
,
subnet6
,
addr
));
HostPtr
host
(
new
Host
(
&
ident
[
0
],
ident
.
size
(),
id
,
subnet4
,
subnet6
,
addr
));
return
(
host
);
}
...
...
@@ -112,17 +95,13 @@ HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
Host
::
IdentifierType
identifier
,
bool
prefix
,
bool
new_identifier
)
{
string
ident
;
string
ident_type
;
std
::
vector
<
uint8_t
>
ident
;
switch
(
identifier
)
{
case
Host
::
IDENT_HWADDR
:
ident
=
generateHWAddr
(
new_identifier
);
ident_type
=
"hw-address"
;
break
;
case
Host
::
IDENT_DUID
:
ident
=
generateDuid
(
new_identifier
);
ident_type
=
"duid"
;
ident
=
generateIdentifier
(
new_identifier
);
break
;
default:
ADD_FAILURE
()
<<
"Unknown IdType: "
<<
identifier
;
...
...
@@ -137,7 +116,8 @@ HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
subnet4
++
;
subnet6
++
;
HostPtr
host
(
new
Host
(
ident
,
ident_type
,
subnet4
,
subnet6
,
IOAddress
(
"0.0.0.0"
)));
HostPtr
host
(
new
Host
(
&
ident
[
0
],
ident
.
size
(),
identifier
,
subnet4
,
subnet6
,
IOAddress
(
"0.0.0.0"
)));
if
(
!
prefix
)
{
// Create IPv6 reservation (for an address)
...
...
@@ -333,12 +313,12 @@ GenericHostDataSourceTest::compareClientClasses(const ClientClasses& /*classes1*
/// This is part of the work for #4213.
}
void
GenericHostDataSourceTest
::
testBasic4
(
bool
hwaddr
)
{
void
GenericHostDataSourceTest
::
testBasic4
(
const
Host
::
IdentifierType
&
id
)
{
// Make sure we have the pointer to the host data source.
ASSERT_TRUE
(
hdsptr_
);
// Create a host reservation.
HostPtr
host
=
initializeHost4
(
"192.0.2.1"
,
hwaddr
);
HostPtr
host
=
initializeHost4
(
"192.0.2.1"
,
id
);
ASSERT_TRUE
(
host
);
// Make sure the host is generate properly.
SubnetID
subnet
=
host
->
getIPv4SubnetID
();
...
...
@@ -358,15 +338,15 @@ void GenericHostDataSourceTest::testBasic4(bool hwaddr) {
}
void
GenericHostDataSourceTest
::
testGetByIPv4
(
bool
hwaddr
)
{
void
GenericHostDataSourceTest
::
testGetByIPv4
(
const
Host
::
IdentifierType
&
id
)
{
// Make sure we have a pointer to the host data source.
ASSERT_TRUE
(
hdsptr_
);
// Let's create a couple of hosts...
HostPtr
host1
=
initializeHost4
(
"192.0.2.1"
,
hwaddr
);
HostPtr
host2
=
initializeHost4
(
"192.0.2.2"
,
hwaddr
);
HostPtr
host3
=
initializeHost4
(
"192.0.2.3"
,
hwaddr
);
HostPtr
host4
=
initializeHost4
(
"192.0.2.4"
,
hwaddr
);
HostPtr
host1
=
initializeHost4
(
"192.0.2.1"
,
id
);
HostPtr
host2
=
initializeHost4
(
"192.0.2.2"
,
id
);
HostPtr
host3
=
initializeHost4
(
"192.0.2.3"
,
id
);
HostPtr
host4
=
initializeHost4
(
"192.0.2.4"
,
id
);
// ... and add them to the data source.
ASSERT_NO_THROW
(
hdsptr_
->
add
(
host1
));
...
...
@@ -402,52 +382,16 @@ void GenericHostDataSourceTest::testGetByIPv4(bool hwaddr) {