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
Adam Osuchowski
Kea
Commits
22c667a6
Commit
22c667a6
authored
Feb 20, 2014
by
Thomas Markwalder
Browse files
[master] Merge branch 'trac3034'
b10-dhcp6 parses and uses ddns-dhcp configuration
parents
a3e73038
fbcacb9e
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/config_parser.cc
View file @
22c667a6
...
...
@@ -640,6 +640,8 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
parser
=
new
DbAccessParser
(
config_id
);
}
else
if
(
config_id
.
compare
(
"hooks-libraries"
)
==
0
)
{
parser
=
new
HooksLibrariesParser
(
config_id
);
}
else
if
(
config_id
.
compare
(
"dhcp-ddns"
)
==
0
)
{
parser
=
new
D2ClientConfigParser
(
config_id
);
}
else
{
isc_throw
(
NotImplemented
,
"Parser error: Global configuration parameter not supported: "
...
...
src/bin/dhcp6/dhcp6.spec
View file @
22c667a6
...
...
@@ -352,7 +352,94 @@
}
} ]
}
}
},
{ "item_name": "dhcp-ddns",
"item_type": "map",
"item_optional": false,
"item_default": {"enable-updates": false},
"item_description" : "Contains parameters pertaining DHCP-driven DDNS updates",
"map_item_spec": [
{
"item_name": "enable-updates",
"item_type": "boolean",
"item_optional": false,
"item_default": false,
"item_description" : "Enables DDNS update processing"
},
{
"item_name": "server-ip",
"item_type": "string",
"item_optional": true,
"item_default": "127.0.0.1",
"item_description" : "IP address of b10-dhcp-ddns (IPv4 or IPv6)"
},
{
"item_name": "server-port",
"item_type": "integer",
"item_optional": true,
"item_default": 53001,
"item_description" : "port number of b10-dhcp-ddns"
},
{
"item_name": "ncr-protocol",
"item_type": "string",
"item_optional": true,
"item_default": "UDP",
"item_description" : "Socket protocol to use with b10-dhcp-ddns"
},
{
"item_name": "ncr-format",
"item_type": "string",
"item_optional": true,
"item_default": "JSON",
"item_description" : "Format of the update request packet"
},
{
"item_name": "always-include-fqdn",
"item_type": "boolean",
"item_optional": true,
"item_default": false,
"item_description": "Enable always including the FQDN option in its response"
},
{
"item_name": "override-no-update",
"item_type": "boolean",
"item_optional": true,
"item_default": false,
"item_description": "Do update, even if client requested no updates with N flag"
},
{
"item_name": "override-client-update",
"item_type": "boolean",
"item_optional": true,
"item_default": false,
"item_description": "Server performs an update even if client requested delegation"
},
{
"item_name": "replace-client-name",
"item_type": "boolean",
"item_optional": true,
"item_default": false,
"item_description": "Should server replace the domain-name supplied by the client"
},
{
"item_name": "generated-prefix",
"item_type": "string",
"item_optional": true,
"item_default": "myhost",
"item_description": "Prefix to use when generating the client's name"
},
{
"item_name": "qualifying-suffix",
"item_type": "string",
"item_optional": true,
"item_default": "example.com",
"item_description": "Fully qualified domain-name suffix if partial name provided by client"
},
]
},
],
"commands": [
{
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
22c667a6
...
...
@@ -102,31 +102,6 @@ namespace dhcp {
const
std
::
string
Dhcpv6Srv
::
VENDOR_CLASS_PREFIX
(
"VENDOR_CLASS_"
);
namespace
{
// The following constants describe server's behavior with respect to the
// DHCPv6 Client FQDN Option sent by a client. They will be removed
// when DDNS parameters for DHCPv6 are implemented with the ticket #3034.
// Enable AAAA RR update delegation to the client (Disabled).
const
bool
FQDN_ALLOW_CLIENT_UPDATE
=
false
;
// Globally enable updates (Enabled).
const
bool
FQDN_ENABLE_UPDATE
=
true
;
// The partial name generated for the client if empty name has been
// supplied.
const
char
*
FQDN_GENERATED_PARTIAL_NAME
=
"myhost"
;
// Do update, even if client requested no updates with N flag (Disabled).
const
bool
FQDN_OVERRIDE_NO_UPDATE
=
false
;
// Server performs an update when client requested delegation (Enabled).
const
bool
FQDN_OVERRIDE_CLIENT_UPDATE
=
true
;
// The fully qualified domain-name suffix if partial name provided by
// a client.
const
char
*
FQDN_PARTIAL_SUFFIX
=
"example.com"
;
// Should server replace the domain-name supplied by the client (Disabled).
const
bool
FQDN_REPLACE_CLIENT_NAME
=
false
;
}
/// @brief file name of a server-id file
///
/// Server must store its duid in persistent storage that must not change
...
...
@@ -1016,69 +991,18 @@ Dhcpv6Srv::processClientFqdn(const Pkt6Ptr& question, const Pkt6Ptr& answer) {
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_DETAIL
,
DHCP6_DDNS_RECEIVE_FQDN
).
arg
(
fqdn
->
toText
());
// Prepare the FQDN option which will be included in the response to
// the client.
// Create the DHCPv6 Client FQDN Option to be included in the server's
// response to a client.
Option6ClientFqdnPtr
fqdn_resp
(
new
Option6ClientFqdn
(
*
fqdn
));
// RFC 4704, section 6. - all flags set to 0.
fqdn_resp
->
resetFlags
();
// Conditions when N flag has to be set to indicate that server will not
// perform DNS updates:
// 1. Updates are globally disabled,
// 2. Client requested no update and server respects it,
// 3. Client requested that the AAAA update is delegated to the client but
// server neither respects delegation of updates nor it is configured
// to send update on its own when client requested delegation.
if
(
!
FQDN_ENABLE_UPDATE
||
(
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_N
)
&&
!
FQDN_OVERRIDE_NO_UPDATE
)
||
(
!
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
)
&&
!
FQDN_ALLOW_CLIENT_UPDATE
&&
!
FQDN_OVERRIDE_CLIENT_UPDATE
))
{
fqdn_resp
->
setFlag
(
Option6ClientFqdn
::
FLAG_N
,
true
);
// Conditions when S flag is set to indicate that server will perform
// DNS update on its own:
// 1. Client requested that server performs DNS update and DNS updates are
// globally enabled
// 2. Client requested that server delegates AAAA update to the client but
// server doesn't respect delegation and it is configured to perform
// an update on its own when client requested delegation.
}
else
if
(
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
)
||
(
!
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
)
&&
!
FQDN_ALLOW_CLIENT_UPDATE
&&
FQDN_OVERRIDE_CLIENT_UPDATE
))
{
fqdn_resp
->
setFlag
(
Option6ClientFqdn
::
FLAG_S
,
true
);
}
// Server MUST set the O flag if it has overridden the client's setting
// of S flag.
if
(
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
)
!=
fqdn_resp
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
))
{
fqdn_resp
->
setFlag
(
Option6ClientFqdn
::
FLAG_O
,
true
);
}
// If client supplied partial or empty domain-name, server should
// generate one.
if
(
fqdn
->
getDomainNameType
()
==
Option6ClientFqdn
::
PARTIAL
)
{
std
::
ostringstream
name
;
if
(
fqdn
->
getDomainName
().
empty
()
||
FQDN_REPLACE_CLIENT_NAME
)
{
fqdn
->
setDomainName
(
""
,
Option6ClientFqdn
::
PARTIAL
);
}
else
{
name
<<
fqdn
->
getDomainName
();
name
<<
"."
<<
FQDN_PARTIAL_SUFFIX
;
fqdn_resp
->
setDomainName
(
name
.
str
(),
Option6ClientFqdn
::
FULL
);
}
// Server may be configured to replace a name supplied by a client,
// even if client supplied fully qualified domain-name.
}
else
if
(
FQDN_REPLACE_CLIENT_NAME
)
{
std
::
ostringstream
name
;
name
<<
FQDN_GENERATED_PARTIAL_NAME
<<
"."
<<
FQDN_PARTIAL_SUFFIX
;
fqdn_resp
->
setDomainName
(
name
.
str
(),
Option6ClientFqdn
::
FULL
);
// Set the server S, N, and O flags based on client's flags and
// current configuration.
D2ClientMgr
&
d2_mgr
=
CfgMgr
::
instance
().
getD2ClientMgr
();
d2_mgr
.
adjustFqdnFlags
<
Option6ClientFqdn
>
(
*
fqdn
,
*
fqdn_resp
);
}
// Adjust the domain name based on domain name value and type sent by the
// client and current configuration.
d2_mgr
.
adjustDomainName
<
Option6ClientFqdn
>
(
*
fqdn
,
*
fqdn_resp
);
// The FQDN has been processed successfully. Let's append it to the
// response to be sent to a client. Note that the Client FQDN option is
...
...
@@ -1090,7 +1014,7 @@ Dhcpv6Srv::processClientFqdn(const Pkt6Ptr& question, const Pkt6Ptr& answer) {
void
Dhcpv6Srv
::
createNameChangeRequests
(
const
Pkt6Ptr
&
answer
)
{
// Don't create NameChangeRequests if DNS updates are disabled.
if
(
!
FQDN_ENABLE_UPDATE
)
{
if
(
!
CfgMgr
::
instance
().
ddnsEnabled
()
)
{
return
;
}
...
...
@@ -1177,7 +1101,7 @@ Dhcpv6Srv::createNameChangeRequests(const Pkt6Ptr& answer) {
void
Dhcpv6Srv
::
createRemovalNameChangeRequest
(
const
Lease6Ptr
&
lease
)
{
// Don't create NameChangeRequests if DNS updates are disabled.
if
(
!
FQDN_ENABLE_UPDATE
)
{
if
(
!
CfgMgr
::
instance
().
ddnsEnabled
()
)
{
return
;
}
...
...
@@ -1299,14 +1223,11 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
Option6ClientFqdnPtr
fqdn
=
boost
::
dynamic_pointer_cast
<
Option6ClientFqdn
>
(
answer
->
getOption
(
D6O_CLIENT_FQDN
));
if
(
fqdn
)
{
// Flag S must not coexist with flag N being set to 1, so if S=1
// server takes responsibility for both reverse and forward updates.
// Otherwise, we have to check N.
/// @todo For now, we assert that if we are doing forward we are also
/// doing reverse.
if
(
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
))
{
do_fwd
=
true
;
do_rev
=
true
;
}
else
if
(
!
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_N
))
{
do_rev
=
true
;
}
}
// Set hostname only in case any of the updates is being performed.
...
...
@@ -1557,11 +1478,11 @@ Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
Option6ClientFqdnPtr
fqdn
=
boost
::
dynamic_pointer_cast
<
Option6ClientFqdn
>
(
answer
->
getOption
(
D6O_CLIENT_FQDN
));
if
(
fqdn
)
{
// For now, we assert that if we are doing forward we are also
// doing reverse.
if
(
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_S
))
{
do_fwd
=
true
;
do_rev
=
true
;
}
else
if
(
!
fqdn
->
getFlag
(
Option6ClientFqdn
::
FLAG_N
))
{
do_rev
=
true
;
}
}
...
...
@@ -2501,17 +2422,8 @@ Dhcpv6Srv::generateFqdn(const Pkt6Ptr& answer) {
}
// Get the IPv6 address acquired by the client.
IOAddress
addr
=
iaaddr
->
getAddress
();
std
::
string
hostname
=
addr
.
toText
();
// Colons may not be ok for FQDNs so let's replace them with hyphens.
std
::
replace
(
hostname
.
begin
(),
hostname
.
end
(),
':'
,
'-'
);
std
::
ostringstream
stream
;
// The final FQDN consists of the partial domain name and the suffix.
// For example, if the acquired address is 2001:db8:1::2, the generated
// FQDN may be:
// host-2001-db8:1--2.example.com.
// where prefix 'host' should be configurable. The domain name suffix
// should also be configurable.
stream
<<
"host-"
<<
hostname
<<
"."
<<
FQDN_PARTIAL_SUFFIX
<<
"."
;
std
::
string
generated_name
=
CfgMgr
::
instance
().
getD2ClientMgr
().
generateFqdn
(
addr
);
try
{
// The lease has been acquired but the FQDN for this lease hasn't
// been updated in the lease database. We now have new FQDN
...
...
@@ -2522,7 +2434,7 @@ Dhcpv6Srv::generateFqdn(const Pkt6Ptr& answer) {
Lease6Ptr
lease
=
LeaseMgrFactory
::
instance
().
getLease6
(
Lease
::
TYPE_NA
,
addr
);
if
(
lease
)
{
lease
->
hostname_
=
stream
.
str
()
;
lease
->
hostname_
=
generated_name
;
LeaseMgrFactory
::
instance
().
updateLease6
(
lease
);
}
else
{
...
...
@@ -2533,13 +2445,12 @@ Dhcpv6Srv::generateFqdn(const Pkt6Ptr& answer) {
" client"
);
}
}
// Set the generated FQDN in the Client FQDN option.
fqdn
->
setDomainName
(
stream
.
str
()
,
Option6ClientFqdn
::
FULL
);
fqdn
->
setDomainName
(
generated_name
,
Option6ClientFqdn
::
FULL
);
}
catch
(
const
Exception
&
ex
)
{
LOG_ERROR
(
dhcp6_logger
,
DHCP6_NAME_GEN_UPDATE_FAIL
)
.
arg
(
hostname
)
.
arg
(
addr
.
toText
()
)
.
arg
(
ex
.
what
());
}
}
...
...
src/bin/dhcp6/dhcp6_srv.h
View file @
22c667a6
...
...
@@ -405,6 +405,7 @@ protected:
/// objects and store them in the internal queue. Requests created by this
/// function are only adding or updating DNS records. In order to generate
/// requests for DNS records removal, use @c createRemovalNameChangeRequest.
/// If ddns updates are disabled, this method returns immediately.
///
/// @todo Add support for multiple IAADDR options in the IA_NA.
///
...
...
@@ -422,6 +423,7 @@ protected:
/// Note that this function will not remove the entries which server hadn't
/// added. This is the case, when client performs forward DNS update on its
/// own.
/// If ddns updates are disabled, this method returns immediately.
///
/// @param lease A lease for which the the removal of corresponding DNS
/// records will be performed.
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
22c667a6
...
...
@@ -347,6 +347,7 @@ public:
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000, "
"
\"
subnet6
\"
: [ ], "
"
\"
dhcp-ddns
\"
: {
\"
enable-updates
\"
: false }, "
"
\"
option-def
\"
: [ ], "
"
\"
option-data
\"
: [ ] }"
;
static_cast
<
void
>
(
executeConfiguration
(
config
,
...
...
@@ -3091,5 +3092,113 @@ TEST_F(Dhcp6ParserTest, classifySubnets) {
EXPECT_TRUE
(
subnets
->
at
(
3
)
->
clientSupported
(
classes
));
}
// This test checks the ability of the server to parse a configuration
// containing a full, valid dhcp-ddns (D2ClientConfig) entry.
TEST_F
(
Dhcp6ParserTest
,
d2ClientConfig
)
{
ConstElementPtr
status
;
// Verify that the D2 configuraiton can be fetched and is set to disabled.
D2ClientConfigPtr
d2_client_config
=
CfgMgr
::
instance
().
getD2ClientConfig
();
EXPECT_FALSE
(
d2_client_config
->
getEnableUpdates
());
// Verify that the convenience method agrees.
ASSERT_FALSE
(
CfgMgr
::
instance
().
ddnsEnabled
());
string
config_str
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet6
\"
: [ { "
"
\"
pool
\"
: [
\"
2001:db8:1::/80
\"
],"
"
\"
subnet
\"
:
\"
2001:db8:1::/64
\"
} ], "
"
\"
dhcp-ddns
\"
: {"
"
\"
enable-updates
\"
: true, "
"
\"
server-ip
\"
:
\"
192.168.2.1
\"
, "
"
\"
server-port
\"
: 777, "
"
\"
ncr-protocol
\"
:
\"
UDP
\"
, "
"
\"
ncr-format
\"
:
\"
JSON
\"
, "
"
\"
always-include-fqdn
\"
: true, "
"
\"
allow-client-update
\"
: true, "
"
\"
override-no-update
\"
: true, "
"
\"
override-client-update
\"
: true, "
"
\"
replace-client-name
\"
: true, "
"
\"
generated-prefix
\"
:
\"
test.prefix
\"
, "
"
\"
qualifying-suffix
\"
:
\"
test.suffix.
\"
},"
"
\"
valid-lifetime
\"
: 4000 }"
;
// Convert the JSON string to configuration elements.
ElementPtr
config
;
ASSERT_NO_THROW
(
config
=
Element
::
fromJSON
(
config_str
));
// Pass the configuration in for parsing.
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
config
));
// check if returned status is OK
checkResult
(
status
,
0
);
// Verify that DHCP-DDNS updating is enabled.
EXPECT_TRUE
(
CfgMgr
::
instance
().
ddnsEnabled
());
// Verify that the D2 configuration can be retrieved.
d2_client_config
=
CfgMgr
::
instance
().
getD2ClientConfig
();
ASSERT_TRUE
(
d2_client_config
);
// Verify that the configuration values are correct.
EXPECT_TRUE
(
d2_client_config
->
getEnableUpdates
());
EXPECT_EQ
(
"192.168.2.1"
,
d2_client_config
->
getServerIp
().
toText
());
EXPECT_EQ
(
777
,
d2_client_config
->
getServerPort
());
EXPECT_EQ
(
dhcp_ddns
::
NCR_UDP
,
d2_client_config
->
getNcrProtocol
());
EXPECT_EQ
(
dhcp_ddns
::
FMT_JSON
,
d2_client_config
->
getNcrFormat
());
EXPECT_TRUE
(
d2_client_config
->
getAlwaysIncludeFqdn
());
EXPECT_TRUE
(
d2_client_config
->
getOverrideNoUpdate
());
EXPECT_TRUE
(
d2_client_config
->
getOverrideClientUpdate
());
EXPECT_TRUE
(
d2_client_config
->
getReplaceClientName
());
EXPECT_EQ
(
"test.prefix"
,
d2_client_config
->
getGeneratedPrefix
());
EXPECT_EQ
(
"test.suffix."
,
d2_client_config
->
getQualifyingSuffix
());
}
// This test checks the ability of the server to handle a configuration
// containing an invalid dhcp-ddns (D2ClientConfig) entry.
TEST_F
(
Dhcp6ParserTest
,
invalidD2ClientConfig
)
{
ConstElementPtr
status
;
// Configuration string with an invalid D2 client config,
// "server-ip" is missing.
string
config_str
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet6
\"
: [ { "
"
\"
pool
\"
: [
\"
2001:db8:1::/80
\"
],"
"
\"
subnet
\"
:
\"
2001:db8:1::/64
\"
} ], "
"
\"
dhcp-ddns
\"
: {"
"
\"
enable-updates
\"
: true, "
"
\"
server-port
\"
: 5301, "
"
\"
ncr-protocol
\"
:
\"
UDP
\"
, "
"
\"
ncr-format
\"
:
\"
JSON
\"
, "
"
\"
always-include-fqdn
\"
: true, "
"
\"
allow-client-update
\"
: true, "
"
\"
override-no-update
\"
: true, "
"
\"
override-client-update
\"
: true, "
"
\"
replace-client-name
\"
: true, "
"
\"
generated-prefix
\"
:
\"
test.prefix
\"
, "
"
\"
qualifying-suffix
\"
:
\"
test.suffix.
\"
},"
"
\"
valid-lifetime
\"
: 4000 }"
;
// Convert the JSON string to configuration elements.
ElementPtr
config
;
ASSERT_NO_THROW
(
config
=
Element
::
fromJSON
(
config_str
));
// Configuration should not throw, but should fail.
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
config
));
// check if returned status is failed.
checkResult
(
status
,
1
);
// Verify that the D2 configuraiton can be fetched and is set to disabled.
D2ClientConfigPtr
d2_client_config
=
CfgMgr
::
instance
().
getD2ClientConfig
();
EXPECT_FALSE
(
d2_client_config
->
getEnableUpdates
());
// Verify that the convenience method agrees.
ASSERT_FALSE
(
CfgMgr
::
instance
().
ddnsEnabled
());
}
};
src/bin/dhcp6/tests/fqdn_unittest.cc
View file @
22c667a6
...
...
@@ -43,20 +43,63 @@ namespace {
/// @brief A test fixture class for testing DHCPv6 Client FQDN Option handling.
class
FqdnDhcpv6SrvTest
:
public
Dhcpv6SrvTest
{
public:
// Reference to D2ClientMgr singleton
D2ClientMgr
&
d2_mgr_
;
// Bit Constants for turning on and off DDNS configuration options.
// (Defined here as these are only meaningful to this class.)
static
const
uint16_t
ALWAYS_INCLUDE_FQDN
=
1
;
static
const
uint16_t
OVERRIDE_NO_UPDATE
=
2
;
static
const
uint16_t
OVERRIDE_CLIENT_UPDATE
=
4
;
static
const
uint16_t
REPLACE_CLIENT_NAME
=
8
;
/// @brief Constructor
FqdnDhcpv6SrvTest
()
:
Dhcpv6SrvTest
()
{
:
Dhcpv6SrvTest
()
,
d2_mgr_
(
CfgMgr
::
instance
().
getD2ClientMgr
())
{
// generateClientId assigns DUID to duid_.
generateClientId
();
lease_
.
reset
(
new
Lease6
(
Lease
::
TYPE_NA
,
IOAddress
(
"2001:db8:1::1"
),
duid_
,
1234
,
501
,
502
,
503
,
504
,
1
,
0
));
// Config DDNS to be enabled, all controls off
enableD2
();
}
/// @brief Destructor
virtual
~
FqdnDhcpv6SrvTest
()
{
// Default constructor creates a config with DHCP-DDNS updates
// disabled.
D2ClientConfigPtr
cfg
(
new
D2ClientConfig
());
CfgMgr
::
instance
().
setD2ClientConfig
(
cfg
);
}
/// @brief Sets the server's DDNS configuration to ddns updates disabled.
void
disableD2
()
{
// Default constructor creates a config with DHCP-DDNS updates
// disabled.
D2ClientConfigPtr
cfg
(
new
D2ClientConfig
());
CfgMgr
::
instance
().
setD2ClientConfig
(
cfg
);
}
/// @brief Enables DHCP-DDNS updates with the given options enabled.
///
/// Replaces the current D2ClientConfiguration with a configuration
/// which as updates enabled and the control options set based upon
/// the bit mask of options.
///
/// @param mask Bit mask of configuration options that should be enabled.
void
enableD2
(
const
uint16_t
mask
=
0
)
{
D2ClientConfigPtr
cfg
;
ASSERT_NO_THROW
(
cfg
.
reset
(
new
D2ClientConfig
(
true
,
isc
::
asiolink
::
IOAddress
(
"127.0.0.1"
),
53001
,
dhcp_ddns
::
NCR_UDP
,
dhcp_ddns
::
FMT_JSON
,
(
mask
&
ALWAYS_INCLUDE_FQDN
),
(
mask
&
OVERRIDE_NO_UPDATE
),
(
mask
&
OVERRIDE_CLIENT_UPDATE
),
(
mask
&
REPLACE_CLIENT_NAME
),
"myhost"
,
"example.com"
)));
ASSERT_NO_THROW
(
CfgMgr
::
instance
().
setD2ClientConfig
(
cfg
));
}
/// @brief Construct the DHCPv6 Client FQDN option using flags and
...
...
@@ -376,6 +419,13 @@ public:
/// @param addr A string representation of the IPv6 address held in the
/// NameChangeRequest.
/// @param dhcid An expected DHCID value.
/// @note This value is the value that is produced by
/// dhcp_ddns::D2Dhcid::crateDigest() with the appropriate arguments. This
/// method uses encryption tools to produce the value which cannot be
/// easily duplicated by hand. It is more or less necessary to generate
/// these values programmatically and place them here. Should the
/// underlying implementation of createDigest() change these test values
/// will likely need to be updated as well.
/// @param expires A timestamp when the lease associated with the
/// NameChangeRequest expires.
/// @param len A valid lifetime of the lease associated with the
...
...
@@ -443,6 +493,7 @@ TEST_F(FqdnDhcpv6SrvTest, noUpdate) {
// Test server's response when client requests that server delegates the AAAA
// update to the client and this delegation is not allowed.
TEST_F
(
FqdnDhcpv6SrvTest
,
clientAAAAUpdateNotAllowed
)
{
enableD2
(
OVERRIDE_CLIENT_UPDATE
);
testFqdn
(
DHCPV6_SOLICIT
,
0
,
"myhost.example.com."
,
Option6ClientFqdn
::
FULL
,
Option6ClientFqdn
::
FLAG_S
|
Option6ClientFqdn
::
FLAG_O
,
...
...
@@ -545,6 +596,34 @@ TEST_F(FqdnDhcpv6SrvTest, createNameChangeRequests) {
}
// Checks that NameChangeRequests to add entries are not
// created when ddns updates are disabled.
TEST_F
(
FqdnDhcpv6SrvTest
,
noAddRequestsWhenDisabled
)
{
NakedDhcpv6Srv
srv
(
0
);
// Disable DDNS udpates.
disableD2
();
// Create Reply message with Client Id and Server id.
Pkt6Ptr
answer
=
generateMessageWithIds
(
DHCPV6_REPLY
,
srv
);
// Create three IAs, each having different address.
addIA
(
1234
,
IOAddress
(
"2001:db8:1::1"
),
answer
);
// Use domain name in upper case. It should be converted to lower-case
// before DHCID is calculated. So, we should get the same result as if
// we typed domain name in lower-case.
Option6ClientFqdnPtr
fqdn
=
createClientFqdn
(
Option6ClientFqdn
::
FLAG_S
,
"MYHOST.EXAMPLE.COM"
,
Option6ClientFqdn
::
FULL
);
answer
->
addOption
(
fqdn
);
// Create NameChangeRequest for the first allocated address.
ASSERT_NO_THROW
(
srv
.
createNameChangeRequests
(
answer
));
ASSERT_TRUE
(
srv
.
name_change_reqs_
.
empty
());
}
// Test creation of the NameChangeRequest to remove both forward and reverse
// mapping for the given lease.
TEST_F
(
FqdnDhcpv6SrvTest
,
createRemovalNameChangeRequestFwdRev
)
{
...
...
@@ -569,6 +648,27 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestFwdRev) {
}
// Checks that NameChangeRequests to remove entries are not created
// when ddns updates are disabled.
TEST_F
(
FqdnDhcpv6SrvTest
,
noRemovalsWhenDisabled
)
{
NakedDhcpv6Srv
srv
(
0
);
// Disable DDNS updates.
disableD2
();
lease_
->
fqdn_fwd_
=
true
;
lease_
->
fqdn_rev_
=
true
;
// Part of the domain name is in upper case, to test that it gets converted
// to lower case before DHCID is computed. So, we should get the same DHCID
// as if we typed domain-name in lower case.
lease_
->
hostname_
=
"MYHOST.example.com."
;
ASSERT_NO_THROW
(
srv
.
createRemovalNameChangeRequest
(
lease_
));
ASSERT_TRUE
(
srv
.
name_change_reqs_
.
empty
());
}
// Test creation of the NameChangeRequest to remove reverse mapping for the
// given lease.
TEST_F
(
FqdnDhcpv6SrvTest
,
createRemovalNameChangeRequestRev
)
{
...
...
@@ -821,13 +921,13 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestEmptyFqdn) {
NakedDhcpv6Srv
srv
(
0
);
testProcessMessage
(
DHCPV6_REQUEST
,
""
,
"host-2001-db8-1-1--dead-beef.example.com."
,
"
my
host-2001-db8-1-1--dead-beef.example.com."
,
srv
,
false
);
ASSERT_EQ
(
1
,
srv
.
name_change_reqs_
.
size
());
verifyNameChangeRequest
(
srv
,
isc
::
dhcp_ddns
::
CHG_ADD
,
true
,
true
,
"2001:db8:1:1::dead:beef"
,
"000201
8D6874B105A5C92DBBD6E4F6C80A93161
"
"
BC03996F0CD0EB75800DEF997C29961
"
,
"000201
C905E54BE12DE6AF92ADE72752B9F362
"
"
13B5A8BC9D217548CD739B4CF31AFB1B
"
,
0
,
4000
);
}
...
...
Write
Preview
Supports
Markdown