mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 05:27:55 +00:00
[#2819] kea-dhcp4 supports ddns-ttl, min, and max
Added support for ddns-ttl,ddns-ttl-min, and ddsn-ttl-max to global,shared-network, and subnet for kea-dhcp4 Changes to be committed: modified: doc/examples/kea4/all-keys.json modified: src/bin/dhcp4/dhcp4_lexer.cc modified: src/bin/dhcp4/dhcp4_lexer.ll modified: src/bin/dhcp4/dhcp4_parser.cc modified: src/bin/dhcp4/dhcp4_parser.h modified: src/bin/dhcp4/dhcp4_parser.yy modified: src/bin/dhcp4/json_config_parser.cc modified: src/bin/dhcp4/tests/config_parser_unittest.cc modified: src/bin/dhcp4/tests/fqdn_unittest.cc modified: src/bin/dhcp4/tests/get_config_unittest.cc modified: src/bin/dhcp6/json_config_parser.cc modified: src/lib/dhcpsrv/cb_ctl_dhcp4.cc modified: src/lib/dhcpsrv/cb_ctl_dhcp6.cc modified: src/lib/dhcpsrv/cfg_globals.cc modified: src/lib/dhcpsrv/cfg_globals.h modified: src/lib/dhcpsrv/dhcpsrv_messages.cc modified: src/lib/dhcpsrv/dhcpsrv_messages.h modified: src/lib/dhcpsrv/dhcpsrv_messages.mes modified: src/lib/dhcpsrv/ncr_generator.cc modified: src/lib/dhcpsrv/ncr_generator.h modified: src/lib/dhcpsrv/network.cc modified: src/lib/dhcpsrv/network.h modified: src/lib/dhcpsrv/parsers/base_network_parser.cc modified: src/lib/dhcpsrv/parsers/simple_parser4.cc modified: src/lib/dhcpsrv/parsers/simple_parser6.cc modified: src/lib/dhcpsrv/srv_config.cc modified: src/lib/dhcpsrv/srv_config.h modified: src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc modified: src/lib/dhcpsrv/tests/ncr_generator_unittest.cc modified: src/lib/dhcpsrv/tests/network_unittest.cc modified: src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc modified: src/lib/dhcpsrv/tests/srv_config_unittest.cc modified: src/lib/util/str.cc modified: src/lib/util/str.h
This commit is contained in:
parent
f4a25f1776
commit
f414f9aa2d
@ -344,6 +344,17 @@
|
|||||||
// to use for the DNS TTL.
|
// to use for the DNS TTL.
|
||||||
"ddns-ttl-percent": 0.75,
|
"ddns-ttl-percent": 0.75,
|
||||||
|
|
||||||
|
// When greater than 0 it will be used as the DNS TTL. Specified in seconds.
|
||||||
|
"ddns-ttl": 0,
|
||||||
|
|
||||||
|
// When greater than 0 it used as the lower boundary for calculated DNS TTL values.
|
||||||
|
// Specified in seconds.
|
||||||
|
"ddns-ttl-min": 24000,
|
||||||
|
|
||||||
|
// When greater than 0 it used as the upper boundary for calculated DNS TTL values.
|
||||||
|
// Specified in seconds.
|
||||||
|
"ddns-ttl-max": 64000,
|
||||||
|
|
||||||
// Time in seconds specifying how long a declined lease should be
|
// Time in seconds specifying how long a declined lease should be
|
||||||
// excluded from DHCP assignments. The default value is 86400 (24 hours).
|
// excluded from DHCP assignments. The default value is 86400 (24 hours).
|
||||||
"decline-probation-period": 86400,
|
"decline-probation-period": 86400,
|
||||||
@ -895,6 +906,15 @@
|
|||||||
// Shared-network level value. See description at the global level.
|
// Shared-network level value. See description at the global level.
|
||||||
"ddns-ttl-percent": 0.65,
|
"ddns-ttl-percent": 0.65,
|
||||||
|
|
||||||
|
// Shared-network level value. See description at the global level.
|
||||||
|
"ddns-ttl": 0,
|
||||||
|
|
||||||
|
// Shared-network level value. See description at the global level.
|
||||||
|
"ddns-ttl-min": 10000,
|
||||||
|
|
||||||
|
// Shared-network level value. See description at the global level.
|
||||||
|
"ddns-ttl-max": 20000,
|
||||||
|
|
||||||
// Shared-network level value. See description at the global level.
|
// Shared-network level value. See description at the global level.
|
||||||
"hostname-char-replacement": "x",
|
"hostname-char-replacement": "x",
|
||||||
|
|
||||||
@ -1035,6 +1055,15 @@
|
|||||||
// Subnet-level value. See description at the global level.
|
// Subnet-level value. See description at the global level.
|
||||||
"ddns-ttl-percent": 0.55,
|
"ddns-ttl-percent": 0.55,
|
||||||
|
|
||||||
|
// Subnet-level value. See description at the global level.
|
||||||
|
"ddns-ttl": 0,
|
||||||
|
|
||||||
|
// Subnet-evel value. See description at the global level.
|
||||||
|
"ddns-ttl-min": 10000,
|
||||||
|
|
||||||
|
// Subnet-level value. See description at the global level.
|
||||||
|
"ddns-ttl-max": 20000,
|
||||||
|
|
||||||
// Subnet-level value. See description at the global level.
|
// Subnet-level value. See description at the global level.
|
||||||
"hostname-char-replacement": "x",
|
"hostname-char-replacement": "x",
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -905,6 +905,39 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
\"ddns-ttl\" {
|
||||||
|
switch(driver.ctx_) {
|
||||||
|
case isc::dhcp::Parser4Context::DHCP4:
|
||||||
|
case isc::dhcp::Parser4Context::SUBNET4:
|
||||||
|
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||||
|
return isc::dhcp::Dhcp4Parser::make_DDNS_TTL(driver.loc_);
|
||||||
|
default:
|
||||||
|
return isc::dhcp::Dhcp4Parser::make_STRING("ddns-ttl", driver.loc_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\"ddns-ttl-min\" {
|
||||||
|
switch(driver.ctx_) {
|
||||||
|
case isc::dhcp::Parser4Context::DHCP4:
|
||||||
|
case isc::dhcp::Parser4Context::SUBNET4:
|
||||||
|
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||||
|
return isc::dhcp::Dhcp4Parser::make_DDNS_TTL_MIN(driver.loc_);
|
||||||
|
default:
|
||||||
|
return isc::dhcp::Dhcp4Parser::make_STRING("ddns-ttl-min", driver.loc_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\"ddns-ttl-max\" {
|
||||||
|
switch(driver.ctx_) {
|
||||||
|
case isc::dhcp::Parser4Context::DHCP4:
|
||||||
|
case isc::dhcp::Parser4Context::SUBNET4:
|
||||||
|
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||||
|
return isc::dhcp::Dhcp4Parser::make_DDNS_TTL_MAX(driver.loc_);
|
||||||
|
default:
|
||||||
|
return isc::dhcp::Dhcp4Parser::make_STRING("ddns-ttl-max", driver.loc_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
\"subnet4\" {
|
\"subnet4\" {
|
||||||
switch(driver.ctx_) {
|
switch(driver.ctx_) {
|
||||||
case isc::dhcp::Parser4Context::DHCP4:
|
case isc::dhcp::Parser4Context::DHCP4:
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -137,6 +137,9 @@ using namespace std;
|
|||||||
DDNS_UPDATE_ON_RENEW "ddns-update-on-renew"
|
DDNS_UPDATE_ON_RENEW "ddns-update-on-renew"
|
||||||
DDNS_USE_CONFLICT_RESOLUTION "ddns-use-conflict-resolution"
|
DDNS_USE_CONFLICT_RESOLUTION "ddns-use-conflict-resolution"
|
||||||
DDNS_TTL_PERCENT "ddns-ttl-percent"
|
DDNS_TTL_PERCENT "ddns-ttl-percent"
|
||||||
|
DDNS_TTL "ddns-ttl"
|
||||||
|
DDNS_TTL_MIN "ddns-ttl-min"
|
||||||
|
DDNS_TTL_MAX "ddns-ttl-mix"
|
||||||
STORE_EXTENDED_INFO "store-extended-info"
|
STORE_EXTENDED_INFO "store-extended-info"
|
||||||
SUBNET4 "subnet4"
|
SUBNET4 "subnet4"
|
||||||
SUBNET_4O6_INTERFACE "4o6-interface"
|
SUBNET_4O6_INTERFACE "4o6-interface"
|
||||||
@ -566,6 +569,9 @@ global_param: valid_lifetime
|
|||||||
| ddns_use_conflict_resolution
|
| ddns_use_conflict_resolution
|
||||||
| ddns_conflict_resolution_mode
|
| ddns_conflict_resolution_mode
|
||||||
| ddns_ttl_percent
|
| ddns_ttl_percent
|
||||||
|
| ddns_ttl
|
||||||
|
| ddns_ttl_min
|
||||||
|
| ddns_ttl_max
|
||||||
| store_extended_info
|
| store_extended_info
|
||||||
| statistic_default_sample_count
|
| statistic_default_sample_count
|
||||||
| statistic_default_sample_age
|
| statistic_default_sample_age
|
||||||
@ -800,6 +806,24 @@ ddns_ttl_percent: DDNS_TTL_PERCENT COLON FLOAT {
|
|||||||
ctx.stack_.back()->set("ddns-ttl-percent", ttl);
|
ctx.stack_.back()->set("ddns-ttl-percent", ttl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ddns_ttl: DDNS_TTL COLON INTEGER {
|
||||||
|
ctx.unique("ddns-ttl", ctx.loc2pos(@1));
|
||||||
|
ElementPtr ttl(new IntElement($3, ctx.loc2pos(@3)));
|
||||||
|
ctx.stack_.back()->set("ddns-ttl", ttl);
|
||||||
|
};
|
||||||
|
|
||||||
|
ddns_ttl_min: DDNS_TTL_MIN COLON INTEGER {
|
||||||
|
ctx.unique("ddns-ttl-min", ctx.loc2pos(@1));
|
||||||
|
ElementPtr ttl(new IntElement($3, ctx.loc2pos(@3)));
|
||||||
|
ctx.stack_.back()->set("ddns-ttl-min", ttl);
|
||||||
|
};
|
||||||
|
|
||||||
|
ddns_ttl_max: DDNS_TTL_MAX COLON INTEGER {
|
||||||
|
ctx.unique("ddns-ttl-max", ctx.loc2pos(@1));
|
||||||
|
ElementPtr ttl(new IntElement($3, ctx.loc2pos(@3)));
|
||||||
|
ctx.stack_.back()->set("ddns-ttl-max", ttl);
|
||||||
|
};
|
||||||
|
|
||||||
hostname_char_set: HOSTNAME_CHAR_SET {
|
hostname_char_set: HOSTNAME_CHAR_SET {
|
||||||
ctx.unique("hostname-char-set", ctx.loc2pos(@1));
|
ctx.unique("hostname-char-set", ctx.loc2pos(@1));
|
||||||
ctx.enter(ctx.NO_KEYWORD);
|
ctx.enter(ctx.NO_KEYWORD);
|
||||||
@ -1636,6 +1660,9 @@ subnet4_param: valid_lifetime
|
|||||||
| ddns_use_conflict_resolution
|
| ddns_use_conflict_resolution
|
||||||
| ddns_conflict_resolution_mode
|
| ddns_conflict_resolution_mode
|
||||||
| ddns_ttl_percent
|
| ddns_ttl_percent
|
||||||
|
| ddns_ttl
|
||||||
|
| ddns_ttl_min
|
||||||
|
| ddns_ttl_max
|
||||||
| hostname_char_set
|
| hostname_char_set
|
||||||
| hostname_char_replacement
|
| hostname_char_replacement
|
||||||
| store_extended_info
|
| store_extended_info
|
||||||
@ -1837,6 +1864,9 @@ shared_network_param: name
|
|||||||
| ddns_use_conflict_resolution
|
| ddns_use_conflict_resolution
|
||||||
| ddns_conflict_resolution_mode
|
| ddns_conflict_resolution_mode
|
||||||
| ddns_ttl_percent
|
| ddns_ttl_percent
|
||||||
|
| ddns_ttl
|
||||||
|
| ddns_ttl_min
|
||||||
|
| ddns_ttl_max
|
||||||
| hostname_char_set
|
| hostname_char_set
|
||||||
| hostname_char_replacement
|
| hostname_char_replacement
|
||||||
| store_extended_info
|
| store_extended_info
|
||||||
|
@ -195,6 +195,9 @@ public:
|
|||||||
/// Global lifetime sanity checks
|
/// Global lifetime sanity checks
|
||||||
cfg->sanityChecksLifetime("valid-lifetime");
|
cfg->sanityChecksLifetime("valid-lifetime");
|
||||||
|
|
||||||
|
/// Sanity check global ddns-ttl parameters
|
||||||
|
cfg->sanityChecksDdnsTtlParameters();
|
||||||
|
|
||||||
/// Shared network sanity checks
|
/// Shared network sanity checks
|
||||||
const SharedNetwork4Collection* networks = cfg->getCfgSharedNetworks4()->getAll();
|
const SharedNetwork4Collection* networks = cfg->getCfgSharedNetworks4()->getAll();
|
||||||
if (networks) {
|
if (networks) {
|
||||||
@ -673,7 +676,10 @@ processDhcp4Config(isc::data::ConstElementPtr config_set) {
|
|||||||
(config_pair.first == "parked-packet-limit") ||
|
(config_pair.first == "parked-packet-limit") ||
|
||||||
(config_pair.first == "allocator") ||
|
(config_pair.first == "allocator") ||
|
||||||
(config_pair.first == "offer-lifetime") ||
|
(config_pair.first == "offer-lifetime") ||
|
||||||
(config_pair.first == "stash-agent-options") ) {
|
(config_pair.first == "ddns-ttl") ||
|
||||||
|
(config_pair.first == "ddns-ttl-min") ||
|
||||||
|
(config_pair.first == "ddns-ttl-max") ||
|
||||||
|
(config_pair.first == "stash-agent-options")) {
|
||||||
CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
|
CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
|
||||||
config_pair.second);
|
config_pair.second);
|
||||||
continue;
|
continue;
|
||||||
|
@ -8269,4 +8269,180 @@ TEST_F(Dhcp4ParserTest, deprecatedClientClassesCheck) {
|
|||||||
" and 'client-classes'. Use only the latter.");
|
" and 'client-classes'. Use only the latter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(Dhcp4ParserTest, ddnsTtlPercent) {
|
||||||
|
string config = R"(
|
||||||
|
{
|
||||||
|
"ddns-ttl-percent": 0.75,
|
||||||
|
"valid-lifetime": 4000,
|
||||||
|
"shared-networks": [{
|
||||||
|
"name": "net",
|
||||||
|
"ddns-ttl-percent": 0.50,
|
||||||
|
"subnet4": [{
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "10.0.2.0/24",
|
||||||
|
"ddns-ttl-percent": 0.25
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ConstElementPtr json;
|
||||||
|
ASSERT_NO_THROW(json = parseDHCP4(config));
|
||||||
|
extractConfig(config);
|
||||||
|
|
||||||
|
ConstElementPtr status;
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 0);
|
||||||
|
|
||||||
|
// Commit it so global inheritance works.
|
||||||
|
CfgMgr::instance().commit();
|
||||||
|
|
||||||
|
ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||||
|
getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlPercent(Network::Inheritance::NONE).unspecified());
|
||||||
|
EXPECT_EQ(0.25, subnet->getDdnsTtlPercent(Network::Inheritance::NONE).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).unspecified());
|
||||||
|
EXPECT_EQ(0.50, subnet->getDdnsTtlPercent(Network::Inheritance::PARENT_NETWORK).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).unspecified());
|
||||||
|
EXPECT_EQ(0.75, subnet->getDdnsTtlPercent(Network::Inheritance::GLOBAL).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Dhcp4ParserTest, ddnsTtl) {
|
||||||
|
string config = R"(
|
||||||
|
{
|
||||||
|
"ddns-ttl": 750,
|
||||||
|
"valid-lifetime": 4000,
|
||||||
|
"shared-networks": [{
|
||||||
|
"name": "net",
|
||||||
|
"ddns-ttl": 500,
|
||||||
|
"subnet4": [{
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "10.0.2.0/24",
|
||||||
|
"ddns-ttl": 250
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ConstElementPtr json;
|
||||||
|
ASSERT_NO_THROW(json = parseDHCP4(config));
|
||||||
|
extractConfig(config);
|
||||||
|
|
||||||
|
ConstElementPtr status;
|
||||||
|
EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 0);
|
||||||
|
|
||||||
|
// Commit it so global inheritance works.
|
||||||
|
CfgMgr::instance().commit();
|
||||||
|
|
||||||
|
ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||||
|
getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtl(Network::Inheritance::NONE).unspecified());
|
||||||
|
EXPECT_EQ(250, subnet->getDdnsTtl(Network::Inheritance::NONE).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).unspecified());
|
||||||
|
EXPECT_EQ(500, subnet->getDdnsTtl(Network::Inheritance::PARENT_NETWORK).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtl(Network::Inheritance::GLOBAL).unspecified());
|
||||||
|
EXPECT_EQ(750, subnet->getDdnsTtl(Network::Inheritance::GLOBAL).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Dhcp4ParserTest, ddnsTtlMin) {
|
||||||
|
string config = R"(
|
||||||
|
{
|
||||||
|
"ddns-ttl-min": 750,
|
||||||
|
"valid-lifetime": 4000,
|
||||||
|
"shared-networks": [{
|
||||||
|
"name": "net",
|
||||||
|
"ddns-ttl-min": 500,
|
||||||
|
"subnet4": [{
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "10.0.2.0/24",
|
||||||
|
"ddns-ttl-min": 250
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ConstElementPtr json;
|
||||||
|
ASSERT_NO_THROW(json = parseDHCP4(config));
|
||||||
|
extractConfig(config);
|
||||||
|
|
||||||
|
ConstElementPtr status;
|
||||||
|
EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 0);
|
||||||
|
|
||||||
|
// Commit it so global inheritance works.
|
||||||
|
CfgMgr::instance().commit();
|
||||||
|
|
||||||
|
ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||||
|
getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlMin(Network::Inheritance::NONE).unspecified());
|
||||||
|
EXPECT_EQ(250, subnet->getDdnsTtlMin(Network::Inheritance::NONE).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).unspecified());
|
||||||
|
EXPECT_EQ(500, subnet->getDdnsTtlMin(Network::Inheritance::PARENT_NETWORK).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).unspecified());
|
||||||
|
EXPECT_EQ(750, subnet->getDdnsTtlMin(Network::Inheritance::GLOBAL).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(Dhcp4ParserTest, ddnsTtlMax) {
|
||||||
|
string config = R"(
|
||||||
|
{
|
||||||
|
"ddns-ttl-max": 750,
|
||||||
|
"valid-lifetime": 4000,
|
||||||
|
"shared-networks": [{
|
||||||
|
"name": "net",
|
||||||
|
"ddns-ttl-max": 500,
|
||||||
|
"subnet4": [{
|
||||||
|
"id": 1,
|
||||||
|
"subnet": "10.0.2.0/24",
|
||||||
|
"ddns-ttl-max": 250
|
||||||
|
}],
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ConstElementPtr json;
|
||||||
|
ASSERT_NO_THROW(json = parseDHCP4(config));
|
||||||
|
extractConfig(config);
|
||||||
|
|
||||||
|
ConstElementPtr status;
|
||||||
|
EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 0);
|
||||||
|
|
||||||
|
// Commit it so global inheritance works.
|
||||||
|
CfgMgr::instance().commit();
|
||||||
|
|
||||||
|
ConstSubnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||||
|
getCfgSubnets4()->selectSubnet(IOAddress("10.0.2.0"));
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlMax(Network::Inheritance::NONE).unspecified());
|
||||||
|
EXPECT_EQ(250, subnet->getDdnsTtlMax(Network::Inheritance::NONE).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).unspecified());
|
||||||
|
EXPECT_EQ(500, subnet->getDdnsTtlMax(Network::Inheritance::PARENT_NETWORK).get());
|
||||||
|
|
||||||
|
EXPECT_FALSE(subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).unspecified());
|
||||||
|
EXPECT_EQ(750, subnet->getDdnsTtlMax(Network::Inheritance::GLOBAL).get());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -772,6 +772,100 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Verifies that DDNS TTL parameters are used when specified.
|
||||||
|
///
|
||||||
|
/// @param valid_flt lease life time
|
||||||
|
/// @param ddns_ttl_percent expected configured value for ddns-ttl-percent
|
||||||
|
/// @param ddns_ttl expected configured value for ddns-ttl
|
||||||
|
/// @param ddns_ttl_min expected configured value for ddns-ttl-min
|
||||||
|
/// @param ddns_ttl_max expected configured value for ddns-ttl-max
|
||||||
|
void testDdnsTtlParameters(uint32_t valid_lft,
|
||||||
|
Optional<double> ddns_ttl_percent = Optional<double>(),
|
||||||
|
Optional<uint32_t> ddns_ttl = Optional<uint32_t>(),
|
||||||
|
Optional<uint32_t> ddns_ttl_min = Optional<uint32_t>(),
|
||||||
|
Optional<uint32_t> ddns_ttl_max = Optional<uint32_t>()) {
|
||||||
|
|
||||||
|
std::string config_header = R"(
|
||||||
|
{
|
||||||
|
"interfaces-config": { "interfaces": [ "*" ] },
|
||||||
|
"subnet4": [ {
|
||||||
|
"subnet": "10.0.0.0/24",
|
||||||
|
"interface": "eth1",
|
||||||
|
"id": 1,
|
||||||
|
"pools": [ { "pool": "10.0.0.10-10.0.0.10" } ]
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::string config_footer = R"(
|
||||||
|
}],
|
||||||
|
"ddns-qualifying-suffix": "example.com.",
|
||||||
|
"dhcp-ddns": { "enable-updates": true }
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << config_header;
|
||||||
|
|
||||||
|
oss << ",\n \"valid-lifetime\":" << valid_lft;
|
||||||
|
|
||||||
|
if (!ddns_ttl_percent.unspecified()) {
|
||||||
|
oss << ",\n, \"ddns-ttl-percent\" :" << util::str::dumpDouble(ddns_ttl_percent.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ddns_ttl.unspecified()) {
|
||||||
|
oss << ",\n, \"ddns-ttl\" :" << ddns_ttl.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ddns_ttl_min.unspecified()) {
|
||||||
|
oss << ",\n, \"ddns-ttl-min\" :" << ddns_ttl_min.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ddns_ttl_max.unspecified()) {
|
||||||
|
oss << ",\n, \"ddns-ttl-max\" :" << ddns_ttl_max.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
oss << "\n" << config_footer;
|
||||||
|
|
||||||
|
// Load a configuration with D2 enabled and ddns-ttl* parameters.
|
||||||
|
ASSERT_NO_FATAL_FAILURE(configure(oss.str(), *srv_));
|
||||||
|
ASSERT_TRUE(CfgMgr::instance().ddnsEnabled());
|
||||||
|
|
||||||
|
// Create a client and get a lease.
|
||||||
|
Dhcp4Client client1(srv_, Dhcp4Client::SELECTING);
|
||||||
|
client1.setIfaceName("eth1");
|
||||||
|
client1.setIfaceIndex(ETH1_INDEX);
|
||||||
|
ASSERT_NO_THROW(client1.includeHostname("client1"));
|
||||||
|
|
||||||
|
// Do the DORA.
|
||||||
|
ASSERT_NO_THROW(client1.doDORA());
|
||||||
|
Pkt4Ptr resp = client1.getContext().response_;
|
||||||
|
ASSERT_TRUE(resp);
|
||||||
|
ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
|
||||||
|
|
||||||
|
// Obtain the Hostname option sent in the response and make sure that the server
|
||||||
|
// has used the hostname reserved for this client.
|
||||||
|
OptionStringPtr hostname;
|
||||||
|
hostname = boost::dynamic_pointer_cast<OptionString>(resp->getOption(DHO_HOST_NAME));
|
||||||
|
ASSERT_TRUE(hostname);
|
||||||
|
EXPECT_EQ("client1.example.com", hostname->getValue());
|
||||||
|
|
||||||
|
// Make sure the lease is in the database and hostname is correct.
|
||||||
|
Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(IOAddress("10.0.0.10"));
|
||||||
|
ASSERT_TRUE(lease);
|
||||||
|
EXPECT_EQ("client1.example.com", lease->hostname_);
|
||||||
|
|
||||||
|
// Verify that an NCR was generated correctly.
|
||||||
|
ASSERT_EQ(1, CfgMgr::instance().getD2ClientMgr().getQueueSize());
|
||||||
|
verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true,
|
||||||
|
resp->getYiaddr().toText(),
|
||||||
|
"client1.example.com.", "",
|
||||||
|
time(NULL), lease->valid_lft_, true,
|
||||||
|
CHECK_WITH_DHCID,
|
||||||
|
ddns_ttl_percent,
|
||||||
|
ddns_ttl,
|
||||||
|
ddns_ttl_min,
|
||||||
|
ddns_ttl_max);
|
||||||
|
}
|
||||||
|
|
||||||
///@brief Verify that NameChangeRequest holds valid values.
|
///@brief Verify that NameChangeRequest holds valid values.
|
||||||
///
|
///
|
||||||
/// Pulls the NCR from the top of the send queue and checks its content
|
/// Pulls the NCR from the top of the send queue and checks its content
|
||||||
@ -794,6 +888,10 @@ public:
|
|||||||
/// lease expiration time is conducted as greater than or equal to rather
|
/// lease expiration time is conducted as greater than or equal to rather
|
||||||
/// equal to CLTT plus lease ttl .
|
/// equal to CLTT plus lease ttl .
|
||||||
/// @param exp_conflict_resolution_mode expected value of conflict resolution mode
|
/// @param exp_conflict_resolution_mode expected value of conflict resolution mode
|
||||||
|
/// @param ddns_ttl_percent expected configured value for ddns-ttl-percent
|
||||||
|
/// @param ddns_ttl expected configured value for ddns-ttl
|
||||||
|
/// @param ddns_ttl_min expected configured value for ddns-ttl-min
|
||||||
|
/// @param ddns_ttl_max expected configured value for ddns-ttl-max
|
||||||
void verifyNameChangeRequest(const isc::dhcp_ddns::NameChangeType type,
|
void verifyNameChangeRequest(const isc::dhcp_ddns::NameChangeType type,
|
||||||
const bool reverse, const bool forward,
|
const bool reverse, const bool forward,
|
||||||
const std::string& addr,
|
const std::string& addr,
|
||||||
@ -804,7 +902,10 @@ public:
|
|||||||
const bool not_strict_expire_check = false,
|
const bool not_strict_expire_check = false,
|
||||||
const ConflictResolutionMode
|
const ConflictResolutionMode
|
||||||
exp_conflict_resolution_mode = CHECK_WITH_DHCID,
|
exp_conflict_resolution_mode = CHECK_WITH_DHCID,
|
||||||
Optional<double> ttl_percent = Optional<double>()) {
|
Optional<double> ddns_ttl_percent = Optional<double>(),
|
||||||
|
Optional<uint32_t> ddns_ttl = Optional<uint32_t>(),
|
||||||
|
Optional<uint32_t> ddns_ttl_min = Optional<uint32_t>(),
|
||||||
|
Optional<uint32_t> ddns_ttl_max = Optional<uint32_t>()) {
|
||||||
NameChangeRequestPtr ncr;
|
NameChangeRequestPtr ncr;
|
||||||
ASSERT_NO_THROW(ncr = d2_mgr_.peekAt(0));
|
ASSERT_NO_THROW(ncr = d2_mgr_.peekAt(0));
|
||||||
ASSERT_TRUE(ncr);
|
ASSERT_TRUE(ncr);
|
||||||
@ -825,7 +926,10 @@ public:
|
|||||||
// current time as cltt but the it may not check the lease expiration
|
// current time as cltt but the it may not check the lease expiration
|
||||||
// time for equality but rather check that the lease expiration time
|
// time for equality but rather check that the lease expiration time
|
||||||
// is not greater than the current time + lease lifetime.
|
// is not greater than the current time + lease lifetime.
|
||||||
uint32_t ttl = calculateDdnsTtl(valid_lft, ttl_percent);
|
|
||||||
|
uint32_t ttl = calculateDdnsTtl(valid_lft, ddns_ttl_percent,
|
||||||
|
ddns_ttl, ddns_ttl_min, ddns_ttl_max);
|
||||||
|
|
||||||
if (not_strict_expire_check) {
|
if (not_strict_expire_check) {
|
||||||
EXPECT_GE(cltt + ttl, ncr->getLeaseExpiresOn());
|
EXPECT_GE(cltt + ttl, ncr->getLeaseExpiresOn());
|
||||||
} else {
|
} else {
|
||||||
@ -2840,7 +2944,7 @@ TEST_F(NameDhcpv4SrvTest, withOfferLifetime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verifies the DNS TTL when ttl percent is specified
|
// Verifies the DNS TTL when ttl percent is specified
|
||||||
// than zero.
|
// greater than zero.
|
||||||
TEST_F(NameDhcpv4SrvTest, withDdnsTtlPercent) {
|
TEST_F(NameDhcpv4SrvTest, withDdnsTtlPercent) {
|
||||||
// Load a configuration with D2 enabled and ddns-ttl-percent
|
// Load a configuration with D2 enabled and ddns-ttl-percent
|
||||||
ASSERT_NO_FATAL_FAILURE(configure(CONFIGS[12], *srv_));
|
ASSERT_NO_FATAL_FAILURE(configure(CONFIGS[12], *srv_));
|
||||||
@ -2958,4 +3062,36 @@ TEST_F(NameDhcpv4SrvTest, checkExistsDHCIDConflictResolutionMode) {
|
|||||||
lease->cltt_, 100, false, CHECK_EXISTS_WITH_DHCID);
|
lease->cltt_, 100, false, CHECK_EXISTS_WITH_DHCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify the ddns-ttl-percent is used when specified.
|
||||||
|
TEST_F(NameDhcpv4SrvTest, ddnsTtlPercentTest) {
|
||||||
|
testDdnsTtlParameters(2100, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the ddns-ttl is used when specified.
|
||||||
|
TEST_F(NameDhcpv4SrvTest, ddnsTtlTest) {
|
||||||
|
testDdnsTtlParameters(2100, // valid lft
|
||||||
|
Optional<double>(), // percent
|
||||||
|
999, // ttl
|
||||||
|
Optional<uint32_t>(), // min
|
||||||
|
Optional<uint32_t>()); // max
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the ddns-ttl-min is used when specified.
|
||||||
|
TEST_F(NameDhcpv4SrvTest, ddnsTtlMinTest) {
|
||||||
|
testDdnsTtlParameters(2100, // valid lft
|
||||||
|
Optional<double>(), // percent
|
||||||
|
Optional<uint32_t>(), // ttl
|
||||||
|
800, // ttl-min
|
||||||
|
Optional<uint32_t>()); // ttl-max
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the ddns-ttl-max is used when specified.
|
||||||
|
TEST_F(NameDhcpv4SrvTest, ddnsTtlMaxTest) {
|
||||||
|
testDdnsTtlParameters(2100, // valid lft
|
||||||
|
Optional<double>(), // percent
|
||||||
|
Optional<uint32_t>(), // ttl
|
||||||
|
Optional<uint32_t>(), // ttl-min
|
||||||
|
500); // ttl-max
|
||||||
|
}
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
@ -68,6 +68,7 @@ namespace {
|
|||||||
///@{
|
///@{
|
||||||
/// @brief extracted configurations
|
/// @brief extracted configurations
|
||||||
const char* EXTRACTED_CONFIGS[] = {
|
const char* EXTRACTED_CONFIGS[] = {
|
||||||
|
/// put this after const char* EXTRACTED_CONFIGS[] = {
|
||||||
// CONFIGURATION 0
|
// CONFIGURATION 0
|
||||||
"{\n"
|
"{\n"
|
||||||
" \"interfaces-config\": {\n"
|
" \"interfaces-config\": {\n"
|
||||||
@ -2651,11 +2652,84 @@ const char* EXTRACTED_CONFIGS[] = {
|
|||||||
" }\n"
|
" }\n"
|
||||||
" ],\n"
|
" ],\n"
|
||||||
" \"valid-lifetime\": 400\n"
|
" \"valid-lifetime\": 400\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 83
|
||||||
|
"{\n"
|
||||||
|
" \"ddns-ttl-percent\": 0.75,\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl-percent\": 0.5,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl-percent\": 0.25,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\"\n"
|
||||||
|
" }\n"
|
||||||
|
" ]\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 84
|
||||||
|
"{\n"
|
||||||
|
" \"ddns-ttl\": 750,\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl\": 500,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl\": 250,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\"\n"
|
||||||
|
" }\n"
|
||||||
|
" ]\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 85
|
||||||
|
"{\n"
|
||||||
|
" \"ddns-ttl-min\": 750,\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl-min\": 500,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl-min\": 250,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\"\n"
|
||||||
|
" }\n"
|
||||||
|
" ]\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 86
|
||||||
|
"{\n"
|
||||||
|
" \"ddns-ttl-max\": 750,\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl-max\": 500,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"ddns-ttl-max\": 250,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\"\n"
|
||||||
|
" }\n"
|
||||||
|
" ]\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief unparsed configurations
|
/// @brief unparsed configurations
|
||||||
const char* UNPARSED_CONFIGS[] = {
|
const char* UNPARSED_CONFIGS[] = {
|
||||||
|
///put this after const char* UNPARSED_CONFIGS[] = {
|
||||||
// CONFIGURATION 0
|
// CONFIGURATION 0
|
||||||
"{\n"
|
"{\n"
|
||||||
" \"allocator\": \"iterative\",\n"
|
" \"allocator\": \"iterative\",\n"
|
||||||
@ -13546,6 +13620,506 @@ const char* UNPARSED_CONFIGS[] = {
|
|||||||
" \"t1-percent\": 0.5,\n"
|
" \"t1-percent\": 0.5,\n"
|
||||||
" \"t2-percent\": 0.875,\n"
|
" \"t2-percent\": 0.875,\n"
|
||||||
" \"valid-lifetime\": 400\n"
|
" \"valid-lifetime\": 400\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 83
|
||||||
|
"{\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"authoritative\": false,\n"
|
||||||
|
" \"boot-file-name\": \"\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
|
||||||
|
" \"ddns-generated-prefix\": \"myhost\",\n"
|
||||||
|
" \"ddns-override-client-update\": false,\n"
|
||||||
|
" \"ddns-override-no-update\": false,\n"
|
||||||
|
" \"ddns-qualifying-suffix\": \"\",\n"
|
||||||
|
" \"ddns-replace-client-name\": \"never\",\n"
|
||||||
|
" \"ddns-send-updates\": true,\n"
|
||||||
|
" \"ddns-ttl-percent\": 0.75,\n"
|
||||||
|
" \"ddns-update-on-renew\": false,\n"
|
||||||
|
" \"decline-probation-period\": 86400,\n"
|
||||||
|
" \"dhcp-ddns\": {\n"
|
||||||
|
" \"enable-updates\": false,\n"
|
||||||
|
" \"max-queue-size\": 1024,\n"
|
||||||
|
" \"ncr-format\": \"JSON\",\n"
|
||||||
|
" \"ncr-protocol\": \"UDP\",\n"
|
||||||
|
" \"sender-ip\": \"0.0.0.0\",\n"
|
||||||
|
" \"sender-port\": 0,\n"
|
||||||
|
" \"server-ip\": \"127.0.0.1\",\n"
|
||||||
|
" \"server-port\": 53001\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp-queue-control\": {\n"
|
||||||
|
" \"capacity\": 64,\n"
|
||||||
|
" \"enable-queue\": false,\n"
|
||||||
|
" \"queue-type\": \"kea-ring4\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp4o6-port\": 0,\n"
|
||||||
|
" \"early-global-reservations-lookup\": false,\n"
|
||||||
|
" \"echo-client-id\": true,\n"
|
||||||
|
" \"expired-leases-processing\": {\n"
|
||||||
|
" \"flush-reclaimed-timer-wait-time\": 25,\n"
|
||||||
|
" \"hold-reclaimed-time\": 3600,\n"
|
||||||
|
" \"max-reclaim-leases\": 100,\n"
|
||||||
|
" \"max-reclaim-time\": 250,\n"
|
||||||
|
" \"reclaim-timer-wait-time\": 10,\n"
|
||||||
|
" \"unwarned-reclaim-cycles\": 5\n"
|
||||||
|
" },\n"
|
||||||
|
" \"hooks-libraries\": [ ],\n"
|
||||||
|
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
|
||||||
|
" \"hostname-char-replacement\": \"\",\n"
|
||||||
|
" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
|
||||||
|
" \"interfaces-config\": {\n"
|
||||||
|
" \"interfaces\": [ ],\n"
|
||||||
|
" \"re-detect\": false\n"
|
||||||
|
" },\n"
|
||||||
|
" \"ip-reservations-unique\": true,\n"
|
||||||
|
" \"lease-database\": {\n"
|
||||||
|
" \"type\": \"memfile\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"match-client-id\": true,\n"
|
||||||
|
" \"multi-threading\": {\n"
|
||||||
|
" \"enable-multi-threading\": true,\n"
|
||||||
|
" \"packet-queue-size\": 64,\n"
|
||||||
|
" \"thread-pool-size\": 0\n"
|
||||||
|
" },\n"
|
||||||
|
" \"next-server\": \"0.0.0.0\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"option-def\": [ ],\n"
|
||||||
|
" \"parked-packet-limit\": 256,\n"
|
||||||
|
" \"reservations-global\": false,\n"
|
||||||
|
" \"reservations-in-subnet\": true,\n"
|
||||||
|
" \"reservations-lookup-first\": false,\n"
|
||||||
|
" \"reservations-out-of-pool\": false,\n"
|
||||||
|
" \"sanity-checks\": {\n"
|
||||||
|
" \"extended-info-checks\": \"fix\",\n"
|
||||||
|
" \"lease-checks\": \"warn\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"server-hostname\": \"\",\n"
|
||||||
|
" \"server-tag\": \"\",\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl-percent\": 0.5,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"4o6-interface\": \"\",\n"
|
||||||
|
" \"4o6-interface-id\": \"\",\n"
|
||||||
|
" \"4o6-subnet\": \"\",\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl-percent\": 0.25,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"pools\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"reservations\": [ ],\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\",\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"stash-agent-options\": false,\n"
|
||||||
|
" \"statistic-default-sample-age\": 0,\n"
|
||||||
|
" \"statistic-default-sample-count\": 20,\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [ ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 84
|
||||||
|
"{\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"authoritative\": false,\n"
|
||||||
|
" \"boot-file-name\": \"\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
|
||||||
|
" \"ddns-generated-prefix\": \"myhost\",\n"
|
||||||
|
" \"ddns-override-client-update\": false,\n"
|
||||||
|
" \"ddns-override-no-update\": false,\n"
|
||||||
|
" \"ddns-qualifying-suffix\": \"\",\n"
|
||||||
|
" \"ddns-replace-client-name\": \"never\",\n"
|
||||||
|
" \"ddns-send-updates\": true,\n"
|
||||||
|
" \"ddns-ttl\": 750,\n"
|
||||||
|
" \"ddns-update-on-renew\": false,\n"
|
||||||
|
" \"decline-probation-period\": 86400,\n"
|
||||||
|
" \"dhcp-ddns\": {\n"
|
||||||
|
" \"enable-updates\": false,\n"
|
||||||
|
" \"max-queue-size\": 1024,\n"
|
||||||
|
" \"ncr-format\": \"JSON\",\n"
|
||||||
|
" \"ncr-protocol\": \"UDP\",\n"
|
||||||
|
" \"sender-ip\": \"0.0.0.0\",\n"
|
||||||
|
" \"sender-port\": 0,\n"
|
||||||
|
" \"server-ip\": \"127.0.0.1\",\n"
|
||||||
|
" \"server-port\": 53001\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp-queue-control\": {\n"
|
||||||
|
" \"capacity\": 64,\n"
|
||||||
|
" \"enable-queue\": false,\n"
|
||||||
|
" \"queue-type\": \"kea-ring4\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp4o6-port\": 0,\n"
|
||||||
|
" \"early-global-reservations-lookup\": false,\n"
|
||||||
|
" \"echo-client-id\": true,\n"
|
||||||
|
" \"expired-leases-processing\": {\n"
|
||||||
|
" \"flush-reclaimed-timer-wait-time\": 25,\n"
|
||||||
|
" \"hold-reclaimed-time\": 3600,\n"
|
||||||
|
" \"max-reclaim-leases\": 100,\n"
|
||||||
|
" \"max-reclaim-time\": 250,\n"
|
||||||
|
" \"reclaim-timer-wait-time\": 10,\n"
|
||||||
|
" \"unwarned-reclaim-cycles\": 5\n"
|
||||||
|
" },\n"
|
||||||
|
" \"hooks-libraries\": [ ],\n"
|
||||||
|
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
|
||||||
|
" \"hostname-char-replacement\": \"\",\n"
|
||||||
|
" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
|
||||||
|
" \"interfaces-config\": {\n"
|
||||||
|
" \"interfaces\": [ ],\n"
|
||||||
|
" \"re-detect\": false\n"
|
||||||
|
" },\n"
|
||||||
|
" \"ip-reservations-unique\": true,\n"
|
||||||
|
" \"lease-database\": {\n"
|
||||||
|
" \"type\": \"memfile\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"match-client-id\": true,\n"
|
||||||
|
" \"multi-threading\": {\n"
|
||||||
|
" \"enable-multi-threading\": true,\n"
|
||||||
|
" \"packet-queue-size\": 64,\n"
|
||||||
|
" \"thread-pool-size\": 0\n"
|
||||||
|
" },\n"
|
||||||
|
" \"next-server\": \"0.0.0.0\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"option-def\": [ ],\n"
|
||||||
|
" \"parked-packet-limit\": 256,\n"
|
||||||
|
" \"reservations-global\": false,\n"
|
||||||
|
" \"reservations-in-subnet\": true,\n"
|
||||||
|
" \"reservations-lookup-first\": false,\n"
|
||||||
|
" \"reservations-out-of-pool\": false,\n"
|
||||||
|
" \"sanity-checks\": {\n"
|
||||||
|
" \"extended-info-checks\": \"fix\",\n"
|
||||||
|
" \"lease-checks\": \"warn\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"server-hostname\": \"\",\n"
|
||||||
|
" \"server-tag\": \"\",\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl\": 500,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"4o6-interface\": \"\",\n"
|
||||||
|
" \"4o6-interface-id\": \"\",\n"
|
||||||
|
" \"4o6-subnet\": \"\",\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl\": 250,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"pools\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"reservations\": [ ],\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\",\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"stash-agent-options\": false,\n"
|
||||||
|
" \"statistic-default-sample-age\": 0,\n"
|
||||||
|
" \"statistic-default-sample-count\": 20,\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [ ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 85
|
||||||
|
"{\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"authoritative\": false,\n"
|
||||||
|
" \"boot-file-name\": \"\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
|
||||||
|
" \"ddns-generated-prefix\": \"myhost\",\n"
|
||||||
|
" \"ddns-override-client-update\": false,\n"
|
||||||
|
" \"ddns-override-no-update\": false,\n"
|
||||||
|
" \"ddns-qualifying-suffix\": \"\",\n"
|
||||||
|
" \"ddns-replace-client-name\": \"never\",\n"
|
||||||
|
" \"ddns-send-updates\": true,\n"
|
||||||
|
" \"ddns-ttl-min\": 750,\n"
|
||||||
|
" \"ddns-update-on-renew\": false,\n"
|
||||||
|
" \"decline-probation-period\": 86400,\n"
|
||||||
|
" \"dhcp-ddns\": {\n"
|
||||||
|
" \"enable-updates\": false,\n"
|
||||||
|
" \"max-queue-size\": 1024,\n"
|
||||||
|
" \"ncr-format\": \"JSON\",\n"
|
||||||
|
" \"ncr-protocol\": \"UDP\",\n"
|
||||||
|
" \"sender-ip\": \"0.0.0.0\",\n"
|
||||||
|
" \"sender-port\": 0,\n"
|
||||||
|
" \"server-ip\": \"127.0.0.1\",\n"
|
||||||
|
" \"server-port\": 53001\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp-queue-control\": {\n"
|
||||||
|
" \"capacity\": 64,\n"
|
||||||
|
" \"enable-queue\": false,\n"
|
||||||
|
" \"queue-type\": \"kea-ring4\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp4o6-port\": 0,\n"
|
||||||
|
" \"early-global-reservations-lookup\": false,\n"
|
||||||
|
" \"echo-client-id\": true,\n"
|
||||||
|
" \"expired-leases-processing\": {\n"
|
||||||
|
" \"flush-reclaimed-timer-wait-time\": 25,\n"
|
||||||
|
" \"hold-reclaimed-time\": 3600,\n"
|
||||||
|
" \"max-reclaim-leases\": 100,\n"
|
||||||
|
" \"max-reclaim-time\": 250,\n"
|
||||||
|
" \"reclaim-timer-wait-time\": 10,\n"
|
||||||
|
" \"unwarned-reclaim-cycles\": 5\n"
|
||||||
|
" },\n"
|
||||||
|
" \"hooks-libraries\": [ ],\n"
|
||||||
|
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
|
||||||
|
" \"hostname-char-replacement\": \"\",\n"
|
||||||
|
" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
|
||||||
|
" \"interfaces-config\": {\n"
|
||||||
|
" \"interfaces\": [ ],\n"
|
||||||
|
" \"re-detect\": false\n"
|
||||||
|
" },\n"
|
||||||
|
" \"ip-reservations-unique\": true,\n"
|
||||||
|
" \"lease-database\": {\n"
|
||||||
|
" \"type\": \"memfile\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"match-client-id\": true,\n"
|
||||||
|
" \"multi-threading\": {\n"
|
||||||
|
" \"enable-multi-threading\": true,\n"
|
||||||
|
" \"packet-queue-size\": 64,\n"
|
||||||
|
" \"thread-pool-size\": 0\n"
|
||||||
|
" },\n"
|
||||||
|
" \"next-server\": \"0.0.0.0\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"option-def\": [ ],\n"
|
||||||
|
" \"parked-packet-limit\": 256,\n"
|
||||||
|
" \"reservations-global\": false,\n"
|
||||||
|
" \"reservations-in-subnet\": true,\n"
|
||||||
|
" \"reservations-lookup-first\": false,\n"
|
||||||
|
" \"reservations-out-of-pool\": false,\n"
|
||||||
|
" \"sanity-checks\": {\n"
|
||||||
|
" \"extended-info-checks\": \"fix\",\n"
|
||||||
|
" \"lease-checks\": \"warn\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"server-hostname\": \"\",\n"
|
||||||
|
" \"server-tag\": \"\",\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl-min\": 500,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"4o6-interface\": \"\",\n"
|
||||||
|
" \"4o6-interface-id\": \"\",\n"
|
||||||
|
" \"4o6-subnet\": \"\",\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl-min\": 250,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"pools\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"reservations\": [ ],\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\",\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"stash-agent-options\": false,\n"
|
||||||
|
" \"statistic-default-sample-age\": 0,\n"
|
||||||
|
" \"statistic-default-sample-count\": 20,\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [ ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n",
|
||||||
|
// CONFIGURATION 86
|
||||||
|
"{\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"authoritative\": false,\n"
|
||||||
|
" \"boot-file-name\": \"\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
|
||||||
|
" \"ddns-generated-prefix\": \"myhost\",\n"
|
||||||
|
" \"ddns-override-client-update\": false,\n"
|
||||||
|
" \"ddns-override-no-update\": false,\n"
|
||||||
|
" \"ddns-qualifying-suffix\": \"\",\n"
|
||||||
|
" \"ddns-replace-client-name\": \"never\",\n"
|
||||||
|
" \"ddns-send-updates\": true,\n"
|
||||||
|
" \"ddns-ttl-max\": 750,\n"
|
||||||
|
" \"ddns-update-on-renew\": false,\n"
|
||||||
|
" \"decline-probation-period\": 86400,\n"
|
||||||
|
" \"dhcp-ddns\": {\n"
|
||||||
|
" \"enable-updates\": false,\n"
|
||||||
|
" \"max-queue-size\": 1024,\n"
|
||||||
|
" \"ncr-format\": \"JSON\",\n"
|
||||||
|
" \"ncr-protocol\": \"UDP\",\n"
|
||||||
|
" \"sender-ip\": \"0.0.0.0\",\n"
|
||||||
|
" \"sender-port\": 0,\n"
|
||||||
|
" \"server-ip\": \"127.0.0.1\",\n"
|
||||||
|
" \"server-port\": 53001\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp-queue-control\": {\n"
|
||||||
|
" \"capacity\": 64,\n"
|
||||||
|
" \"enable-queue\": false,\n"
|
||||||
|
" \"queue-type\": \"kea-ring4\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"dhcp4o6-port\": 0,\n"
|
||||||
|
" \"early-global-reservations-lookup\": false,\n"
|
||||||
|
" \"echo-client-id\": true,\n"
|
||||||
|
" \"expired-leases-processing\": {\n"
|
||||||
|
" \"flush-reclaimed-timer-wait-time\": 25,\n"
|
||||||
|
" \"hold-reclaimed-time\": 3600,\n"
|
||||||
|
" \"max-reclaim-leases\": 100,\n"
|
||||||
|
" \"max-reclaim-time\": 250,\n"
|
||||||
|
" \"reclaim-timer-wait-time\": 10,\n"
|
||||||
|
" \"unwarned-reclaim-cycles\": 5\n"
|
||||||
|
" },\n"
|
||||||
|
" \"hooks-libraries\": [ ],\n"
|
||||||
|
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
|
||||||
|
" \"hostname-char-replacement\": \"\",\n"
|
||||||
|
" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
|
||||||
|
" \"interfaces-config\": {\n"
|
||||||
|
" \"interfaces\": [ ],\n"
|
||||||
|
" \"re-detect\": false\n"
|
||||||
|
" },\n"
|
||||||
|
" \"ip-reservations-unique\": true,\n"
|
||||||
|
" \"lease-database\": {\n"
|
||||||
|
" \"type\": \"memfile\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"match-client-id\": true,\n"
|
||||||
|
" \"multi-threading\": {\n"
|
||||||
|
" \"enable-multi-threading\": true,\n"
|
||||||
|
" \"packet-queue-size\": 64,\n"
|
||||||
|
" \"thread-pool-size\": 0\n"
|
||||||
|
" },\n"
|
||||||
|
" \"next-server\": \"0.0.0.0\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"option-def\": [ ],\n"
|
||||||
|
" \"parked-packet-limit\": 256,\n"
|
||||||
|
" \"reservations-global\": false,\n"
|
||||||
|
" \"reservations-in-subnet\": true,\n"
|
||||||
|
" \"reservations-lookup-first\": false,\n"
|
||||||
|
" \"reservations-out-of-pool\": false,\n"
|
||||||
|
" \"sanity-checks\": {\n"
|
||||||
|
" \"extended-info-checks\": \"fix\",\n"
|
||||||
|
" \"lease-checks\": \"warn\"\n"
|
||||||
|
" },\n"
|
||||||
|
" \"server-hostname\": \"\",\n"
|
||||||
|
" \"server-tag\": \"\",\n"
|
||||||
|
" \"shared-networks\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl-max\": 500,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"name\": \"net\",\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"4o6-interface\": \"\",\n"
|
||||||
|
" \"4o6-interface-id\": \"\",\n"
|
||||||
|
" \"4o6-subnet\": \"\",\n"
|
||||||
|
" \"allocator\": \"iterative\",\n"
|
||||||
|
" \"calculate-tee-times\": false,\n"
|
||||||
|
" \"ddns-ttl-max\": 250,\n"
|
||||||
|
" \"id\": 1,\n"
|
||||||
|
" \"max-valid-lifetime\": 4000,\n"
|
||||||
|
" \"min-valid-lifetime\": 4000,\n"
|
||||||
|
" \"option-data\": [ ],\n"
|
||||||
|
" \"pools\": [ ],\n"
|
||||||
|
" \"relay\": {\n"
|
||||||
|
" \"ip-addresses\": [ ]\n"
|
||||||
|
" },\n"
|
||||||
|
" \"reservations\": [ ],\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet\": \"10.0.2.0/24\",\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"stash-agent-options\": false,\n"
|
||||||
|
" \"statistic-default-sample-age\": 0,\n"
|
||||||
|
" \"statistic-default-sample-count\": 20,\n"
|
||||||
|
" \"store-extended-info\": false,\n"
|
||||||
|
" \"subnet4\": [ ],\n"
|
||||||
|
" \"t1-percent\": 0.5,\n"
|
||||||
|
" \"t2-percent\": 0.875,\n"
|
||||||
|
" \"valid-lifetime\": 4000\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -284,6 +284,9 @@ public:
|
|||||||
cfg->sanityChecksLifetime("preferred-lifetime");
|
cfg->sanityChecksLifetime("preferred-lifetime");
|
||||||
cfg->sanityChecksLifetime("valid-lifetime");
|
cfg->sanityChecksLifetime("valid-lifetime");
|
||||||
|
|
||||||
|
/// Sanity check global ddns-ttl parameters
|
||||||
|
cfg->sanityChecksDdnsTtlParameters();
|
||||||
|
|
||||||
/// Shared network sanity checks
|
/// Shared network sanity checks
|
||||||
const SharedNetwork6Collection* networks = cfg->getCfgSharedNetworks6()->getAll();
|
const SharedNetwork6Collection* networks = cfg->getCfgSharedNetworks6()->getAll();
|
||||||
if (networks) {
|
if (networks) {
|
||||||
|
@ -86,6 +86,7 @@ CBControlDHCPv4::databaseConfigApply(const BackendSelector& backend_selector,
|
|||||||
|
|
||||||
// Sanity check it.
|
// Sanity check it.
|
||||||
external_cfg->sanityChecksLifetime("valid-lifetime");
|
external_cfg->sanityChecksLifetime("valid-lifetime");
|
||||||
|
external_cfg->sanityChecksDdnsTtlParameters();
|
||||||
|
|
||||||
// Now that we successfully fetched the new global parameters, let's
|
// Now that we successfully fetched the new global parameters, let's
|
||||||
// remove existing ones and merge them into the current configuration.
|
// remove existing ones and merge them into the current configuration.
|
||||||
@ -310,6 +311,7 @@ CBControlDHCPv4::databaseConfigApply(const BackendSelector& backend_selector,
|
|||||||
// ip-reservations-unique setting here. It will be applied when the
|
// ip-reservations-unique setting here. It will be applied when the
|
||||||
// configuration is committed.
|
// configuration is committed.
|
||||||
external_cfg->sanityChecksLifetime(*staging_cfg, "valid-lifetime");
|
external_cfg->sanityChecksLifetime(*staging_cfg, "valid-lifetime");
|
||||||
|
external_cfg->sanityChecksDdnsTtlParameters();
|
||||||
CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
|
CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -331,6 +333,7 @@ CBControlDHCPv4::databaseConfigApply(const BackendSelector& backend_selector,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
external_cfg->sanityChecksLifetime(*current_cfg, "valid-lifetime");
|
external_cfg->sanityChecksLifetime(*current_cfg, "valid-lifetime");
|
||||||
|
external_cfg->sanityChecksDdnsTtlParameters();
|
||||||
CfgMgr::instance().mergeIntoCurrentCfg(external_cfg->getSequence());
|
CfgMgr::instance().mergeIntoCurrentCfg(external_cfg->getSequence());
|
||||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->initAllocatorsAfterConfigure();
|
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->initAllocatorsAfterConfigure();
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,7 @@ CBControlDHCPv6::databaseConfigApply(const db::BackendSelector& backend_selector
|
|||||||
// Sanity check it.
|
// Sanity check it.
|
||||||
external_cfg->sanityChecksLifetime("preferred-lifetime");
|
external_cfg->sanityChecksLifetime("preferred-lifetime");
|
||||||
external_cfg->sanityChecksLifetime("valid-lifetime");
|
external_cfg->sanityChecksLifetime("valid-lifetime");
|
||||||
|
external_cfg->sanityChecksDdnsTtlParameters();
|
||||||
|
|
||||||
// Now that we successfully fetched the new global parameters, let's
|
// Now that we successfully fetched the new global parameters, let's
|
||||||
// remove existing ones and merge them into the current configuration.
|
// remove existing ones and merge them into the current configuration.
|
||||||
@ -325,6 +326,7 @@ CBControlDHCPv6::databaseConfigApply(const db::BackendSelector& backend_selector
|
|||||||
auto const& cfg = CfgMgr::instance().getStagingCfg();
|
auto const& cfg = CfgMgr::instance().getStagingCfg();
|
||||||
external_cfg->sanityChecksLifetime(*cfg, "preferred-lifetime");
|
external_cfg->sanityChecksLifetime(*cfg, "preferred-lifetime");
|
||||||
external_cfg->sanityChecksLifetime(*cfg, "valid-lifetime");
|
external_cfg->sanityChecksLifetime(*cfg, "valid-lifetime");
|
||||||
|
external_cfg->sanityChecksDdnsTtlParameters();
|
||||||
CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
|
CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -348,6 +350,7 @@ CBControlDHCPv6::databaseConfigApply(const db::BackendSelector& backend_selector
|
|||||||
auto const& cfg = CfgMgr::instance().getCurrentCfg();
|
auto const& cfg = CfgMgr::instance().getCurrentCfg();
|
||||||
external_cfg->sanityChecksLifetime(*cfg, "preferred-lifetime");
|
external_cfg->sanityChecksLifetime(*cfg, "preferred-lifetime");
|
||||||
external_cfg->sanityChecksLifetime(*cfg, "valid-lifetime");
|
external_cfg->sanityChecksLifetime(*cfg, "valid-lifetime");
|
||||||
|
external_cfg->sanityChecksDdnsTtlParameters();
|
||||||
CfgMgr::instance().mergeIntoCurrentCfg(external_cfg->getSequence());
|
CfgMgr::instance().mergeIntoCurrentCfg(external_cfg->getSequence());
|
||||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->initAllocatorsAfterConfigure();
|
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->initAllocatorsAfterConfigure();
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,9 @@ CfgGlobals::nameToIndex = {
|
|||||||
{ "multi-threading", MULTI_THREADING },
|
{ "multi-threading", MULTI_THREADING },
|
||||||
{ "sanity-checks", SANITY_CHECKS },
|
{ "sanity-checks", SANITY_CHECKS },
|
||||||
{ "dhcp-queue-control", DHCP_QUEUE_CONTROL },
|
{ "dhcp-queue-control", DHCP_QUEUE_CONTROL },
|
||||||
|
{ "ddns-ttl", DDNS_TTL },
|
||||||
|
{ "ddns-ttl-min", DDNS_TTL_MIN },
|
||||||
|
{ "ddns-ttl-max", DDNS_TTL_MAX },
|
||||||
|
|
||||||
// DHCPv4 specific parameters.
|
// DHCPv4 specific parameters.
|
||||||
{ "echo-client-id", ECHO_CLIENT_ID },
|
{ "echo-client-id", ECHO_CLIENT_ID },
|
||||||
|
@ -80,6 +80,9 @@ public:
|
|||||||
MULTI_THREADING,
|
MULTI_THREADING,
|
||||||
SANITY_CHECKS,
|
SANITY_CHECKS,
|
||||||
DHCP_QUEUE_CONTROL,
|
DHCP_QUEUE_CONTROL,
|
||||||
|
DDNS_TTL,
|
||||||
|
DDNS_TTL_MIN,
|
||||||
|
DDNS_TTL_MAX,
|
||||||
|
|
||||||
// DHCPv4 specific parameters.
|
// DHCPv4 specific parameters.
|
||||||
ECHO_CLIENT_ID,
|
ECHO_CLIENT_ID,
|
||||||
|
@ -49,7 +49,8 @@ extern const isc::log::MessageID DHCPSRV_CFGMGR_USE_UNICAST = "DHCPSRV_CFGMGR_US
|
|||||||
extern const isc::log::MessageID DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES = "DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES";
|
extern const isc::log::MessageID DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES = "DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES";
|
||||||
extern const isc::log::MessageID DHCPSRV_CLIENT_CLASS_DEPRECATED = "DHCPSRV_CLIENT_CLASS_DEPRECATED";
|
extern const isc::log::MessageID DHCPSRV_CLIENT_CLASS_DEPRECATED = "DHCPSRV_CLIENT_CLASS_DEPRECATED";
|
||||||
extern const isc::log::MessageID DHCPSRV_CLOSE_DB = "DHCPSRV_CLOSE_DB";
|
extern const isc::log::MessageID DHCPSRV_CLOSE_DB = "DHCPSRV_CLOSE_DB";
|
||||||
extern const isc::log::MessageID DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL = "DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL";
|
extern const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_LARGE = "DHCPSRV_DDNS_TTL_TOO_LARGE";
|
||||||
|
extern const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_SMALL = "DHCPSRV_DDNS_TTL_TOO_SMALL";
|
||||||
extern const isc::log::MessageID DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET = "DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET";
|
extern const isc::log::MessageID DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET = "DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET";
|
||||||
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION = "DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION";
|
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION = "DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION";
|
||||||
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_HANDLER_NULL = "DHCPSRV_DHCP_DDNS_HANDLER_NULL";
|
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_HANDLER_NULL = "DHCPSRV_DHCP_DDNS_HANDLER_NULL";
|
||||||
@ -220,7 +221,8 @@ const char* values[] = {
|
|||||||
"DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES", "class: %1 has 'only-in-additional-list' true while specifying one or more lease life time values. Life time values will be ignored.",
|
"DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES", "class: %1 has 'only-in-additional-list' true while specifying one or more lease life time values. Life time values will be ignored.",
|
||||||
"DHCPSRV_CLIENT_CLASS_DEPRECATED", "The parameter 'client-class' is deprecated. Use 'client-classes' list parameter instead",
|
"DHCPSRV_CLIENT_CLASS_DEPRECATED", "The parameter 'client-class' is deprecated. Use 'client-classes' list parameter instead",
|
||||||
"DHCPSRV_CLOSE_DB", "closing currently open %1 database",
|
"DHCPSRV_CLOSE_DB", "closing currently open %1 database",
|
||||||
"DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL", "ddns-ttl-percent %1 of lease lifetime %2 is too small, ignoring it",
|
"DHCPSRV_DDNS_TTL_TOO_LARGE", "%1 of lease life time %2 is %3, using maximum of %4 instead.",
|
||||||
|
"DHCPSRV_DDNS_TTL_TOO_SMALL", "%1 of lease life time %2 is %3, using minimum of %4 instead.",
|
||||||
"DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET", "received bad DHCPv4o6 packet: %1",
|
"DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET", "received bad DHCPv4o6 packet: %1",
|
||||||
"DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION", "error handler for DHCP_DDNS IO generated an expected exception: %1",
|
"DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION", "error handler for DHCP_DDNS IO generated an expected exception: %1",
|
||||||
"DHCPSRV_DHCP_DDNS_HANDLER_NULL", "error handler for DHCP_DDNS IO is not set.",
|
"DHCPSRV_DHCP_DDNS_HANDLER_NULL", "error handler for DHCP_DDNS IO is not set.",
|
||||||
|
@ -50,7 +50,8 @@ extern const isc::log::MessageID DHCPSRV_CFGMGR_USE_UNICAST;
|
|||||||
extern const isc::log::MessageID DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES;
|
extern const isc::log::MessageID DHCPSRV_CLASS_WITH_ADDITIONAL_AND_LIFETIMES;
|
||||||
extern const isc::log::MessageID DHCPSRV_CLIENT_CLASS_DEPRECATED;
|
extern const isc::log::MessageID DHCPSRV_CLIENT_CLASS_DEPRECATED;
|
||||||
extern const isc::log::MessageID DHCPSRV_CLOSE_DB;
|
extern const isc::log::MessageID DHCPSRV_CLOSE_DB;
|
||||||
extern const isc::log::MessageID DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL;
|
extern const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_LARGE;
|
||||||
|
extern const isc::log::MessageID DHCPSRV_DDNS_TTL_TOO_SMALL;
|
||||||
extern const isc::log::MessageID DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET;
|
extern const isc::log::MessageID DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET;
|
||||||
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION;
|
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION;
|
||||||
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_HANDLER_NULL;
|
extern const isc::log::MessageID DHCPSRV_DHCP_DDNS_HANDLER_NULL;
|
||||||
|
@ -267,14 +267,6 @@ the database access parameters are changed: in the latter case, the
|
|||||||
server closes the currently open database, and opens a database using
|
server closes the currently open database, and opens a database using
|
||||||
the new parameters.
|
the new parameters.
|
||||||
|
|
||||||
% DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL ddns-ttl-percent %1 of lease lifetime %2 is too small, ignoring it
|
|
||||||
Logged at debug log level 55.
|
|
||||||
A debug message issued when the DDNS TTL value calculated using the
|
|
||||||
ddns-ttl-percent is zero. Kea will ignore the value and calculate
|
|
||||||
the DDNS TTL as though ddsn-ttl-percent were not specified. The
|
|
||||||
value of ddns-ttl-percent and the lease lifetime are shown in
|
|
||||||
the message details.
|
|
||||||
|
|
||||||
% DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET received bad DHCPv4o6 packet: %1
|
% DHCPSRV_DHCP4O6_RECEIVED_BAD_PACKET received bad DHCPv4o6 packet: %1
|
||||||
A bad DHCPv4o6 packet was received.
|
A bad DHCPv4o6 packet was received.
|
||||||
|
|
||||||
@ -971,3 +963,20 @@ included in the message.
|
|||||||
% DHCPSRV_UNKNOWN_DB unknown database type: %1
|
% DHCPSRV_UNKNOWN_DB unknown database type: %1
|
||||||
The database access string specified a database type (given in the
|
The database access string specified a database type (given in the
|
||||||
message) that is unknown to the software. This is a configuration error.
|
message) that is unknown to the software. This is a configuration error.
|
||||||
|
|
||||||
|
% DHCPSRV_DDNS_TTL_TOO_SMALL %1 of lease life time %2 is %3, using minimum of %4 instead.
|
||||||
|
Logged at debug log level 55.
|
||||||
|
A debug message issued when the DDNS TTL value calculated using the
|
||||||
|
ddns-ttl-percent if specfieed or (0.33 if not) is too small. Kea will
|
||||||
|
ignore the value and is the minimum (ddns-ttl-min is specifed or 600
|
||||||
|
seconds if not). The message details include the percentage, the lease
|
||||||
|
life time, the calculated TTL, and the value actually used.
|
||||||
|
|
||||||
|
% DHCPSRV_DDNS_TTL_TOO_LARGE %1 of lease life time %2 is %3, using maximum of %4 instead.
|
||||||
|
Logged at debug log level 55.
|
||||||
|
A debug message issued when the DDNS TTL value calculated using the
|
||||||
|
ddns-ttl-percent if specfieed or (0.33 if not) is larger than the
|
||||||
|
the specified value of ddns-ttl-max. Kea will ignore the value and
|
||||||
|
use is the specified maxinimum instead. The message details include
|
||||||
|
the percentage, the lease life time, the calculated TTL, and the value
|
||||||
|
actually used.
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <dhcpsrv/ncr_generator.h>
|
#include <dhcpsrv/ncr_generator.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <util/str.h>
|
||||||
|
|
||||||
using namespace isc;
|
using namespace isc;
|
||||||
using namespace isc::dhcp;
|
using namespace isc::dhcp;
|
||||||
@ -52,6 +53,9 @@ void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
|
|||||||
|
|
||||||
ConflictResolutionMode conflict_resolution_mode = CHECK_WITH_DHCID;
|
ConflictResolutionMode conflict_resolution_mode = CHECK_WITH_DHCID;
|
||||||
util::Optional<double> ddns_ttl_percent;
|
util::Optional<double> ddns_ttl_percent;
|
||||||
|
util::Optional<uint32_t> ddns_ttl;
|
||||||
|
util::Optional<uint32_t> ddns_ttl_min;
|
||||||
|
util::Optional<uint32_t> ddns_ttl_max;
|
||||||
if (subnet) {
|
if (subnet) {
|
||||||
auto mode = subnet->getDdnsConflictResolutionMode();
|
auto mode = subnet->getDdnsConflictResolutionMode();
|
||||||
if (!mode.empty()) {
|
if (!mode.empty()) {
|
||||||
@ -59,6 +63,9 @@ void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ddns_ttl_percent = subnet->getDdnsTtlPercent();
|
ddns_ttl_percent = subnet->getDdnsTtlPercent();
|
||||||
|
ddns_ttl = subnet->getDdnsTtl();
|
||||||
|
ddns_ttl_min = subnet->getDdnsTtlMin();
|
||||||
|
ddns_ttl_max = subnet->getDdnsTtlMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -68,7 +75,9 @@ void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
|
|||||||
D2Dhcid dhcid = D2Dhcid(identifier, hostname_wire);
|
D2Dhcid dhcid = D2Dhcid(identifier, hostname_wire);
|
||||||
|
|
||||||
// Calculate the TTL based on lease life time.
|
// Calculate the TTL based on lease life time.
|
||||||
uint32_t ttl = calculateDdnsTtl(lease->valid_lft_, ddns_ttl_percent);
|
uint32_t ttl = calculateDdnsTtl(lease->valid_lft_,
|
||||||
|
ddns_ttl_percent, ddns_ttl,
|
||||||
|
ddns_ttl_min, ddns_ttl_max);
|
||||||
|
|
||||||
// Create name change request.
|
// Create name change request.
|
||||||
NameChangeRequestPtr ncr
|
NameChangeRequestPtr ncr
|
||||||
@ -131,27 +140,50 @@ void queueNCR(const NameChangeType& chg_type, const Lease6Ptr& lease) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t calculateDdnsTtl(uint32_t lease_lft, const util::Optional<double>& ddns_ttl_percent) {
|
uint32_t calculateDdnsTtl(uint32_t lease_lft,
|
||||||
// If we have a configured percentage use it to calculate TTL.
|
const util::Optional<double>& ddns_ttl_percent,
|
||||||
if (!ddns_ttl_percent.unspecified() && (ddns_ttl_percent.get() > 0.0)) {
|
const util::Optional<uint32_t>& ddns_ttl,
|
||||||
uint32_t new_lft = static_cast<uint32_t>(round(ddns_ttl_percent.get() * lease_lft));
|
const util::Optional<uint32_t>& ddns_ttl_min,
|
||||||
if (new_lft > 0) {
|
const util::Optional<uint32_t>& ddns_ttl_max) {
|
||||||
return (new_lft);
|
// If we have an explicit value use it.
|
||||||
} else {
|
if (!ddns_ttl.unspecified() && ddns_ttl.get() > 0) {
|
||||||
|
return (ddns_ttl.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use specified percentage (if one) or 1/3 as called for in RFC 4702.
|
||||||
|
double ttl_percent = (ddns_ttl_percent.get() > 0.0 ?
|
||||||
|
ddns_ttl_percent.get() : 0.33333);
|
||||||
|
|
||||||
|
// Calculate the ttl.
|
||||||
|
uint32_t ttl = static_cast<uint32_t>(round(ttl_percent * lease_lft));
|
||||||
|
|
||||||
|
// Adjust for minimum and maximum.
|
||||||
|
// If we have a custom mininum enforce it, otherwise per RFC 4702 it
|
||||||
|
// should not less than 600.
|
||||||
|
uint32_t ttl_min = (ddns_ttl_min.get() > 0) ? ddns_ttl_min.get() : 600;
|
||||||
|
if (ttl < ttl_min) {
|
||||||
|
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA,
|
||||||
|
DHCPSRV_DDNS_TTL_TOO_SMALL)
|
||||||
|
.arg(util::str::dumpDouble(ttl_percent))
|
||||||
|
.arg(lease_lft)
|
||||||
|
.arg(ttl)
|
||||||
|
.arg(ttl_min);
|
||||||
|
return (ttl_min);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have a maximum enforce it.
|
||||||
|
uint32_t ttl_max = ddns_ttl_max.get();
|
||||||
|
if (ttl_max && ttl > ttl_max) {
|
||||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA,
|
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL_DATA,
|
||||||
DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL)
|
DHCPSRV_DDNS_TTL_TOO_LARGE)
|
||||||
.arg(ddns_ttl_percent.get())
|
.arg(util::str::dumpDouble(ttl_percent))
|
||||||
.arg(lease_lft);
|
.arg(lease_lft)
|
||||||
}
|
.arg(ttl)
|
||||||
|
.arg(ttl_max);
|
||||||
|
return (ttl_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per RFC 4702 DDNS RR TTL should be given by:
|
return (ttl);
|
||||||
// ((lease life time / 3) < 10 minutes) ? 10 minutes : (lease life time / 3)
|
|
||||||
if (lease_lft < 1800) {
|
|
||||||
return (600);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (lease_lft / 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,22 +44,38 @@ void queueNCR(const dhcp_ddns::NameChangeType& chg_type, const Lease6Ptr& lease)
|
|||||||
|
|
||||||
/// @brief Calculates TTL for a DNS resource record based on lease life time.
|
/// @brief Calculates TTL for a DNS resource record based on lease life time.
|
||||||
///
|
///
|
||||||
/// If the parameter, ddns_ttl_percent is greater than zero, it is used to calculate
|
/// The logic for calculating TTL is as follow:
|
||||||
/// the TTL directly:
|
|
||||||
///
|
///
|
||||||
/// TTL = (lease life time * ddns-ttl-percent)
|
/// If ddns-ttl is specified use it unconditionally.
|
||||||
///
|
///
|
||||||
/// Otherwise it is calculated as per RFC 4702 Section 5:
|
/// If ddns-ttl-percnet is specified use it otherwise use 1/3 as
|
||||||
|
/// called for by RFC 4702.
|
||||||
///
|
///
|
||||||
/// TTL = ((lease life time / 3) < 10 minutes) ? 10 minutes : (lease life time / 3)
|
/// Calculate the candidate TTL based on the deteremined percentage.
|
||||||
|
///
|
||||||
|
/// If ddsn-ttl-min is specified used it otherwise use a minimum of
|
||||||
|
/// 600 per RFC 4702. If the TTL is less than the mininum return
|
||||||
|
/// the minimum.
|
||||||
|
///
|
||||||
|
/// If ddsn-ttl-max is specified limit the ttl to that value otherwse
|
||||||
|
/// return the ttl.
|
||||||
///
|
///
|
||||||
/// @param lease_life_time valid life time of the lease
|
/// @param lease_life_time valid life time of the lease
|
||||||
/// @param ddns_ttl_percent optional percentage to use in calculation
|
/// @param ddns_ttl_percent optional percentage to use in calculation
|
||||||
|
/// @param ddns_ttl optional percentage to use in calculation
|
||||||
|
/// @param ddns_ttl_min optional minium TTL to allow
|
||||||
|
/// @param ddns_ttl_max optional maximum TTL to allow
|
||||||
///
|
///
|
||||||
/// @return the calculated TTL.
|
/// @return the calculated TTL.
|
||||||
uint32_t calculateDdnsTtl(uint32_t lease_life_time,
|
uint32_t calculateDdnsTtl(uint32_t lease_life_time,
|
||||||
const util::Optional<double>& ddns_ttl_percent
|
const util::Optional<double>& ddns_ttl_percent
|
||||||
= util::Optional<double>());
|
= util::Optional<double>(),
|
||||||
|
const util::Optional<uint32_t>& ddns_ttl
|
||||||
|
= util::Optional<uint32_t>(),
|
||||||
|
const util::Optional<uint32_t>& ddns_ttl_min
|
||||||
|
= util::Optional<uint32_t>(),
|
||||||
|
const util::Optional<uint32_t>& ddns_ttl_max
|
||||||
|
= util::Optional<uint32_t>());
|
||||||
|
|
||||||
} // end of isc::dhcp namespace
|
} // end of isc::dhcp namespace
|
||||||
} // end of isc namespace
|
} // end of isc namespace
|
||||||
|
@ -231,6 +231,18 @@ Network::toElement() const {
|
|||||||
map->set("ddns-ttl-percent", Element::create(ddns_ttl_percent_));
|
map->set("ddns-ttl-percent", Element::create(ddns_ttl_percent_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ddns_ttl_.unspecified()) {
|
||||||
|
map->set("ddns-ttl", Element::create(ddns_ttl_));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ddns_ttl_min_.unspecified()) {
|
||||||
|
map->set("ddns-ttl-min", Element::create(ddns_ttl_min_));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ddns_ttl_max_.unspecified()) {
|
||||||
|
map->set("ddns-ttl-max", Element::create(ddns_ttl_max_));
|
||||||
|
}
|
||||||
|
|
||||||
if (!hostname_char_set_.unspecified()) {
|
if (!hostname_char_set_.unspecified()) {
|
||||||
map->set("hostname-char-set", Element::create(hostname_char_set_));
|
map->set("hostname-char-set", Element::create(hostname_char_set_));
|
||||||
}
|
}
|
||||||
|
@ -219,8 +219,9 @@ public:
|
|||||||
ddns_replace_client_name_mode_(), ddns_generated_prefix_(), ddns_qualifying_suffix_(),
|
ddns_replace_client_name_mode_(), ddns_generated_prefix_(), ddns_qualifying_suffix_(),
|
||||||
hostname_char_set_(), hostname_char_replacement_(), store_extended_info_(),
|
hostname_char_set_(), hostname_char_replacement_(), store_extended_info_(),
|
||||||
cache_threshold_(), cache_max_age_(), ddns_update_on_renew_(),
|
cache_threshold_(), cache_max_age_(), ddns_update_on_renew_(),
|
||||||
ddns_conflict_resolution_mode_(), ddns_ttl_percent_(), allocator_type_(),
|
ddns_conflict_resolution_mode_(), ddns_ttl_percent_(),
|
||||||
default_allocator_type_() {
|
ddns_ttl_(), ddns_ttl_min_(), ddns_ttl_max_(),
|
||||||
|
allocator_type_(), default_allocator_type_() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Virtual destructor.
|
/// @brief Virtual destructor.
|
||||||
@ -682,6 +683,59 @@ public:
|
|||||||
ddns_ttl_percent_ = ddns_ttl_percent;
|
ddns_ttl_percent_ = ddns_ttl_percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Returns ddns-ttl
|
||||||
|
///
|
||||||
|
/// @param inheritance inheritance mode to be used.
|
||||||
|
util::Optional<uint32_t>
|
||||||
|
getDdnsTtl(const Inheritance& inheritance = Inheritance::ALL) const {
|
||||||
|
return (getProperty<Network>(&Network::getDdnsTtl,
|
||||||
|
ddns_ttl_, inheritance,
|
||||||
|
CfgGlobals::DDNS_TTL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Sets new ddns-ttl
|
||||||
|
///
|
||||||
|
/// @param ddns_ttl New value to use.
|
||||||
|
void setDdnsTtl(const util::Optional<uint32_t>& ddns_ttl) {
|
||||||
|
ddns_ttl_ = ddns_ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Returns ddns-ttl-min
|
||||||
|
///
|
||||||
|
/// @param inheritance inheritance mode to be used.
|
||||||
|
util::Optional<uint32_t>
|
||||||
|
getDdnsTtlMin(const Inheritance& inheritance = Inheritance::ALL) const {
|
||||||
|
return (getProperty<Network>(&Network::getDdnsTtlMin,
|
||||||
|
ddns_ttl_min_, inheritance,
|
||||||
|
CfgGlobals::DDNS_TTL_MIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Sets new ddns-ttl-min
|
||||||
|
///
|
||||||
|
/// @param ddns_ttl_min New value to use.
|
||||||
|
void setDdnsTtlMin(const util::Optional<uint32_t>& ddns_ttl_min) {
|
||||||
|
ddns_ttl_min_ = ddns_ttl_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns ddns-ttl-max
|
||||||
|
///
|
||||||
|
/// @param inheritance inheritance mode to be used.
|
||||||
|
util::Optional<uint32_t>
|
||||||
|
getDdnsTtlMax(const Inheritance& inheritance = Inheritance::ALL) const {
|
||||||
|
return (getProperty<Network>(&Network::getDdnsTtlMax,
|
||||||
|
ddns_ttl_max_, inheritance,
|
||||||
|
CfgGlobals::DDNS_TTL_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Sets new ddns-ttl-max
|
||||||
|
///
|
||||||
|
/// @param ddns_ttl_max New value to use.
|
||||||
|
void setDdnsTtlMax(const util::Optional<uint32_t>& ddns_ttl_max) {
|
||||||
|
ddns_ttl_max_ = ddns_ttl_max;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Return the char set regexp used to sanitize client hostnames.
|
/// @brief Return the char set regexp used to sanitize client hostnames.
|
||||||
util::Optional<std::string>
|
util::Optional<std::string>
|
||||||
getHostnameCharSet(const Inheritance& inheritance = Inheritance::ALL) const {
|
getHostnameCharSet(const Inheritance& inheritance = Inheritance::ALL) const {
|
||||||
@ -1237,6 +1291,15 @@ protected:
|
|||||||
/// @brief Percentage of the lease lifetime to use for DNS TTL.
|
/// @brief Percentage of the lease lifetime to use for DNS TTL.
|
||||||
util::Optional<double> ddns_ttl_percent_;
|
util::Optional<double> ddns_ttl_percent_;
|
||||||
|
|
||||||
|
/// @brief Explicit value to use for DNS TTL.
|
||||||
|
util::Optional<uint32_t> ddns_ttl_;
|
||||||
|
|
||||||
|
/// @brief Minimum value to use for DNS TTL.
|
||||||
|
util::Optional<uint32_t> ddns_ttl_min_;
|
||||||
|
|
||||||
|
/// @brief Maximum value to use for DNS TTL.
|
||||||
|
util::Optional<uint32_t> ddns_ttl_max_;
|
||||||
|
|
||||||
/// @brief Allocator used for IP address allocations.
|
/// @brief Allocator used for IP address allocations.
|
||||||
util::Optional<std::string> allocator_type_;
|
util::Optional<std::string> allocator_type_;
|
||||||
|
|
||||||
|
@ -197,10 +197,46 @@ BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
|
|||||||
network->setDdnsUpdateOnRenew(getBoolean(network_data, "ddns-update-on-renew"));
|
network->setDdnsUpdateOnRenew(getBoolean(network_data, "ddns-update-on-renew"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_ddns_ttl = false;
|
||||||
|
uint32_t ddns_ttl = 0;
|
||||||
|
if (network_data->contains("ddns-ttl")) {
|
||||||
|
ddns_ttl = getInteger(network_data, "ddns-ttl");
|
||||||
|
network->setDdnsTtl(ddns_ttl);
|
||||||
|
has_ddns_ttl = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (network_data->contains("ddns-ttl-percent")) {
|
if (network_data->contains("ddns-ttl-percent")) {
|
||||||
|
if (has_ddns_ttl) {
|
||||||
|
isc_throw(BadValue, "cannot specify both ddns-ttl-percent and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
network->setDdnsTtlPercent(getDouble(network_data, "ddns-ttl-percent"));
|
network->setDdnsTtlPercent(getDouble(network_data, "ddns-ttl-percent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ddns_ttl_min = 0;
|
||||||
|
if (network_data->contains("ddns-ttl-min")) {
|
||||||
|
if (has_ddns_ttl) {
|
||||||
|
isc_throw(BadValue, "cannot specify both ddns-ttl-min and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
ddns_ttl_min = getInteger(network_data, "ddns-ttl-min");
|
||||||
|
network->setDdnsTtlMin(ddns_ttl_min);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (network_data->contains("ddns-ttl-max")) {
|
||||||
|
if (has_ddns_ttl) {
|
||||||
|
isc_throw(BadValue, "cannot specify both ddns-ttl-max and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ddns_ttl_max = getInteger(network_data, "ddns-ttl-max");
|
||||||
|
if (ddns_ttl_max < ddns_ttl_min) {
|
||||||
|
isc_throw(BadValue, "ddns-ttl-max: " << ddns_ttl_max
|
||||||
|
<< " must be greater than ddns-ttl-min: " << ddns_ttl_min);
|
||||||
|
}
|
||||||
|
|
||||||
|
network->setDdnsTtlMax(ddns_ttl_max);
|
||||||
|
}
|
||||||
|
|
||||||
// For backward compatibility, ddns-conflict-resolution-mode is optional.
|
// For backward compatibility, ddns-conflict-resolution-mode is optional.
|
||||||
if (network_data->contains("ddns-conflict-resolution-mode")) {
|
if (network_data->contains("ddns-conflict-resolution-mode")) {
|
||||||
network->setDdnsConflictResolutionMode(getString(network_data,
|
network->setDdnsConflictResolutionMode(getString(network_data,
|
||||||
|
@ -101,6 +101,9 @@ const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = {
|
|||||||
{ "ddns-ttl-percent", Element::real },
|
{ "ddns-ttl-percent", Element::real },
|
||||||
{ "ddns-conflict-resolution-mode", Element::string },
|
{ "ddns-conflict-resolution-mode", Element::string },
|
||||||
{ "stash-agent-options", Element::boolean },
|
{ "stash-agent-options", Element::boolean },
|
||||||
|
{ "ddns-ttl", Element::integer },
|
||||||
|
{ "ddns-ttl-min", Element::integer },
|
||||||
|
{ "ddns-ttl-max", Element::integer },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief This table defines default global values for DHCPv4
|
/// @brief This table defines default global values for DHCPv4
|
||||||
@ -261,6 +264,9 @@ const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = {
|
|||||||
{ "offer-lifetime", Element::integer },
|
{ "offer-lifetime", Element::integer },
|
||||||
{ "ddns-ttl-percent", Element::real },
|
{ "ddns-ttl-percent", Element::real },
|
||||||
{ "ddns-conflict-resolution-mode", Element::string },
|
{ "ddns-conflict-resolution-mode", Element::string },
|
||||||
|
{ "ddns-ttl", Element::integer },
|
||||||
|
{ "ddns-ttl-min", Element::integer },
|
||||||
|
{ "ddns-ttl-max", Element::integer },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief This table defines default values for each IPv4 subnet.
|
/// @brief This table defines default values for each IPv4 subnet.
|
||||||
@ -388,6 +394,9 @@ const SimpleKeywords SimpleParser4::SHARED_NETWORK4_PARAMETERS = {
|
|||||||
{ "offer-lifetime", Element::integer },
|
{ "offer-lifetime", Element::integer },
|
||||||
{ "ddns-ttl-percent", Element::real },
|
{ "ddns-ttl-percent", Element::real },
|
||||||
{ "ddns-conflict-resolution-mode", Element::string },
|
{ "ddns-conflict-resolution-mode", Element::string },
|
||||||
|
{ "ddns-ttl", Element::integer },
|
||||||
|
{ "ddns-ttl-min", Element::integer },
|
||||||
|
{ "ddns-ttl-max", Element::integer },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief This table defines default values for interfaces for DHCPv4.
|
/// @brief This table defines default values for interfaces for DHCPv4.
|
||||||
|
@ -100,6 +100,9 @@ const SimpleKeywords SimpleParser6::GLOBAL6_PARAMETERS = {
|
|||||||
{ "pd-allocator", Element::string },
|
{ "pd-allocator", Element::string },
|
||||||
{ "ddns-ttl-percent", Element::real },
|
{ "ddns-ttl-percent", Element::real },
|
||||||
{ "ddns-conflict-resolution-mode", Element::string },
|
{ "ddns-conflict-resolution-mode", Element::string },
|
||||||
|
{ "ddns-ttl", Element::integer },
|
||||||
|
{ "ddns-ttl-min", Element::integer },
|
||||||
|
{ "ddns-ttl-max", Element::integer },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief This table defines default global values for DHCPv6
|
/// @brief This table defines default global values for DHCPv6
|
||||||
@ -253,6 +256,9 @@ const SimpleKeywords SimpleParser6::SUBNET6_PARAMETERS = {
|
|||||||
{ "pd-allocator", Element::string },
|
{ "pd-allocator", Element::string },
|
||||||
{ "ddns-ttl-percent", Element::real },
|
{ "ddns-ttl-percent", Element::real },
|
||||||
{ "ddns-conflict-resolution-mode", Element::string },
|
{ "ddns-conflict-resolution-mode", Element::string },
|
||||||
|
{ "ddns-ttl", Element::integer },
|
||||||
|
{ "ddns-ttl-min", Element::integer },
|
||||||
|
{ "ddns-ttl-max", Element::integer },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief This table defines default values for each IPv6 subnet.
|
/// @brief This table defines default values for each IPv6 subnet.
|
||||||
@ -401,6 +407,9 @@ const SimpleKeywords SimpleParser6::SHARED_NETWORK6_PARAMETERS = {
|
|||||||
{ "pd-allocator", Element::string },
|
{ "pd-allocator", Element::string },
|
||||||
{ "ddns-ttl-percent", Element::real },
|
{ "ddns-ttl-percent", Element::real },
|
||||||
{ "ddns-conflict-resolution-mode", Element::string },
|
{ "ddns-conflict-resolution-mode", Element::string },
|
||||||
|
{ "ddns-ttl", Element::integer },
|
||||||
|
{ "ddns-ttl-min", Element::integer },
|
||||||
|
{ "ddns-ttl-max", Element::integer },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief This table defines default values for interfaces for DHCPv6.
|
/// @brief This table defines default values for interfaces for DHCPv6.
|
||||||
|
@ -1057,6 +1057,42 @@ DdnsParams::getHostnameSanitizer() const {
|
|||||||
return (sanitizer);
|
return (sanitizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SrvConfig::sanityChecksDdnsTtlParameters() const {
|
||||||
|
// Need to check that global DDNS TTL values make sense
|
||||||
|
|
||||||
|
// Get ddns-ttl first. If ddns-ttl is specified none of the others should be.
|
||||||
|
ConstElementPtr has_ddns_ttl = getConfiguredGlobal("ddns-ttl");
|
||||||
|
|
||||||
|
if (getConfiguredGlobal("ddns-ttl-percent")) {
|
||||||
|
if (has_ddns_ttl) {
|
||||||
|
isc_throw(BadValue, "cannot specify both ddns-ttl-percent and ddns-ttl");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstElementPtr has_ddns_ttl_min = getConfiguredGlobal("ddns-ttl-min");
|
||||||
|
if (has_ddns_ttl_min && has_ddns_ttl) {
|
||||||
|
isc_throw(BadValue, "cannot specify both ddns-ttl-min and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstElementPtr has_ddns_ttl_max = getConfiguredGlobal("ddns-ttl-max");
|
||||||
|
if (has_ddns_ttl_max) {
|
||||||
|
if (has_ddns_ttl) {
|
||||||
|
isc_throw(BadValue, "cannot specify both ddns-ttl-max and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_ddns_ttl_min) {
|
||||||
|
// Have min and max, make sure the range is sane.
|
||||||
|
uint32_t ddns_ttl_min = has_ddns_ttl_min->intValue();
|
||||||
|
uint32_t ddns_ttl_max = has_ddns_ttl_max->intValue();
|
||||||
|
if (ddns_ttl_max < ddns_ttl_min) {
|
||||||
|
isc_throw(BadValue, "ddns-ttl-max: " << ddns_ttl_max
|
||||||
|
<< " must be greater than ddns-ttl-min: " << ddns_ttl_min);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DdnsParams::getUpdateOnRenew() const {
|
DdnsParams::getUpdateOnRenew() const {
|
||||||
if (!subnet_) {
|
if (!subnet_) {
|
||||||
@ -1075,6 +1111,33 @@ DdnsParams::getTtlPercent() const {
|
|||||||
return (subnet_->getDdnsTtlPercent());
|
return (subnet_->getDdnsTtlPercent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
util::Optional<uint32_t>
|
||||||
|
DdnsParams::getTtl() const {
|
||||||
|
if (!subnet_) {
|
||||||
|
return (util::Optional<uint32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (subnet_->getDdnsTtl());
|
||||||
|
}
|
||||||
|
|
||||||
|
util::Optional<uint32_t>
|
||||||
|
DdnsParams::getTtlMin() const {
|
||||||
|
if (!subnet_) {
|
||||||
|
return (util::Optional<uint32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (subnet_->getDdnsTtlMin());
|
||||||
|
}
|
||||||
|
|
||||||
|
util::Optional<uint32_t>
|
||||||
|
DdnsParams::getTtlMax() const {
|
||||||
|
if (!subnet_) {
|
||||||
|
return (util::Optional<uint32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (subnet_->getDdnsTtlMax());
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
DdnsParams::getConflictResolutionMode() const {
|
DdnsParams::getConflictResolutionMode() const {
|
||||||
if (!subnet_) {
|
if (!subnet_) {
|
||||||
|
@ -150,6 +150,30 @@ public:
|
|||||||
/// @return TTL percent as an Optional.
|
/// @return TTL percent as an Optional.
|
||||||
util::Optional<double> getTtlPercent() const;
|
util::Optional<double> getTtlPercent() const;
|
||||||
|
|
||||||
|
/// @brief Returns explicit TTL to use
|
||||||
|
///
|
||||||
|
/// This value, if greater than zero, is used as the lifetime
|
||||||
|
/// passed to D2 in the NCR.
|
||||||
|
///
|
||||||
|
/// @return TTL as an Optional.
|
||||||
|
util::Optional<uint32_t> getTtl() const;
|
||||||
|
|
||||||
|
/// @brief Returns the minimum TTL to use
|
||||||
|
///
|
||||||
|
/// This value, if greater than zero, is used as the lower boundary
|
||||||
|
/// for calculated TTLs.
|
||||||
|
///
|
||||||
|
/// @return TTL minimum as an Optional.
|
||||||
|
util::Optional<uint32_t> getTtlMin() const;
|
||||||
|
|
||||||
|
/// @brief Returns the maximum TTL to use
|
||||||
|
///
|
||||||
|
/// This value, if greater than zero, is used as the upper boundary
|
||||||
|
/// for calculated TTLs.
|
||||||
|
///
|
||||||
|
/// @return TTL maximum as an Optional.
|
||||||
|
util::Optional<uint32_t> getTtlMax() const;
|
||||||
|
|
||||||
/// @brief Returns the DDNS config resolution mode for kea-dhcp-ddns
|
/// @brief Returns the DDNS config resolution mode for kea-dhcp-ddns
|
||||||
///
|
///
|
||||||
/// This value is communicated to D2 via the NCR.
|
/// This value is communicated to D2 via the NCR.
|
||||||
@ -951,6 +975,16 @@ public:
|
|||||||
void sanityChecksLifetime(const SrvConfig& target_config,
|
void sanityChecksLifetime(const SrvConfig& target_config,
|
||||||
const std::string& name) const;
|
const std::string& name) const;
|
||||||
|
|
||||||
|
/// @brief Conducts sanity checks on global DDNS ttl parameters:
|
||||||
|
/// ddsn-ttl, ddsn-ttl-percent, ddns-ttl-min, ddns-ttl-max
|
||||||
|
///
|
||||||
|
/// If ddns-ttl is specified none of the others can be
|
||||||
|
/// If ddns-ttl-min and ddsn-ttl-max are specified max cannot
|
||||||
|
/// be less than min.
|
||||||
|
///
|
||||||
|
/// @throw Throws BadValue if any of the rules are violated.
|
||||||
|
void sanityChecksDdnsTtlParameters() const;
|
||||||
|
|
||||||
/// @brief Configures the server to allow or disallow specifying multiple
|
/// @brief Configures the server to allow or disallow specifying multiple
|
||||||
/// hosts with the same IP address/subnet.
|
/// hosts with the same IP address/subnet.
|
||||||
///
|
///
|
||||||
|
@ -72,6 +72,161 @@ public:
|
|||||||
void resetIfaceCfg() {
|
void resetIfaceCfg() {
|
||||||
CfgMgr::instance().clear();
|
CfgMgr::instance().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verifies valid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for SubnetX.
|
||||||
|
template<typename ParserType, typename NetworkPtrType>
|
||||||
|
void validDdnsTtlParmatersSubnet(int family) {
|
||||||
|
struct Scenario {
|
||||||
|
size_t line_no_;
|
||||||
|
std::string json_;
|
||||||
|
double ddns_ttl_percent_;
|
||||||
|
uint32_t ddns_ttl_;
|
||||||
|
uint32_t ddns_ttl_min_;
|
||||||
|
uint32_t ddns_ttl_max_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::list<Scenario> scenarios = {
|
||||||
|
{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl": 100
|
||||||
|
})^",
|
||||||
|
0.0, 100, 0, 0
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl-percent": 5.0
|
||||||
|
})^",
|
||||||
|
5.0, 0, 0, 0
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl-min": 25
|
||||||
|
})^",
|
||||||
|
0.0, 0, 25, 0
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
0.0, 0, 0, 150
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl-min": 25,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
0.0, 0, 25, 150
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1, "subnet": "192.0.2.0/24",
|
||||||
|
"ddns-ttl-percent": 5.0,
|
||||||
|
"ddns-ttl-min": 25,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
5.0, 0, 25, 150
|
||||||
|
}};
|
||||||
|
|
||||||
|
ElementPtr subnet_elem = Element::create(family == AF_INET ?
|
||||||
|
"192.0.2.0/24" : "2001:db8::/64");
|
||||||
|
for (const auto& scenario : scenarios) {
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << "scenario at " << scenario.line_no_;
|
||||||
|
SCOPED_TRACE(oss.str());
|
||||||
|
|
||||||
|
// Parse configuration specified above.
|
||||||
|
ElementPtr config_element;
|
||||||
|
ASSERT_NO_THROW_LOG(config_element = Element::fromJSON(scenario.json_));
|
||||||
|
config_element->set("subnet", subnet_elem);
|
||||||
|
|
||||||
|
ParserType parser(family);
|
||||||
|
|
||||||
|
NetworkPtrType subnet;
|
||||||
|
|
||||||
|
ASSERT_NO_THROW_LOG(subnet = parser.parse(config_element));
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtlPercent().unspecified(), (scenario.ddns_ttl_percent_ == 0.0));
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtlPercent(), scenario.ddns_ttl_percent_);
|
||||||
|
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtl().unspecified(), (scenario.ddns_ttl_ == 0));
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtl(), scenario.ddns_ttl_);
|
||||||
|
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtlMin().unspecified(), (scenario.ddns_ttl_min_ == 0));
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtlMin(), scenario.ddns_ttl_min_);
|
||||||
|
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtlMax().unspecified(), (scenario.ddns_ttl_max_ == 0));
|
||||||
|
EXPECT_EQ(subnet->getDdnsTtlMax(), scenario.ddns_ttl_max_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies invalid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for SubnetX.
|
||||||
|
template<typename ParserType>
|
||||||
|
void invalidDdnsTtlParmatersSubnet(int family) {
|
||||||
|
struct Scenario {
|
||||||
|
size_t line_no_;
|
||||||
|
std::string json_;
|
||||||
|
std::string exp_message_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::list<Scenario> scenarios = {
|
||||||
|
{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl-percent": 5.0,
|
||||||
|
"ddns-ttl": 100
|
||||||
|
})^",
|
||||||
|
"subnet configuration failed: cannot specify both ddns-ttl-percent and ddns-ttl"
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl": 100,
|
||||||
|
"ddns-ttl-min": 25
|
||||||
|
})^",
|
||||||
|
"subnet configuration failed: cannot specify both ddns-ttl-min and ddns-ttl"
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl": 100,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
"subnet configuration failed: cannot specify both ddns-ttl-max and ddns-ttl"
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"id": 1,
|
||||||
|
"ddns-ttl-min": 150,
|
||||||
|
"ddns-ttl-max": 25
|
||||||
|
})^",
|
||||||
|
"subnet configuration failed: ddns-ttl-max: 25 must be greater than ddns-ttl-min: 150"
|
||||||
|
}};
|
||||||
|
|
||||||
|
ElementPtr subnet_elem = Element::create(family == AF_INET ?
|
||||||
|
"192.0.2.0/24" : "2001:db8::/64");
|
||||||
|
for (const auto& scenario : scenarios) {
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << "scenario at " << scenario.line_no_;
|
||||||
|
SCOPED_TRACE(oss.str());
|
||||||
|
|
||||||
|
// Parse configuration specified above.
|
||||||
|
ElementPtr config_element;
|
||||||
|
ASSERT_NO_THROW_LOG(config_element = Element::fromJSON(scenario.json_));
|
||||||
|
config_element->set("subnet", subnet_elem);
|
||||||
|
ParserType parser(family);
|
||||||
|
ASSERT_THROW_MSG(parser.parse(config_element), DhcpConfigError, scenario.exp_message_);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Verifies the code that parses mac sources and adds them to CfgMgr
|
/// Verifies the code that parses mac sources and adds them to CfgMgr
|
||||||
@ -4115,4 +4270,28 @@ TEST_F(DhcpParserTest, deprecatedClientClassPool6) {
|
|||||||
" 'client-classes'. Use only the latter.");
|
" 'client-classes'. Use only the latter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verifies valid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for Subnet4.
|
||||||
|
TEST_F(DhcpParserTest, validDdnsTtlParmatersSubnet4) {
|
||||||
|
validDdnsTtlParmatersSubnet<Subnet4ConfigParser, Subnet4Ptr>(AF_INET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies invalid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for Subnet4.
|
||||||
|
TEST_F(DhcpParserTest, invalidDdnsTtlParmatersSubnet4) {
|
||||||
|
invalidDdnsTtlParmatersSubnet<Subnet4ConfigParser>(AF_INET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies valid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for Subnet6.
|
||||||
|
TEST_F(DhcpParserTest, validDdnsTtlParmatersSubnet6) {
|
||||||
|
validDdnsTtlParmatersSubnet<Subnet6ConfigParser, Subnet6Ptr>(AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies invalid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for Subnet6.
|
||||||
|
TEST_F(DhcpParserTest, invalidDdnsTtlParmatersSubnet6) {
|
||||||
|
invalidDdnsTtlParmatersSubnet<Subnet6ConfigParser>(AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
@ -234,14 +234,18 @@ public:
|
|||||||
void testNCR(const NameChangeType chg_type, const bool fwd, const bool rev,
|
void testNCR(const NameChangeType chg_type, const bool fwd, const bool rev,
|
||||||
const std::string& fqdn, const std::string exp_dhcid,
|
const std::string& fqdn, const std::string exp_dhcid,
|
||||||
const ConflictResolutionMode exp_cr_mode = CHECK_WITH_DHCID,
|
const ConflictResolutionMode exp_cr_mode = CHECK_WITH_DHCID,
|
||||||
const Optional<double> ttl_percent = Optional<double>()) {
|
const Optional<double> ddns_ttl_percent = Optional<double>(),
|
||||||
|
const Optional<uint32_t> ddns_ttl = Optional<uint32_t>(),
|
||||||
|
const Optional<uint32_t> ddns_ttl_min = Optional<uint32_t>(),
|
||||||
|
const Optional<uint32_t> ddns_ttl_max = Optional<uint32_t>()) {
|
||||||
// Queue NCR.
|
// Queue NCR.
|
||||||
ASSERT_NO_FATAL_FAILURE(sendNCR(chg_type, fwd, rev, fqdn));
|
ASSERT_NO_FATAL_FAILURE(sendNCR(chg_type, fwd, rev, fqdn));
|
||||||
// Expecting one NCR be generated.
|
// Expecting one NCR be generated.
|
||||||
ASSERT_EQ(1, d2_mgr_.getQueueSize());
|
ASSERT_EQ(1, d2_mgr_.getQueueSize());
|
||||||
|
|
||||||
// Calculate expected ttl.
|
// Calculate expected ttl.
|
||||||
uint32_t ttl = calculateDdnsTtl(lease_->valid_lft_, ttl_percent);
|
uint32_t ttl = calculateDdnsTtl(lease_->valid_lft_, ddns_ttl_percent,
|
||||||
|
ddns_ttl, ddns_ttl_min, ddns_ttl_max);
|
||||||
|
|
||||||
// Check the details of the NCR.
|
// Check the details of the NCR.
|
||||||
verifyNameChangeRequest(chg_type, rev, fwd, lease_->addr_.toText(), exp_dhcid,
|
verifyNameChangeRequest(chg_type, rev, fwd, lease_->addr_.toText(), exp_dhcid,
|
||||||
@ -719,55 +723,83 @@ TEST_F(NCRGenerator4Test, conflictResolutionMode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that calculateDdnsTtl() produces the expected values.
|
// Verify that calculateDdnsTtl(), called by queueNcr()
|
||||||
TEST_F(NCRGenerator4Test, calculateDdnsTtl) {
|
// produces the expected values. Note there is no v6
|
||||||
|
// version of this test as v4 and v6 use the same code.
|
||||||
|
TEST_F(NCRGenerator4Test, calculateDdnsTtlThroughQueueNcr) {
|
||||||
|
struct Scenario {
|
||||||
|
size_t line_no_;
|
||||||
|
uint32_t lease_lft_;
|
||||||
|
Optional<double> ddns_ttl_percent_;
|
||||||
|
Optional<uint32_t> ddns_ttl_;
|
||||||
|
Optional<uint32_t> ddns_ttl_min_;
|
||||||
|
Optional<uint32_t> ddns_ttl_max_;
|
||||||
|
uint32_t exp_ttl_;
|
||||||
|
};
|
||||||
|
|
||||||
// A life time less than or equal to 1800 should yield a TTL of 600 seconds.
|
Optional<double> no_percent;
|
||||||
EXPECT_EQ(600, calculateDdnsTtl(100));
|
Optional<uint32_t> no_ttl;
|
||||||
|
Optional<uint32_t> no_min;
|
||||||
|
Optional<uint32_t> no_max;
|
||||||
|
|
||||||
// A life time > 1800 should be 1/3 of the value.
|
std::list<Scenario> scenarios = {
|
||||||
EXPECT_EQ(601, calculateDdnsTtl(1803));
|
// No modifiers, should be RFC % (i.e lft / 3)
|
||||||
|
{ __LINE__, 2100, no_percent, no_ttl, no_min, no_max, 700 },
|
||||||
|
|
||||||
// Now check permutations of values for ddns-ttl-percent.
|
// No modifiers, RFC % < RFC minium 600
|
||||||
util::Optional<double> ddns_ttl_percent;
|
{ __LINE__, 1500, no_percent, no_ttl, no_min, no_max, 600 },
|
||||||
|
|
||||||
// Unspecified percent should result in normal per RFC calculation.
|
// RFC % < specified minimum
|
||||||
EXPECT_EQ(601, calculateDdnsTtl(1803, ddns_ttl_percent));
|
{ __LINE__, 2100, no_percent, no_ttl, 800, no_max, 800 },
|
||||||
|
|
||||||
// A percentage of zero should be ignored.
|
// RFC % > specified maximum
|
||||||
ddns_ttl_percent = 0.0;
|
{ __LINE__, 2100, no_percent, no_ttl, no_min, 500, 500 },
|
||||||
EXPECT_EQ(601, calculateDdnsTtl(1803, ddns_ttl_percent));
|
|
||||||
|
|
||||||
// A percentage that results in near zero should be ignored.
|
// Explicit ttl
|
||||||
ddns_ttl_percent = 0.000005;
|
{ __LINE__, 2100, no_percent, 900, no_min, no_max, 900 },
|
||||||
EXPECT_EQ(601, calculateDdnsTtl(1803, ddns_ttl_percent));
|
|
||||||
|
|
||||||
// A large enough percentage should be used.
|
// Explicit ttl wins over specified percent
|
||||||
ddns_ttl_percent = 0.01;
|
{ __LINE__, 2100, 0.25, 900, no_min, no_max, 900 },
|
||||||
EXPECT_EQ(18, calculateDdnsTtl(1803, ddns_ttl_percent));
|
|
||||||
|
|
||||||
// A large enough percentage should be used.
|
// Explicit ttl wins over specified minumum
|
||||||
ddns_ttl_percent = 1.50;
|
{ __LINE__, 2100, no_percent, 900, 1000, no_max, 900 },
|
||||||
EXPECT_EQ(2705, calculateDdnsTtl(1803, ddns_ttl_percent));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that ddns-ttl-percent is used correctly by v4 queueNCR()
|
// Explicit ttl wins over specified maxiumum
|
||||||
TEST_F(NCRGenerator4Test, withTtlPercent) {
|
{ __LINE__, 2100, no_percent, 900, no_min, 800, 900 },
|
||||||
{
|
|
||||||
SCOPED_TRACE("Ttl percent of 0");
|
// Specified percent > RFC minumum
|
||||||
Optional<double> ttl_percent(0);
|
{ __LINE__, 2100, 0.5, no_ttl, no_min, no_max, 1050 },
|
||||||
subnet_->setDdnsTtlPercent(ttl_percent);
|
|
||||||
testNCR(CHG_REMOVE, true, true, "MYHOST.example.com.",
|
// Specified percent < RFC minumum
|
||||||
|
{ __LINE__, 2100, 0.25, no_ttl, no_min, no_max, 600 },
|
||||||
|
|
||||||
|
// Specified percent < specified minimum < RFC minimum
|
||||||
|
{ __LINE__, 2100, 0.10, no_ttl, 300 , no_max, 300 },
|
||||||
|
|
||||||
|
// Specified percent > specified maximum
|
||||||
|
{ __LINE__, 2100, 0.50, no_ttl, no_min, 800, 800 },
|
||||||
|
|
||||||
|
// Specified percent > lft
|
||||||
|
{ __LINE__, 2100, 1.50, no_ttl, no_min, no_max, 3150 },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& scenario : scenarios) {
|
||||||
|
lease_->valid_lft_ = scenario.lease_lft_;
|
||||||
|
subnet_->setDdnsTtlPercent(scenario.ddns_ttl_percent_);
|
||||||
|
subnet_->setDdnsTtl(scenario.ddns_ttl_);
|
||||||
|
subnet_->setDdnsTtlMin(scenario.ddns_ttl_min_);
|
||||||
|
subnet_->setDdnsTtlMax(scenario.ddns_ttl_max_);
|
||||||
|
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << "scenario at: " << scenario.line_no_;
|
||||||
|
SCOPED_TRACE(oss.str());
|
||||||
|
testNCR(CHG_ADD, true, true, "MYHOST.example.com.",
|
||||||
"000001E356D43E5F0A496D65BCA24D982D646140813E3"
|
"000001E356D43E5F0A496D65BCA24D982D646140813E3"
|
||||||
"B03AB370BFF46BFA309AE7BFD", CHECK_WITH_DHCID, ttl_percent);
|
"B03AB370BFF46BFA309AE7BFD", CHECK_WITH_DHCID,
|
||||||
}
|
scenario.ddns_ttl_percent_,
|
||||||
{
|
scenario.ddns_ttl_,
|
||||||
SCOPED_TRACE("Ttl percent of 1.5");
|
scenario.ddns_ttl_min_,
|
||||||
Optional<double> ttl_percent(1.5);
|
scenario.ddns_ttl_max_);
|
||||||
subnet_->setDdnsTtlPercent(ttl_percent);
|
|
||||||
testNCR(CHG_REMOVE, true, true, "MYHOST.example.com.",
|
|
||||||
"000001E356D43E5F0A496D65BCA24D982D646140813E3"
|
|
||||||
"B03AB370BFF46BFA309AE7BFD", CHECK_WITH_DHCID, ttl_percent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +183,9 @@ TEST_F(NetworkTest, inheritanceSupport4) {
|
|||||||
globals_->set("allocator", Element::create("random"));
|
globals_->set("allocator", Element::create("random"));
|
||||||
globals_->set("offer-lifetime", Element::create(45));
|
globals_->set("offer-lifetime", Element::create(45));
|
||||||
globals_->set("ddns-ttl-percent", Element::create(0.75));
|
globals_->set("ddns-ttl-percent", Element::create(0.75));
|
||||||
|
globals_->set("ddns-ttl", Element::create(400));
|
||||||
|
globals_->set("ddns-ttl-min", Element::create(200));
|
||||||
|
globals_->set("ddns-ttl-max", Element::create(600));
|
||||||
|
|
||||||
// For each parameter for which inheritance is supported run
|
// For each parameter for which inheritance is supported run
|
||||||
// the test that checks if the values are inherited properly.
|
// the test that checks if the values are inherited properly.
|
||||||
@ -372,6 +375,24 @@ TEST_F(NetworkTest, inheritanceSupport4) {
|
|||||||
&Network::setDdnsTtlPercent,
|
&Network::setDdnsTtlPercent,
|
||||||
.33, .75);
|
.33, .75);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl");
|
||||||
|
testNetworkInheritance<TestNetwork4>(&Network::getDdnsTtl,
|
||||||
|
&Network::setDdnsTtl,
|
||||||
|
300, 400);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl-min");
|
||||||
|
testNetworkInheritance<TestNetwork4>(&Network::getDdnsTtlMin,
|
||||||
|
&Network::setDdnsTtlMin,
|
||||||
|
100, 200);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl-max");
|
||||||
|
testNetworkInheritance<TestNetwork4>(&Network::getDdnsTtlMax,
|
||||||
|
&Network::setDdnsTtlMax,
|
||||||
|
500, 600);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test verifies that the inheritance is supported for DHCPv6
|
// This test verifies that the inheritance is supported for DHCPv6
|
||||||
@ -394,6 +415,9 @@ TEST_F(NetworkTest, inheritanceSupport6) {
|
|||||||
globals_->set("pd-allocator", Element::create("random"));
|
globals_->set("pd-allocator", Element::create("random"));
|
||||||
globals_->set("ddns-ttl-percent", Element::create(0.55));
|
globals_->set("ddns-ttl-percent", Element::create(0.55));
|
||||||
globals_->set("ddns-conflict-resolution-mode", Element::create("check-with-dhcid"));
|
globals_->set("ddns-conflict-resolution-mode", Element::create("check-with-dhcid"));
|
||||||
|
globals_->set("ddns-ttl", Element::create(400));
|
||||||
|
globals_->set("ddns-ttl-min", Element::create(200));
|
||||||
|
globals_->set("ddns-ttl-max", Element::create(600));
|
||||||
|
|
||||||
// For each parameter for which inheritance is supported run
|
// For each parameter for which inheritance is supported run
|
||||||
// the test that checks if the values are inherited properly.
|
// the test that checks if the values are inherited properly.
|
||||||
@ -502,6 +526,24 @@ TEST_F(NetworkTest, inheritanceSupport6) {
|
|||||||
&Network::setDdnsTtlPercent,
|
&Network::setDdnsTtlPercent,
|
||||||
.22, .55);
|
.22, .55);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl");
|
||||||
|
testNetworkInheritance<TestNetwork6>(&Network::getDdnsTtl,
|
||||||
|
&Network::setDdnsTtl,
|
||||||
|
300, 400);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl-min");
|
||||||
|
testNetworkInheritance<TestNetwork6>(&Network::getDdnsTtlMin,
|
||||||
|
&Network::setDdnsTtlMin,
|
||||||
|
100, 200);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl-max");
|
||||||
|
testNetworkInheritance<TestNetwork6>(&Network::getDdnsTtlMax,
|
||||||
|
&Network::setDdnsTtlMax,
|
||||||
|
500, 600);
|
||||||
|
}
|
||||||
|
|
||||||
// Interface-id requires special type of test.
|
// Interface-id requires special type of test.
|
||||||
boost::shared_ptr<TestNetwork6> net_child(new TestNetwork6());
|
boost::shared_ptr<TestNetwork6> net_child(new TestNetwork6());
|
||||||
|
@ -106,8 +106,155 @@ public:
|
|||||||
/// @param test_config JSON configuration text to parse
|
/// @param test_config JSON configuration text to parse
|
||||||
/// @return A reference to the Network created if parsing is successful
|
/// @return A reference to the Network created if parsing is successful
|
||||||
virtual Network& parseIntoNetwork(ConstElementPtr test_config) = 0;
|
virtual Network& parseIntoNetwork(ConstElementPtr test_config) = 0;
|
||||||
};
|
|
||||||
|
|
||||||
|
// Verifies valid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for SharedNetwork4.
|
||||||
|
template<typename NetworkTypePtr, typename ParserType>
|
||||||
|
void validDdnsTtlParmatersTest() {
|
||||||
|
struct Scenario {
|
||||||
|
size_t line_no_;
|
||||||
|
std::string json_;
|
||||||
|
double ddns_ttl_percent_;
|
||||||
|
uint32_t ddns_ttl_;
|
||||||
|
uint32_t ddns_ttl_min_;
|
||||||
|
uint32_t ddns_ttl_max_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::list<Scenario> scenarios = {
|
||||||
|
{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl": 100
|
||||||
|
})^",
|
||||||
|
0.0, 100, 0, 0
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-percent": 5.0
|
||||||
|
})^",
|
||||||
|
5.0, 0, 0, 0
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-min": 25
|
||||||
|
})^",
|
||||||
|
0.0, 0, 25, 0
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
0.0, 0, 0, 150
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-min": 25,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
0.0, 0, 25, 150
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-percent": 5.0,
|
||||||
|
"ddns-ttl-min": 25,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
5.0, 0, 25, 150
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (const auto& scenario : scenarios) {
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << "scenario at " << scenario.line_no_;
|
||||||
|
SCOPED_TRACE(oss.str());
|
||||||
|
|
||||||
|
// Parse configuration specified above.
|
||||||
|
ElementPtr config_element;
|
||||||
|
ASSERT_NO_THROW_LOG(config_element = Element::fromJSON(scenario.json_));
|
||||||
|
|
||||||
|
ParserType parser;
|
||||||
|
NetworkTypePtr network;
|
||||||
|
|
||||||
|
ASSERT_NO_THROW_LOG(network = parser.parse(config_element));
|
||||||
|
ASSERT_TRUE(network);
|
||||||
|
|
||||||
|
EXPECT_EQ(network->getDdnsTtlPercent().unspecified(), (scenario.ddns_ttl_percent_ == 0.0));
|
||||||
|
EXPECT_EQ(network->getDdnsTtlPercent(), scenario.ddns_ttl_percent_);
|
||||||
|
|
||||||
|
EXPECT_EQ(network->getDdnsTtl().unspecified(), (scenario.ddns_ttl_ == 0));
|
||||||
|
EXPECT_EQ(network->getDdnsTtl(), scenario.ddns_ttl_);
|
||||||
|
|
||||||
|
EXPECT_EQ(network->getDdnsTtlMin().unspecified(), (scenario.ddns_ttl_min_ == 0));
|
||||||
|
EXPECT_EQ(network->getDdnsTtlMin(), scenario.ddns_ttl_min_);
|
||||||
|
|
||||||
|
EXPECT_EQ(network->getDdnsTtlMax().unspecified(), (scenario.ddns_ttl_max_ == 0));
|
||||||
|
EXPECT_EQ(network->getDdnsTtlMax(), scenario.ddns_ttl_max_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies invalid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for SharedNetwork.
|
||||||
|
template<typename ParserType>
|
||||||
|
void invalidDdnsTtlParmatersTest() {
|
||||||
|
struct Scenario {
|
||||||
|
size_t line_no_;
|
||||||
|
std::string json_;
|
||||||
|
std::string exp_message_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::list<Scenario> scenarios = {
|
||||||
|
{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-percent": 5.0,
|
||||||
|
"ddns-ttl": 100
|
||||||
|
})^",
|
||||||
|
"cannot specify both ddns-ttl-percent and ddns-ttl (<string>:1:2)"
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl": 100,
|
||||||
|
"ddns-ttl-min": 25
|
||||||
|
})^",
|
||||||
|
"cannot specify both ddns-ttl-min and ddns-ttl (<string>:1:2)"
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl": 100,
|
||||||
|
"ddns-ttl-max": 150
|
||||||
|
})^",
|
||||||
|
"cannot specify both ddns-ttl-max and ddns-ttl (<string>:1:2)"
|
||||||
|
},{
|
||||||
|
__LINE__,
|
||||||
|
R"^({
|
||||||
|
"name": "one",
|
||||||
|
"ddns-ttl-min": 150,
|
||||||
|
"ddns-ttl-max": 25
|
||||||
|
})^",
|
||||||
|
"ddns-ttl-max: 25 must be greater than ddns-ttl-min: 150 (<string>:1:2)"
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (const auto& scenario : scenarios) {
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << "scenario at " << scenario.line_no_;
|
||||||
|
SCOPED_TRACE(oss.str());
|
||||||
|
|
||||||
|
// Parse configuration specified above.
|
||||||
|
ElementPtr config_element;
|
||||||
|
ASSERT_NO_THROW_LOG(config_element = Element::fromJSON(scenario.json_));
|
||||||
|
ParserType parser;
|
||||||
|
ASSERT_THROW_MSG(parser.parse(config_element), DhcpConfigError, scenario.exp_message_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Test fixture class for SharedNetwork4Parser class.
|
/// @brief Test fixture class for SharedNetwork4Parser class.
|
||||||
class SharedNetwork4ParserTest : public SharedNetworkParserTest {
|
class SharedNetwork4ParserTest : public SharedNetworkParserTest {
|
||||||
@ -1215,5 +1362,28 @@ TEST_F(SharedNetwork6ParserTest, deprecatedClientClass) {
|
|||||||
" (<string>:1:2)");
|
" (<string>:1:2)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verifies valid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for SharedNetwork4.
|
||||||
|
TEST_F(SharedNetwork4ParserTest, validDdnsTtlParmaters4) {
|
||||||
|
validDdnsTtlParmatersTest<SharedNetwork4Ptr, SharedNetwork4Parser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies valid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for SharedNetwork6.
|
||||||
|
TEST_F(SharedNetwork6ParserTest, validDdnsTtlParmaters6) {
|
||||||
|
validDdnsTtlParmatersTest<SharedNetwork6Ptr, SharedNetwork6Parser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies invalid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for Subnet4.
|
||||||
|
TEST_F(SharedNetwork4ParserTest, invalidDdnsTtlParmaters4) {
|
||||||
|
invalidDdnsTtlParmatersTest<SharedNetwork4Parser>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies invalid permuatations of ddns-ttl-percent, ddns-ttl,
|
||||||
|
// ddns-ttl-min, and ddns-ttl-max values for Subnet6.
|
||||||
|
TEST_F(SharedNetwork6ParserTest, invalidDdnsTtlParmaters6) {
|
||||||
|
invalidDdnsTtlParmatersTest<SharedNetwork6Parser>();
|
||||||
|
}
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
@ -2214,4 +2214,73 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verifies that sanityChecksDdnsTtlParams works as expected.
|
||||||
|
TEST_F(SrvConfigTest, sanityChecksDdnsTtlParameters) {
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("none");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
EXPECT_NO_THROW(conf.sanityChecksDdnsTtlParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl only");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl", Element::create(200));
|
||||||
|
EXPECT_NO_THROW(conf.sanityChecksDdnsTtlParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl and ddns-ttl-percent");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl", Element::create(200));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-percent", Element::create(50.0));
|
||||||
|
EXPECT_THROW_MSG(conf.sanityChecksDdnsTtlParameters(), isc::BadValue,
|
||||||
|
"cannot specify both ddns-ttl-percent and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl and ddns-ttl-min");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl", Element::create(200));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-min", Element::create(100));
|
||||||
|
EXPECT_THROW_MSG(conf.sanityChecksDdnsTtlParameters(), isc::BadValue,
|
||||||
|
"cannot specify both ddns-ttl-min and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl and ddns-ttl-max");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl", Element::create(200));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-max", Element::create(100));
|
||||||
|
EXPECT_THROW_MSG(conf.sanityChecksDdnsTtlParameters(), isc::BadValue,
|
||||||
|
"cannot specify both ddns-ttl-max and ddns-ttl");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl-min < ddns-ttl-max");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-min", Element::create(25));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-max", Element::create(100));
|
||||||
|
EXPECT_NO_THROW(conf.sanityChecksDdnsTtlParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddns-ttl-min > ddns-ttl-max");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-min", Element::create(100));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-max", Element::create(25));
|
||||||
|
EXPECT_THROW_MSG(conf.sanityChecksDdnsTtlParameters(), isc::BadValue,
|
||||||
|
"ddns-ttl-max: 25 must be greater than ddns-ttl-min: 100");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("ddsn-ttl-percent and ddns-ttl-min < ddns-ttl-max");
|
||||||
|
SrvConfig conf(32);
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-percent", Element::create(50.0));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-min", Element::create(25));
|
||||||
|
conf.addConfiguredGlobal("ddns-ttl-max", Element::create(100));
|
||||||
|
EXPECT_NO_THROW(conf.sanityChecksDdnsTtlParameters());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
@ -340,6 +340,13 @@ dumpAsHex(const uint8_t* data, size_t length) {
|
|||||||
return (output.str());
|
return (output.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
dumpDouble(double val, size_t precision) {
|
||||||
|
std::stringstream oss;
|
||||||
|
oss << setprecision(precision) << val;
|
||||||
|
return (oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace str
|
} // namespace str
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace isc
|
} // namespace isc
|
||||||
|
@ -286,6 +286,13 @@ isPrintable(const std::vector<uint8_t>& content);
|
|||||||
std::string
|
std::string
|
||||||
dumpAsHex(const uint8_t* data, size_t length);
|
dumpAsHex(const uint8_t* data, size_t length);
|
||||||
|
|
||||||
|
/// @brief Converts a double to a string with given precision
|
||||||
|
///
|
||||||
|
/// @param val double to convert
|
||||||
|
/// @param precision number of maxium number decimal places to output
|
||||||
|
/// @return string representaion of val
|
||||||
|
std::string dumpDouble(double val, size_t precision = 5);
|
||||||
|
|
||||||
} // namespace str
|
} // namespace str
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace isc
|
} // namespace isc
|
||||||
|
Loading…
x
Reference in New Issue
Block a user