Skip to content
GitLab
Projects
Groups
Snippets
/
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
c13c824d
Commit
c13c824d
authored
Mar 20, 2015
by
Thomas Markwalder
Browse files
[master] Merge branch 'trac3689'
parents
ee47aff0
52b6493c
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
doc/guide/dhcp6-srv.xml
View file @
c13c824d
...
...
@@ -2071,11 +2071,64 @@ should include options from the isc option space:
<section
id=
"reservation6-hostname"
>
<title>
Reserving a hostname
</title>
<!-- @todo: replace this with the actual text once #3689 is implemented -->
<para>
Reserving a hostname is currently not supported. It is possible
to specify that information in the configuration file, but that data
is not used by the server engine yet.
</para>
</section>
<para>
When the reservation for the client includes the
<command>
hostname
</command>
, the server will assign this hostname to the client and send
it back in the Client FQDN, if the client sent the FQDN option to the
the server. The reserved hostname always takes precedence over the hostname
supplied by the client (via the FQDN option) or the autogenerated
(from the IPv6 address) hostname.
</para>
<para>
The server qualifies the reserved hostname with the value
of the
<command>
qualifying-suffix
</command>
parameter. For example, the
following subnet configuration:
<screen>
"subnet6": [
{
"subnet": "2001:db8:1::/48",
"pools": [ { "pool": "2001:db8:1::/80" } ],
"reservations": [
{
"duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
"ip-addresses": [ "2001:db8:1::100" ]
"hostname": "alice-laptop"
}
]
}
],
"dhcp-ddns": {
"enable-updates": true,
"qualifying-suffix": "example.isc.org."
}
</screen>
will result in assigning the "alice-laptop.example.isc.org." hostname to the
client using the DUID "01:02:03:04:05:0A:0B:0C:0D:0E". If the
<command>
qualifying-suffix
</command>
is not specified, the default (empty) value will be used, and
in this case the value specified as a
<command>
hostname
</command>
will
be treated as fully qualified name. Thus, by leaving the
<command>
qualifying-suffix
</command>
empty it is possible to qualify
hostnames for the different clients with different domain names:
<screen>
"subnet6": [
{
"subnet": "2001:db8:1::/48",
"pools": [ { "pool": "2001:db8:1::/80" } ],
"reservations": [
{
"duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
"ip-addresses": [ "2001:db8:1::100" ]
"hostname": "mark-desktop.example.org."
}
]
}
],
"dhcp-ddns": {
"enable-updates": true,
}
</screen>
will result in assigning the "mark-desktop.example.org." hostname to the
client using the DUID "01:02:03:04:05:0A:0B:0C:0D:0E".
</para>
</section>
<section
id=
"reservation6-options"
>
<title>
Reserving specific options
</title>
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
c13c824d
This diff is collapsed.
Click to expand it.
src/bin/dhcp6/dhcp6_srv.h
View file @
c13c824d
...
...
@@ -166,25 +166,25 @@ protected:
void
sanityCheck
(
const
Pkt6Ptr
&
pkt
,
RequirementLevel
clientid
,
RequirementLevel
serverid
);
/// @brief Processes incoming S
OLICIT
and returns response.
/// @brief Processes incoming S
olicit
and returns response.
///
/// Processes received S
OLICIT
message and verifies that its sender
/// Processes received S
olicit
message and verifies that its sender
/// should be served. In particular IA, TA and PD options are populated
/// with to-be assigned addresses, temporary addresses and delegated
/// prefixes, respectively. In the usual 4 message exchange, server is
/// expected to respond with A
DVERTISE
message. However, if client
/// requests rapid-commit and server supports it, R
EPLY
will be sent
/// instead of A
DVERTISE
and requested leases will be assigned
/// expected to respond with A
dvertise
message. However, if client
/// requests rapid-commit and server supports it, R
eply
will be sent
/// instead of A
dvertise
and requested leases will be assigned
/// immediately.
///
/// @param solicit S
OLICIT
message received from client
/// @param solicit S
olicit
message received from client
///
/// @return A
DVERTISE, REPLY
message or NULL
/// @return A
dvertise, Reply
message or NULL
.
Pkt6Ptr
processSolicit
(
const
Pkt6Ptr
&
solicit
);
/// @brief Processes incoming R
EQUEST
and returns R
EPLY
response.
/// @brief Processes incoming R
equest
and returns R
eply
response.
///
/// Processes incoming R
EQUEST
message and verifies that its sender
/// Processes incoming R
equest
message and verifies that its sender
/// should be served. In particular IA, TA and PD options are populated
/// with assigned addresses, temporary addresses and delegated
/// prefixes, respectively. Uses LeaseMgr to allocate or update existing
...
...
@@ -195,14 +195,22 @@ protected:
/// @return REPLY message or NULL
Pkt6Ptr
processRequest
(
const
Pkt6Ptr
&
request
);
/// @brief
Stub function that will handle
incoming R
ENEW
message
s
.
/// @brief
Processes
incoming R
enew
message.
///
/// @param renew message received from client
/// @param renew message received from the client
/// @return Reply message to be sent to the client.
Pkt6Ptr
processRenew
(
const
Pkt6Ptr
&
renew
);
/// @brief
Stub function that will handle
incoming R
EBIND
message
s
.
/// @brief
Processes
incoming R
ebind
message.
///
/// @param rebind message received from client
/// @todo There are cases when the Rebind message should be discarded
/// by the DHCP server. One of those is when the server doesn't have a
/// record of the client and it is unable to determine whether the
/// client is on the appropriate link or not. We don't seem to do it
/// now.
///
/// @param rebind message received from the client.
/// @return Reply message to be sent to the client.
Pkt6Ptr
processRebind
(
const
Pkt6Ptr
&
rebind
);
/// @brief Processes incoming Confirm message and returns Reply.
...
...
@@ -226,24 +234,26 @@ protected:
///
/// @param confirm Confirm message sent by a client.
///
/// @return Reply message from the server
al
NULL pointer if Confirm
/// @return Reply message from the server
or
NULL pointer if Confirm
/// message should be discarded by the server.
Pkt6Ptr
processConfirm
(
const
Pkt6Ptr
&
confirm
);
/// @brief
Stub function that will handle
incoming R
ELEASE
message
s
.
/// @brief
Process
incoming R
elease
message.
///
/// @param release message received from client
/// @return Reply message to be sent to the client.
Pkt6Ptr
processRelease
(
const
Pkt6Ptr
&
release
);
/// @brief Stub function that will handle incoming D
ECLINE messages
.
/// @brief Stub function that will handle incoming D
ecline
.
///
/// @param decline message received from client
Pkt6Ptr
processDecline
(
const
Pkt6Ptr
&
decline
);
/// @brief
Stub function that will handle incoming INF-REQUEST
message
s
.
/// @brief
Processes incoming Information-request
message.
///
/// @param infRequest message received from client
Pkt6Ptr
processInfRequest
(
const
Pkt6Ptr
&
infRequest
);
/// @param inf_request message received from client
/// @return Reply message to be sent to the client.
Pkt6Ptr
processInfRequest
(
const
Pkt6Ptr
&
inf_request
);
/// @brief Creates status-code option.
///
...
...
@@ -266,19 +276,17 @@ protected:
/// status code option with non-zero status, denoting cause of the
/// allocation failure.
///
/// @param subnet subnet the client is connected to
/// @param duid client's duid
/// @param query client's message (typically SOLICIT or REQUEST)
/// @param answer server's response to the client's message. This
/// message should contain Client FQDN option being sent by the server
/// to the client (if the client sent this option to the server).
/// @param orig_ctx client context (contains subnet, duid and other parameters)
/// @param ia pointer to client's IA_NA option (client's request)
///
/// @return IA_NA option (server's response)
OptionPtr
assignIA_NA
(
const
isc
::
dhcp
::
Subnet6Ptr
&
subnet
,
const
isc
::
dhcp
::
DuidPtr
&
duid
,
const
isc
::
dhcp
::
Pkt6Ptr
&
query
,
OptionPtr
assignIA_NA
(
const
isc
::
dhcp
::
Pkt6Ptr
&
query
,
const
isc
::
dhcp
::
Pkt6Ptr
&
answer
,
AllocEngine
::
ClientContext6
&
orig_ctx
,
Option6IAPtr
ia
);
/// @brief Processes IA_PD option (and assigns prefixes if necessary).
...
...
@@ -289,13 +297,12 @@ protected:
/// status code option with non-zero status denoting the cause of the
/// allocation failure.
///
/// @param subnet subnet the client is connected to
/// @param duid client's duid
/// @param query client's message (typically SOLICIT or REQUEST)
/// @param orig_ctx client context (contains subnet, duid and other parameters)
/// @param ia pointer to client's IA_PD option (client's request)
/// @return IA_PD option (server's response)
OptionPtr
assignIA_PD
(
const
Subne
t6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
const
Pkt6Ptr
&
query
,
OptionPtr
assignIA_PD
(
const
Pk
t6Ptr
&
query
,
AllocEngine
::
ClientContext6
&
orig_ctx
,
boost
::
shared_ptr
<
Option6IA
>
ia
);
/// @brief Extends lifetime of the specific IA_NA option.
...
...
@@ -323,11 +330,12 @@ protected:
/// @param answer server's response to the client's message. This
/// message should contain Client FQDN option being sent by the server
/// to the client (if the client sent this option to the server).
/// @param orig_ctx client context (contains subnet, duid and other parameters)
/// @param ia IA_NA option which carries adress for which lease lifetime
/// will be extended.
/// @return IA_NA option (server's response)
OptionPtr
extendIA_NA
(
const
Subne
t6Ptr
&
subnet
,
const
Duid
Ptr
&
duid
,
const
Pkt6Ptr
&
query
,
const
Pkt6Ptr
&
answer
,
OptionPtr
extendIA_NA
(
const
Pk
t6Ptr
&
query
,
const
Pkt6
Ptr
&
answer
,
AllocEngine
::
ClientContext6
&
orig_ctx
,
Option6IAPtr
ia
);
/// @brief Extends lifetime of the prefix.
...
...
@@ -341,16 +349,16 @@ protected:
/// is thrown when there is no binding and the Rebind message is processed
/// (see RFC3633, section 12.2. for details).
///
/// @param subnet subnet the sender belongs to
/// @param duid client's duid
/// @param query client's message
/// @param orig_ctx client context (contains subnet, duid and other parameters)
/// @param ia IA_PD option that is being renewed
/// @return IA_PD option (server's response)
/// @throw DHCPv6DiscardMessageError when the message being processed should
/// be discarded by the server, i.e. there is no binding for the client doing
/// Rebind.
OptionPtr
extendIA_PD
(
const
Subnet6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
const
Pkt6Ptr
&
query
,
Option6IAPtr
ia
);
OptionPtr
extendIA_PD
(
const
Pkt6Ptr
&
query
,
AllocEngine
::
ClientContext6
&
orig_ctx
,
Option6IAPtr
ia
);
/// @brief Releases specific IA_NA option
///
...
...
@@ -416,7 +424,9 @@ protected:
///
/// @param question client's message
/// @param answer server's message (options will be added here)
void
appendRequestedOptions
(
const
Pkt6Ptr
&
question
,
Pkt6Ptr
&
answer
);
/// @param ctx client context (contains subnet, duid and other parameters)
void
appendRequestedOptions
(
const
Pkt6Ptr
&
question
,
Pkt6Ptr
&
answer
,
AllocEngine
::
ClientContext6
&
ctx
);
/// @brief Appends requested vendor options to server's answer.
///
...
...
@@ -425,19 +435,22 @@ protected:
///
/// @param question client's message
/// @param answer server's message (vendor options will be added here)
void
appendRequestedVendorOptions
(
const
Pkt6Ptr
&
question
,
Pkt6Ptr
&
answer
);
/// @param ctx client context (contains subnet, duid and other parameters)
void
appendRequestedVendorOptions
(
const
Pkt6Ptr
&
question
,
Pkt6Ptr
&
answer
,
AllocEngine
::
ClientContext6
&
ctx
);
/// @brief Assigns leases.
///
/// It supports addresses (IA_NA) only. It does NOT support temporary
/// addresses (IA_TA) nor prefixes (IA_PD).
/// @todo: Extend this method once TA and PD becomes supported
/// It supports non-temporary addresses (IA_NA) and prefixes (IA_PD). It
/// does NOT support temporary addresses (IA_TA).
///
/// @param question client's message (with requested IA_NA)
/// @param answer server's message (IA_NA options will be added here).
/// This message should contain Client FQDN option being sent by the server
/// to the client (if the client sent this option to the server).
void
assignLeases
(
const
Pkt6Ptr
&
question
,
Pkt6Ptr
&
answer
);
/// @param question client's message (with requested IA options)
/// @param answer server's message (IA options will be added here).
/// This message should contain Client FQDN option being sent by the server
/// to the client (if the client sent this option to the server).
/// @param ctx client context (contains subnet, duid and other parameters)
void
assignLeases
(
const
Pkt6Ptr
&
question
,
Pkt6Ptr
&
answer
,
AllocEngine
::
ClientContext6
&
ctx
);
/// @brief Processes Client FQDN Option.
///
...
...
@@ -453,6 +466,28 @@ protected:
/// domain-name, i.e. if the provided domain-name is partial it should
/// generate the fully qualified domain-name.
///
/// This function takes into account the host reservation if one is matched
/// to this client when forming the FQDN to be used with DNS as well as the
/// lease name to be stored with the lease. In the following the term
/// "reserved hostname" means a host reservation which includes a
/// non-blank hostname.
///
/// - If there is no Client FQDN and no reserved hostname then there
/// will no be DNS updates and the lease hostname will be empty.
///
/// - If there is no Client FQDN but there is reserverd hostname then
/// there will be no DNS updates and the lease hostname will be equal
/// to reserved hostname.
///
/// - If there is a Client FQDN and a reserved hostname, then both the
/// FQDN and lease hostname will be equal to reserved hostname with
/// the qualifying suffix appended.
///
/// - If there is a Client FQDN but no reserverd hostname then both the
/// FQDN and lease hostname will be equal to the name provided in the
/// client FQDN adjusted according the the DhcpDdns configuration
/// parameters (e.g.replace-client-name, qualifying suffix...).
///
/// All the logic required to form appropriate answer to the client is
/// held in this function.
///
...
...
@@ -460,7 +495,9 @@ protected:
/// @param answer Server's response to a client. If server generated
/// Client FQDN option for the client, this option is stored in this
/// object.
void
processClientFqdn
(
const
Pkt6Ptr
&
question
,
const
Pkt6Ptr
&
answer
);
/// @param ctx client context (includes subnet, client-id, hw-addr etc.)
void
processClientFqdn
(
const
Pkt6Ptr
&
question
,
const
Pkt6Ptr
&
answer
,
AllocEngine
::
ClientContext6
&
ctx
);
/// @brief Creates a number of @c isc::dhcp_ddns::NameChangeRequest objects
/// based on the DHCPv6 Client FQDN %Option.
...
...
@@ -507,7 +544,9 @@ protected:
///
/// @param query client's Renew or Rebind message
/// @param reply server's response
void
extendLeases
(
const
Pkt6Ptr
&
query
,
Pkt6Ptr
&
reply
);
/// @param ctx client context (contains subnet, duid and other parameters)
void
extendLeases
(
const
Pkt6Ptr
&
query
,
Pkt6Ptr
&
reply
,
AllocEngine
::
ClientContext6
&
ctx
);
/// @brief Attempts to release received addresses
///
...
...
@@ -518,7 +557,9 @@ protected:
/// to REPLY packet, just its IA_NA containers.
/// @param release client's message asking to release
/// @param reply server's response
void
releaseLeases
(
const
Pkt6Ptr
&
release
,
Pkt6Ptr
&
reply
);
/// @param ctx client context (includes subnet, client-id, hw-addr etc.)
void
releaseLeases
(
const
Pkt6Ptr
&
release
,
Pkt6Ptr
&
reply
,
AllocEngine
::
ClientContext6
&
ctx
);
/// @brief Sets server-identifier.
///
...
...
@@ -616,6 +657,19 @@ protected:
/// - there is no such option provided by the server)
void
processRSOO
(
const
Pkt6Ptr
&
query
,
const
Pkt6Ptr
&
rsp
);
/// @brief Creates client context for specified packet
///
/// Instantiates the ClientContext6 and then:
/// - Performs the subnet selection and stores the result in context
/// - Extracts the duid from the packet and saves it to the context
/// - Extracts the hardware address from the packet and saves it to
/// the context
/// - Performs host reservation lookup and stores the result in the
/// context
///
/// @return client context
AllocEngine
::
ClientContext6
createContext
(
const
Pkt6Ptr
&
pkt
);
/// @brief this is a prefix added to the contend of vendor-class option
///
/// If incoming packet has a vendor class option, its content is
...
...
@@ -683,6 +737,12 @@ private:
const
std
::
string
&
hostname
,
bool
do_fwd
,
bool
do_rev
);
/// @brief Utility method that extracts DUID from client-id option
///
/// @param pkt the message that contains client-id option
/// @return extracted DUID (or NULL if client-id is missing)
DuidPtr
extractClientId
(
const
Pkt6Ptr
&
pkt
);
/// @brief Allocation Engine.
/// Pointer to the allocation engine that we are currently using
/// It must be a pointer, because we will support changing engines
...
...
src/bin/dhcp6/tests/Makefile.am
View file @
c13c824d
...
...
@@ -75,6 +75,7 @@ dhcp6_unittests_SOURCES = dhcp6_unittests.cc
dhcp6_unittests_SOURCES
+=
dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES
+=
fqdn_unittest.cc
dhcp6_unittests_SOURCES
+=
hooks_unittest.cc
dhcp6_unittests_SOURCES
+=
host_unittest.cc
dhcp6_unittests_SOURCES
+=
dhcp6_test_utils.cc dhcp6_test_utils.h
dhcp6_unittests_SOURCES
+=
d2_unittest.cc d2_unittest.h
dhcp6_unittests_SOURCES
+=
marker_file.cc
...
...
src/bin/dhcp6/tests/dhcp6_client.cc
View file @
c13c824d
...
...
@@ -340,6 +340,20 @@ Dhcp6Client::doInfRequest() {
context_
.
response_
=
receiveOneMsg
();
}
void
Dhcp6Client
::
doRenew
()
{
Pkt6Ptr
query
=
createMsg
(
DHCPV6_RENEW
);
query
->
addOption
(
context_
.
response_
->
getOption
(
D6O_SERVERID
));
copyIAsFromLeases
(
query
);
context_
.
query_
=
query
;
sendMsg
(
context_
.
query_
);
context_
.
response_
=
receiveOneMsg
();
// Apply configuration only if the server has responded.
if
(
context_
.
response_
)
{
applyRcvdConfiguration
(
context_
.
response_
);
}
}
void
Dhcp6Client
::
doRebind
()
{
Pkt6Ptr
query
=
createMsg
(
DHCPV6_REBIND
);
...
...
@@ -427,6 +441,12 @@ Dhcp6Client::getLeasesByIAID(const uint32_t iaid) const {
return
(
leases
);
}
void
Dhcp6Client
::
setDUID
(
const
std
::
string
&
str
)
{
DUID
d
=
DUID
::
fromText
(
str
);
duid_
.
reset
(
new
DUID
(
d
));
}
void
Dhcp6Client
::
modifyDUID
()
{
if
(
!
duid_
)
{
...
...
src/bin/dhcp6/tests/dhcp6_client.h
View file @
c13c824d
...
...
@@ -204,6 +204,21 @@ public:
/// @todo Perform sanity checks on returned messages.
void
doSolicit
();
/// @brief Sends a Renew to the server and receives the Reply.
///
/// This function simulates sending the Renew message to the server and
/// receiving server's response (if any). The client uses existing leases
/// (either address or prefixes) and places them in the Renew message.
/// If the server responds to the Renew (and extends the lease lifetimes)
/// the current lease configuration is updated.
///
/// @throw This function doesn't throw exceptions on its own, but it calls
/// functions that are not exception safe, so it may throw exceptions if
/// error occurs.
///
/// @todo Perform sanity checks on returned messages.
void
doRenew
();
/// @brief Sends a Rebind to the server and receives the Reply.
///
/// This function simulates sending the Rebind message to the server and
...
...
@@ -324,6 +339,18 @@ public:
return
(
srv_
);
}
/// @brief Sets the client's DUID from a string value
///
/// Replaces the client's DUID with one constructed from the given
/// string. The string is expected to contain hexadecimal digits with or
/// without ":" separators.
///
/// @param str The string of digits from which to create the DUID
///
/// The DUID modification affects the value returned by the
/// @c Dhcp6Client::getClientId
void
setDUID
(
const
std
::
string
&
duid_str
);
/// @brief Modifies the client's DUID (adds one to it).
///
/// The DUID should be modified to test negative scenarios when the client
...
...
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
View file @
c13c824d
...
...
@@ -2354,4 +2354,5 @@ TEST_F(Dhcpv6SrvTest, rsooOverride) {
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
/// to call processX() methods.
}
// end of anonymous namespace
src/bin/dhcp6/tests/dhcp6_test_utils.h
View file @
c13c824d
...
...
@@ -113,6 +113,7 @@ public:
using
Dhcpv6Srv
::
shutdown_
;
using
Dhcpv6Srv
::
name_change_reqs_
;
using
Dhcpv6Srv
::
VENDOR_CLASS_PREFIX
;
using
Dhcpv6Srv
::
createContext
;
/// @brief packets we pretend to receive
///
...
...
src/bin/dhcp6/tests/fqdn_unittest.cc
View file @
c13c824d
...
...
@@ -24,6 +24,7 @@
#include
<dhcp/option6_iaaddr.h>
#include
<dhcp/option_int_array.h>
#include
<dhcpsrv/lease.h>
#include
<dhcp/tests/iface_mgr_test_config.h>
#include
<dhcp6/tests/dhcp6_test_utils.h>
#include
<boost/pointer_cast.hpp>
...
...
@@ -329,7 +330,8 @@ public:
// Create three IAs, each having different address.
addIA
(
1234
,
IOAddress
(
"2001:db8:1::1"
),
answer
);
ASSERT_NO_THROW
(
srv_
->
processClientFqdn
(
question
,
answer
));
AllocEngine
::
ClientContext6
ctx
;
ASSERT_NO_THROW
(
srv_
->
processClientFqdn
(
question
,
answer
,
ctx
));
Option6ClientFqdnPtr
answ_fqdn
=
boost
::
dynamic_pointer_cast
<
Option6ClientFqdn
>
(
answer
->
getOption
(
D6O_CLIENT_FQDN
));
ASSERT_TRUE
(
answ_fqdn
);
...
...
@@ -393,6 +395,7 @@ public:
const
std
::
string
&
exp_hostname
,
const
uint8_t
client_flags
=
Option6ClientFqdn
::
FLAG_S
,
const
IOAddress
expected_address
=
IOAddress
(
"2001:db8:1:1::dead:beef"
),
const
bool
include_oro
=
true
)
{
// Create a message of a specified type, add server id and
// FQDN option.
...
...
@@ -440,7 +443,7 @@ public:
ASSERT_TRUE
(
addr
);
// Check that we have got the address we requested.
checkIAAddr
(
addr
,
IOAddress
(
"2001:db8:1:1::dead:beef"
)
,
checkIAAddr
(
addr
,
expected_address
,
Lease
::
TYPE_NA
);
if
(
msg_type
!=
DHCPV6_SOLICIT
)
{
...
...
@@ -482,12 +485,15 @@ public:
/// NameChangeRequest expires.
/// @param len A valid lifetime of the lease associated with the
/// NameChangeRequest.
/// @param fqdn The expected string value of the FQDN, if blank the
/// check is skipped
void
verifyNameChangeRequest
(
const
isc
::
dhcp_ddns
::
NameChangeType
type
,
const
bool
reverse
,
const
bool
forward
,
const
std
::
string
&
addr
,
const
std
::
string
&
dhcid
,
const
uint16_t
expires
,
const
uint16_t
len
)
{
const
uint16_t
len
,
const
std
::
string
&
fqdn
=
""
)
{
NameChangeRequestPtr
ncr
;
ASSERT_NO_THROW
(
ncr
=
d2_mgr_
.
peekAt
(
0
));
ASSERT_TRUE
(
ncr
);
...
...
@@ -501,10 +507,40 @@ public:
EXPECT_EQ
(
len
,
ncr
->
getLeaseLength
());
EXPECT_EQ
(
isc
::
dhcp_ddns
::
ST_NEW
,
ncr
->
getStatus
());
if
(
!
fqdn
.
empty
())
{
EXPECT_EQ
(
fqdn
,
ncr
->
getFqdn
());
}
// Process the message off the queue
ASSERT_NO_THROW
(
d2_mgr_
.
runReadyIO
());
}
/// @brief Updates inherited subnet and pool members
///
/// Hack added to set subnet_ and pool_ members that are buried into lower
/// level tests such as checkLease(), so one can use "configure" functionality
/// rather than hand-building configured objects
/// @param subnet_idx Element index of the desired subnet
/// @param pool_idx Element index of the desired pool within the desired subnet
/// @param type lease type of desired pool
///
void
setSubnetAndPool
(
int
subnet_idx
,
int
pool_idx
,
Lease
::
Type
type
)
{
ConstCfgSubnets6Ptr
subnets
=
CfgMgr
::
instance
().
getCurrentCfg
()
->
getCfgSubnets6
();
ASSERT_TRUE
(
subnets
);
const
Subnet6Collection
*
subnet_col
=
subnets
->
getAll
();
ASSERT_EQ
(
subnet_idx
+
1
,
subnet_col
->
size
());
subnet_
=
subnet_col
->
at
(
subnet_idx
);
ASSERT_TRUE
(
subnet_
);
const
PoolCollection
&
pool_col
=
subnet_
->
getPools
(
type
);
ASSERT_EQ
(
pool_idx
+
1
,
pool_col
.
size
());
PoolPtr
pool
=
(
subnet_
->
getPools
(
type
)).
at
(
pool_idx
);
ASSERT_TRUE
(
pool
);
pool_
=
boost
::
dynamic_pointer_cast
<
Pool6
>
(
pool
);
ASSERT_TRUE
(
pool
);
}
// Holds a lease used by a test.
Lease6Ptr
lease_
;
...
...
@@ -943,7 +979,8 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestWithoutFqdn) {
// In this case, we expect that the FQDN option will not be included
// in the server's response. The testProcessMessage will check that.
testProcessMessage
(
DHCPV6_REQUEST
,
"myhost.example.com"
,
"myhost.example.com."
,
Option6ClientFqdn
::
FLAG_S
,
false
);
"myhost.example.com."
,
Option6ClientFqdn
::
FLAG_S
,
IOAddress
(
"2001:db8:1:1::dead:beef"
),
false
);
ASSERT_EQ
(
1
,
d2_mgr_
.
getQueueSize
());
verifyNameChangeRequest
(
isc
::
dhcp_ddns
::
CHG_ADD
,
true
,
true
,
"2001:db8:1:1::dead:beef"
,
...
...
@@ -957,7 +994,8 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestWithoutFqdn) {
TEST_F
(
FqdnDhcpv6SrvTest
,
processRequestEmptyFqdn
)
{
testProcessMessage
(
DHCPV6_REQUEST
,
""
,
"myhost-2001-db8-1-1--dead-beef.example.com."
,
Option6ClientFqdn
::
FLAG_S
,
false
);
Option6ClientFqdn
::
FLAG_S
,
IOAddress
(
"2001:db8:1:1::dead:beef"
),
false
);
ASSERT_EQ
(
1
,
d2_mgr_
.
getQueueSize
());
verifyNameChangeRequest
(
isc
::
dhcp_ddns
::
CHG_ADD
,
true
,
true
,
"2001:db8:1:1::dead:beef"
,
...
...
@@ -1050,5 +1088,151 @@ TEST_F(FqdnDhcpv6SrvTest, processClientDelegation) {
0
,
4000
);
}
// Verify that the host reservation is found and used. Lease host name and
// FQDN should be the reservation hostname suffixed by the qualifying suffix.
TEST_F
(
FqdnDhcpv6SrvTest
,
hostnameReservationSuffix
)
{
isc
::
dhcp
::
test
::
IfaceMgrTestConfig
test_config
(
true
);
string
config_str
=
"{ "
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
valid-lifetime
\"
: 4000, "
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet6
\"
: [ "
" { "
"
\"
subnet
\"
:
\"
2001:db8:1::/48
\"
, "
"
\"
pools
\"
: [ {
\"
pool
\"
:
\"
2001:db8:1:1::/64
\"
} ],"
"
\"
interface
\"
:
\"
eth0
\"
, "
"
\"
reservations
\"
: ["
" {"
"
\"
duid
\"
:
\"
"
+
duid_
->
toText
()
+
"
\"
,"
"
\"
ip-addresses
\"
: [
\"
2001:db8:1:1::babe
\"
],"
"
\"
hostname
\"
:
\"
alice
\"
"
" }"
" ]"
" } ],"
"
\"
dhcp-ddns
\"
: {"
"
\"
enable-updates
\"
: true, "
"
\"
qualifying-suffix
\"
:
\"
example.com
\"
}"
"}"
;
configure
(
config_str
);
// Update subnet_ and pool_ members after config
setSubnetAndPool
(
0
,
0
,
Lease
::
TYPE_NA
);