mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 13:07:50 +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.
|
||||
"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
|
||||
// excluded from DHCP assignments. The default value is 86400 (24 hours).
|
||||
"decline-probation-period": 86400,
|
||||
@ -895,6 +906,15 @@
|
||||
// Shared-network level value. See description at the global level.
|
||||
"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.
|
||||
"hostname-char-replacement": "x",
|
||||
|
||||
@ -1035,6 +1055,15 @@
|
||||
// Subnet-level value. See description at the global level.
|
||||
"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.
|
||||
"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\" {
|
||||
switch(driver.ctx_) {
|
||||
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_USE_CONFLICT_RESOLUTION "ddns-use-conflict-resolution"
|
||||
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"
|
||||
SUBNET4 "subnet4"
|
||||
SUBNET_4O6_INTERFACE "4o6-interface"
|
||||
@ -566,6 +569,9 @@ global_param: valid_lifetime
|
||||
| ddns_use_conflict_resolution
|
||||
| ddns_conflict_resolution_mode
|
||||
| ddns_ttl_percent
|
||||
| ddns_ttl
|
||||
| ddns_ttl_min
|
||||
| ddns_ttl_max
|
||||
| store_extended_info
|
||||
| statistic_default_sample_count
|
||||
| statistic_default_sample_age
|
||||
@ -800,6 +806,24 @@ ddns_ttl_percent: DDNS_TTL_PERCENT COLON FLOAT {
|
||||
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 {
|
||||
ctx.unique("hostname-char-set", ctx.loc2pos(@1));
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
@ -1636,6 +1660,9 @@ subnet4_param: valid_lifetime
|
||||
| ddns_use_conflict_resolution
|
||||
| ddns_conflict_resolution_mode
|
||||
| ddns_ttl_percent
|
||||
| ddns_ttl
|
||||
| ddns_ttl_min
|
||||
| ddns_ttl_max
|
||||
| hostname_char_set
|
||||
| hostname_char_replacement
|
||||
| store_extended_info
|
||||
@ -1837,6 +1864,9 @@ shared_network_param: name
|
||||
| ddns_use_conflict_resolution
|
||||
| ddns_conflict_resolution_mode
|
||||
| ddns_ttl_percent
|
||||
| ddns_ttl
|
||||
| ddns_ttl_min
|
||||
| ddns_ttl_max
|
||||
| hostname_char_set
|
||||
| hostname_char_replacement
|
||||
| store_extended_info
|
||||
|
@ -195,6 +195,9 @@ public:
|
||||
/// Global lifetime sanity checks
|
||||
cfg->sanityChecksLifetime("valid-lifetime");
|
||||
|
||||
/// Sanity check global ddns-ttl parameters
|
||||
cfg->sanityChecksDdnsTtlParameters();
|
||||
|
||||
/// Shared network sanity checks
|
||||
const SharedNetwork4Collection* networks = cfg->getCfgSharedNetworks4()->getAll();
|
||||
if (networks) {
|
||||
@ -673,7 +676,10 @@ processDhcp4Config(isc::data::ConstElementPtr config_set) {
|
||||
(config_pair.first == "parked-packet-limit") ||
|
||||
(config_pair.first == "allocator") ||
|
||||
(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,
|
||||
config_pair.second);
|
||||
continue;
|
||||
|
@ -8269,4 +8269,180 @@ TEST_F(Dhcp4ParserTest, deprecatedClientClassesCheck) {
|
||||
" 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
|
||||
|
@ -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.
|
||||
///
|
||||
/// 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
|
||||
/// equal to CLTT plus lease ttl .
|
||||
/// @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,
|
||||
const bool reverse, const bool forward,
|
||||
const std::string& addr,
|
||||
@ -804,7 +902,10 @@ public:
|
||||
const bool not_strict_expire_check = false,
|
||||
const ConflictResolutionMode
|
||||
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;
|
||||
ASSERT_NO_THROW(ncr = d2_mgr_.peekAt(0));
|
||||
ASSERT_TRUE(ncr);
|
||||
@ -825,7 +926,10 @@ public:
|
||||
// current time as cltt but the it may not check the lease expiration
|
||||
// time for equality but rather check that the lease expiration time
|
||||
// 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) {
|
||||
EXPECT_GE(cltt + ttl, ncr->getLeaseExpiresOn());
|
||||
} else {
|
||||
@ -2840,7 +2944,7 @@ TEST_F(NameDhcpv4SrvTest, withOfferLifetime) {
|
||||
}
|
||||
|
||||
// Verifies the DNS TTL when ttl percent is specified
|
||||
// than zero.
|
||||
// greater than zero.
|
||||
TEST_F(NameDhcpv4SrvTest, withDdnsTtlPercent) {
|
||||
// Load a configuration with D2 enabled and ddns-ttl-percent
|
||||
ASSERT_NO_FATAL_FAILURE(configure(CONFIGS[12], *srv_));
|
||||
@ -2958,4 +3062,36 @@ TEST_F(NameDhcpv4SrvTest, checkExistsDHCIDConflictResolutionMode) {
|
||||
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
|
||||
|
@ -68,6 +68,7 @@ namespace {
|
||||
///@{
|
||||
/// @brief extracted configurations
|
||||
const char* EXTRACTED_CONFIGS[] = {
|
||||
/// put this after const char* EXTRACTED_CONFIGS[] = {
|
||||
// CONFIGURATION 0
|
||||
"{\n"
|
||||
" \"interfaces-config\": {\n"
|
||||
@ -2651,11 +2652,84 @@ const char* EXTRACTED_CONFIGS[] = {
|
||||
" }\n"
|
||||
" ],\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"
|
||||
};
|
||||
|
||||
/// @brief unparsed configurations
|
||||
const char* UNPARSED_CONFIGS[] = {
|
||||
///put this after const char* UNPARSED_CONFIGS[] = {
|
||||
// CONFIGURATION 0
|
||||
"{\n"
|
||||
" \"allocator\": \"iterative\",\n"
|
||||
@ -13546,6 +13620,506 @@ const char* UNPARSED_CONFIGS[] = {
|
||||
" \"t1-percent\": 0.5,\n"
|
||||
" \"t2-percent\": 0.875,\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"
|
||||
};
|
||||
|
||||
|
@ -284,6 +284,9 @@ public:
|
||||
cfg->sanityChecksLifetime("preferred-lifetime");
|
||||
cfg->sanityChecksLifetime("valid-lifetime");
|
||||
|
||||
/// Sanity check global ddns-ttl parameters
|
||||
cfg->sanityChecksDdnsTtlParameters();
|
||||
|
||||
/// Shared network sanity checks
|
||||
const SharedNetwork6Collection* networks = cfg->getCfgSharedNetworks6()->getAll();
|
||||
if (networks) {
|
||||
|
@ -86,6 +86,7 @@ CBControlDHCPv4::databaseConfigApply(const BackendSelector& backend_selector,
|
||||
|
||||
// Sanity check it.
|
||||
external_cfg->sanityChecksLifetime("valid-lifetime");
|
||||
external_cfg->sanityChecksDdnsTtlParameters();
|
||||
|
||||
// Now that we successfully fetched the new global parameters, let's
|
||||
// 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
|
||||
// configuration is committed.
|
||||
external_cfg->sanityChecksLifetime(*staging_cfg, "valid-lifetime");
|
||||
external_cfg->sanityChecksDdnsTtlParameters();
|
||||
CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
|
||||
|
||||
} else {
|
||||
@ -331,6 +333,7 @@ CBControlDHCPv4::databaseConfigApply(const BackendSelector& backend_selector,
|
||||
}
|
||||
}
|
||||
external_cfg->sanityChecksLifetime(*current_cfg, "valid-lifetime");
|
||||
external_cfg->sanityChecksDdnsTtlParameters();
|
||||
CfgMgr::instance().mergeIntoCurrentCfg(external_cfg->getSequence());
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->initAllocatorsAfterConfigure();
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ CBControlDHCPv6::databaseConfigApply(const db::BackendSelector& backend_selector
|
||||
// Sanity check it.
|
||||
external_cfg->sanityChecksLifetime("preferred-lifetime");
|
||||
external_cfg->sanityChecksLifetime("valid-lifetime");
|
||||
external_cfg->sanityChecksDdnsTtlParameters();
|
||||
|
||||
// Now that we successfully fetched the new global parameters, let's
|
||||
// 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();
|
||||
external_cfg->sanityChecksLifetime(*cfg, "preferred-lifetime");
|
||||
external_cfg->sanityChecksLifetime(*cfg, "valid-lifetime");
|
||||
external_cfg->sanityChecksDdnsTtlParameters();
|
||||
CfgMgr::instance().mergeIntoStagingCfg(external_cfg->getSequence());
|
||||
|
||||
} else {
|
||||
@ -348,6 +350,7 @@ CBControlDHCPv6::databaseConfigApply(const db::BackendSelector& backend_selector
|
||||
auto const& cfg = CfgMgr::instance().getCurrentCfg();
|
||||
external_cfg->sanityChecksLifetime(*cfg, "preferred-lifetime");
|
||||
external_cfg->sanityChecksLifetime(*cfg, "valid-lifetime");
|
||||
external_cfg->sanityChecksDdnsTtlParameters();
|
||||
CfgMgr::instance().mergeIntoCurrentCfg(external_cfg->getSequence());
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->initAllocatorsAfterConfigure();
|
||||
}
|
||||
|
@ -57,6 +57,9 @@ CfgGlobals::nameToIndex = {
|
||||
{ "multi-threading", MULTI_THREADING },
|
||||
{ "sanity-checks", SANITY_CHECKS },
|
||||
{ "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.
|
||||
{ "echo-client-id", ECHO_CLIENT_ID },
|
||||
|
@ -80,6 +80,9 @@ public:
|
||||
MULTI_THREADING,
|
||||
SANITY_CHECKS,
|
||||
DHCP_QUEUE_CONTROL,
|
||||
DDNS_TTL,
|
||||
DDNS_TTL_MIN,
|
||||
DDNS_TTL_MAX,
|
||||
|
||||
// DHCPv4 specific parameters.
|
||||
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_CLIENT_CLASS_DEPRECATED = "DHCPSRV_CLIENT_CLASS_DEPRECATED";
|
||||
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_DHCP_DDNS_ERROR_EXCEPTION = "DHCPSRV_DHCP_DDNS_ERROR_EXCEPTION";
|
||||
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_CLIENT_CLASS_DEPRECATED", "The parameter 'client-class' is deprecated. Use 'client-classes' list parameter instead",
|
||||
"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_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.",
|
||||
|
@ -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_CLIENT_CLASS_DEPRECATED;
|
||||
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_DHCP_DDNS_ERROR_EXCEPTION;
|
||||
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
|
||||
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
|
||||
A bad DHCPv4o6 packet was received.
|
||||
|
||||
@ -971,3 +963,20 @@ included in the message.
|
||||
% DHCPSRV_UNKNOWN_DB unknown database type: %1
|
||||
The database access string specified a database type (given in the
|
||||
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 <stdint.h>
|
||||
#include <vector>
|
||||
#include <util/str.h>
|
||||
|
||||
using namespace isc;
|
||||
using namespace isc::dhcp;
|
||||
@ -52,6 +53,9 @@ void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
|
||||
|
||||
ConflictResolutionMode conflict_resolution_mode = CHECK_WITH_DHCID;
|
||||
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) {
|
||||
auto mode = subnet->getDdnsConflictResolutionMode();
|
||||
if (!mode.empty()) {
|
||||
@ -59,6 +63,9 @@ void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
|
||||
}
|
||||
|
||||
ddns_ttl_percent = subnet->getDdnsTtlPercent();
|
||||
ddns_ttl = subnet->getDdnsTtl();
|
||||
ddns_ttl_min = subnet->getDdnsTtlMin();
|
||||
ddns_ttl_max = subnet->getDdnsTtlMax();
|
||||
}
|
||||
|
||||
try {
|
||||
@ -68,7 +75,9 @@ void queueNCRCommon(const NameChangeType& chg_type, const LeasePtrType& lease,
|
||||
D2Dhcid dhcid = D2Dhcid(identifier, hostname_wire);
|
||||
|
||||
// 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.
|
||||
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) {
|
||||
// If we have a configured percentage use it to calculate TTL.
|
||||
if (!ddns_ttl_percent.unspecified() && (ddns_ttl_percent.get() > 0.0)) {
|
||||
uint32_t new_lft = static_cast<uint32_t>(round(ddns_ttl_percent.get() * lease_lft));
|
||||
if (new_lft > 0) {
|
||||
return (new_lft);
|
||||
} else {
|
||||
uint32_t calculateDdnsTtl(uint32_t lease_lft,
|
||||
const util::Optional<double>& ddns_ttl_percent,
|
||||
const util::Optional<uint32_t>& ddns_ttl,
|
||||
const util::Optional<uint32_t>& ddns_ttl_min,
|
||||
const util::Optional<uint32_t>& ddns_ttl_max) {
|
||||
// If we have an explicit value use it.
|
||||
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,
|
||||
DHCPSRV_DDNS_TTL_PERCENT_TOO_SMALL)
|
||||
.arg(ddns_ttl_percent.get())
|
||||
.arg(lease_lft);
|
||||
}
|
||||
DHCPSRV_DDNS_TTL_TOO_LARGE)
|
||||
.arg(util::str::dumpDouble(ttl_percent))
|
||||
.arg(lease_lft)
|
||||
.arg(ttl)
|
||||
.arg(ttl_max);
|
||||
return (ttl_max);
|
||||
}
|
||||
|
||||
// Per RFC 4702 DDNS RR TTL should be given by:
|
||||
// ((lease life time / 3) < 10 minutes) ? 10 minutes : (lease life time / 3)
|
||||
if (lease_lft < 1800) {
|
||||
return (600);
|
||||
}
|
||||
|
||||
return (lease_lft / 3);
|
||||
return (ttl);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
///
|
||||
/// If the parameter, ddns_ttl_percent is greater than zero, it is used to calculate
|
||||
/// the TTL directly:
|
||||
/// The logic for calculating TTL is as follow:
|
||||
///
|
||||
/// 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 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.
|
||||
uint32_t calculateDdnsTtl(uint32_t lease_life_time,
|
||||
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 namespace
|
||||
|
@ -231,6 +231,18 @@ Network::toElement() const {
|
||||
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()) {
|
||||
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_(),
|
||||
hostname_char_set_(), hostname_char_replacement_(), store_extended_info_(),
|
||||
cache_threshold_(), cache_max_age_(), ddns_update_on_renew_(),
|
||||
ddns_conflict_resolution_mode_(), ddns_ttl_percent_(), allocator_type_(),
|
||||
default_allocator_type_() {
|
||||
ddns_conflict_resolution_mode_(), ddns_ttl_percent_(),
|
||||
ddns_ttl_(), ddns_ttl_min_(), ddns_ttl_max_(),
|
||||
allocator_type_(), default_allocator_type_() {
|
||||
}
|
||||
|
||||
/// @brief Virtual destructor.
|
||||
@ -682,6 +683,59 @@ public:
|
||||
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.
|
||||
util::Optional<std::string>
|
||||
getHostnameCharSet(const Inheritance& inheritance = Inheritance::ALL) const {
|
||||
@ -1237,6 +1291,15 @@ protected:
|
||||
/// @brief Percentage of the lease lifetime to use for DNS TTL.
|
||||
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.
|
||||
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"));
|
||||
}
|
||||
|
||||
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 (has_ddns_ttl) {
|
||||
isc_throw(BadValue, "cannot specify both ddns-ttl-percent and ddns-ttl");
|
||||
}
|
||||
|
||||
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.
|
||||
if (network_data->contains("ddns-conflict-resolution-mode")) {
|
||||
network->setDdnsConflictResolutionMode(getString(network_data,
|
||||
|
@ -101,6 +101,9 @@ const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = {
|
||||
{ "ddns-ttl-percent", Element::real },
|
||||
{ "ddns-conflict-resolution-mode", Element::string },
|
||||
{ "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
|
||||
@ -261,6 +264,9 @@ const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = {
|
||||
{ "offer-lifetime", Element::integer },
|
||||
{ "ddns-ttl-percent", Element::real },
|
||||
{ "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.
|
||||
@ -388,6 +394,9 @@ const SimpleKeywords SimpleParser4::SHARED_NETWORK4_PARAMETERS = {
|
||||
{ "offer-lifetime", Element::integer },
|
||||
{ "ddns-ttl-percent", Element::real },
|
||||
{ "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.
|
||||
|
@ -100,6 +100,9 @@ const SimpleKeywords SimpleParser6::GLOBAL6_PARAMETERS = {
|
||||
{ "pd-allocator", Element::string },
|
||||
{ "ddns-ttl-percent", Element::real },
|
||||
{ "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
|
||||
@ -253,6 +256,9 @@ const SimpleKeywords SimpleParser6::SUBNET6_PARAMETERS = {
|
||||
{ "pd-allocator", Element::string },
|
||||
{ "ddns-ttl-percent", Element::real },
|
||||
{ "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.
|
||||
@ -401,6 +407,9 @@ const SimpleKeywords SimpleParser6::SHARED_NETWORK6_PARAMETERS = {
|
||||
{ "pd-allocator", Element::string },
|
||||
{ "ddns-ttl-percent", Element::real },
|
||||
{ "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.
|
||||
|
@ -1057,6 +1057,42 @@ DdnsParams::getHostnameSanitizer() const {
|
||||
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
|
||||
DdnsParams::getUpdateOnRenew() const {
|
||||
if (!subnet_) {
|
||||
@ -1075,6 +1111,33 @@ DdnsParams::getTtlPercent() const {
|
||||
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
|
||||
DdnsParams::getConflictResolutionMode() const {
|
||||
if (!subnet_) {
|
||||
|
@ -150,6 +150,30 @@ public:
|
||||
/// @return TTL percent as an Optional.
|
||||
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
|
||||
///
|
||||
/// This value is communicated to D2 via the NCR.
|
||||
@ -951,6 +975,16 @@ public:
|
||||
void sanityChecksLifetime(const SrvConfig& target_config,
|
||||
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
|
||||
/// hosts with the same IP address/subnet.
|
||||
///
|
||||
|
@ -72,6 +72,161 @@ public:
|
||||
void resetIfaceCfg() {
|
||||
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
|
||||
@ -4115,4 +4270,28 @@ TEST_F(DhcpParserTest, deprecatedClientClassPool6) {
|
||||
" '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
|
||||
|
@ -234,14 +234,18 @@ public:
|
||||
void testNCR(const NameChangeType chg_type, const bool fwd, const bool rev,
|
||||
const std::string& fqdn, const std::string exp_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.
|
||||
ASSERT_NO_FATAL_FAILURE(sendNCR(chg_type, fwd, rev, fqdn));
|
||||
// Expecting one NCR be generated.
|
||||
ASSERT_EQ(1, d2_mgr_.getQueueSize());
|
||||
|
||||
// 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.
|
||||
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.
|
||||
TEST_F(NCRGenerator4Test, calculateDdnsTtl) {
|
||||
// Verify that calculateDdnsTtl(), called by queueNcr()
|
||||
// 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.
|
||||
EXPECT_EQ(600, calculateDdnsTtl(100));
|
||||
Optional<double> no_percent;
|
||||
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.
|
||||
EXPECT_EQ(601, calculateDdnsTtl(1803));
|
||||
std::list<Scenario> scenarios = {
|
||||
// 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.
|
||||
util::Optional<double> ddns_ttl_percent;
|
||||
// No modifiers, RFC % < RFC minium 600
|
||||
{ __LINE__, 1500, no_percent, no_ttl, no_min, no_max, 600 },
|
||||
|
||||
// Unspecified percent should result in normal per RFC calculation.
|
||||
EXPECT_EQ(601, calculateDdnsTtl(1803, ddns_ttl_percent));
|
||||
// RFC % < specified minimum
|
||||
{ __LINE__, 2100, no_percent, no_ttl, 800, no_max, 800 },
|
||||
|
||||
// A percentage of zero should be ignored.
|
||||
ddns_ttl_percent = 0.0;
|
||||
EXPECT_EQ(601, calculateDdnsTtl(1803, ddns_ttl_percent));
|
||||
// RFC % > specified maximum
|
||||
{ __LINE__, 2100, no_percent, no_ttl, no_min, 500, 500 },
|
||||
|
||||
// A percentage that results in near zero should be ignored.
|
||||
ddns_ttl_percent = 0.000005;
|
||||
EXPECT_EQ(601, calculateDdnsTtl(1803, ddns_ttl_percent));
|
||||
// Explicit ttl
|
||||
{ __LINE__, 2100, no_percent, 900, no_min, no_max, 900 },
|
||||
|
||||
// A large enough percentage should be used.
|
||||
ddns_ttl_percent = 0.01;
|
||||
EXPECT_EQ(18, calculateDdnsTtl(1803, ddns_ttl_percent));
|
||||
// Explicit ttl wins over specified percent
|
||||
{ __LINE__, 2100, 0.25, 900, no_min, no_max, 900 },
|
||||
|
||||
// A large enough percentage should be used.
|
||||
ddns_ttl_percent = 1.50;
|
||||
EXPECT_EQ(2705, calculateDdnsTtl(1803, ddns_ttl_percent));
|
||||
}
|
||||
// Explicit ttl wins over specified minumum
|
||||
{ __LINE__, 2100, no_percent, 900, 1000, no_max, 900 },
|
||||
|
||||
// Verify that ddns-ttl-percent is used correctly by v4 queueNCR()
|
||||
TEST_F(NCRGenerator4Test, withTtlPercent) {
|
||||
{
|
||||
SCOPED_TRACE("Ttl percent of 0");
|
||||
Optional<double> ttl_percent(0);
|
||||
subnet_->setDdnsTtlPercent(ttl_percent);
|
||||
testNCR(CHG_REMOVE, true, true, "MYHOST.example.com.",
|
||||
// Explicit ttl wins over specified maxiumum
|
||||
{ __LINE__, 2100, no_percent, 900, no_min, 800, 900 },
|
||||
|
||||
// Specified percent > RFC minumum
|
||||
{ __LINE__, 2100, 0.5, no_ttl, no_min, no_max, 1050 },
|
||||
|
||||
// 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"
|
||||
"B03AB370BFF46BFA309AE7BFD", CHECK_WITH_DHCID, ttl_percent);
|
||||
}
|
||||
{
|
||||
SCOPED_TRACE("Ttl percent of 1.5");
|
||||
Optional<double> ttl_percent(1.5);
|
||||
subnet_->setDdnsTtlPercent(ttl_percent);
|
||||
testNCR(CHG_REMOVE, true, true, "MYHOST.example.com.",
|
||||
"000001E356D43E5F0A496D65BCA24D982D646140813E3"
|
||||
"B03AB370BFF46BFA309AE7BFD", CHECK_WITH_DHCID, ttl_percent);
|
||||
"B03AB370BFF46BFA309AE7BFD", CHECK_WITH_DHCID,
|
||||
scenario.ddns_ttl_percent_,
|
||||
scenario.ddns_ttl_,
|
||||
scenario.ddns_ttl_min_,
|
||||
scenario.ddns_ttl_max_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,6 +183,9 @@ TEST_F(NetworkTest, inheritanceSupport4) {
|
||||
globals_->set("allocator", Element::create("random"));
|
||||
globals_->set("offer-lifetime", Element::create(45));
|
||||
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
|
||||
// the test that checks if the values are inherited properly.
|
||||
@ -372,6 +375,24 @@ TEST_F(NetworkTest, inheritanceSupport4) {
|
||||
&Network::setDdnsTtlPercent,
|
||||
.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
|
||||
@ -394,6 +415,9 @@ TEST_F(NetworkTest, inheritanceSupport6) {
|
||||
globals_->set("pd-allocator", Element::create("random"));
|
||||
globals_->set("ddns-ttl-percent", Element::create(0.55));
|
||||
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
|
||||
// the test that checks if the values are inherited properly.
|
||||
@ -502,6 +526,24 @@ TEST_F(NetworkTest, inheritanceSupport6) {
|
||||
&Network::setDdnsTtlPercent,
|
||||
.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.
|
||||
boost::shared_ptr<TestNetwork6> net_child(new TestNetwork6());
|
||||
|
@ -106,8 +106,155 @@ public:
|
||||
/// @param test_config JSON configuration text to parse
|
||||
/// @return A reference to the Network created if parsing is successful
|
||||
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.
|
||||
class SharedNetwork4ParserTest : public SharedNetworkParserTest {
|
||||
@ -1215,5 +1362,28 @@ TEST_F(SharedNetwork6ParserTest, deprecatedClientClass) {
|
||||
" (<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
|
||||
|
@ -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
|
||||
|
@ -340,6 +340,13 @@ dumpAsHex(const uint8_t* data, size_t length) {
|
||||
return (output.str());
|
||||
}
|
||||
|
||||
string
|
||||
dumpDouble(double val, size_t precision) {
|
||||
std::stringstream oss;
|
||||
oss << setprecision(precision) << val;
|
||||
return (oss.str());
|
||||
}
|
||||
|
||||
} // namespace str
|
||||
} // namespace util
|
||||
} // namespace isc
|
||||
|
@ -286,6 +286,13 @@ isPrintable(const std::vector<uint8_t>& content);
|
||||
std::string
|
||||
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 util
|
||||
} // namespace isc
|
||||
|
Loading…
x
Reference in New Issue
Block a user