From: Francis Dupont Date: Mon, 9 Sep 2019 12:59:09 +0000 (+0200) Subject: [897-add-infinite-valid-lifetime] Limit to one year configured timers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f717953d0b016df4f95049cd0d6787cb7ea7f0f9;p=thirdparty%2Fkea.git [897-add-infinite-valid-lifetime] Limit to one year configured timers --- diff --git a/doc/sphinx/arm/dhcp4-srv.rst b/doc/sphinx/arm/dhcp4-srv.rst index 024687d5be..6bfa9325fd 100644 --- a/doc/sphinx/arm/dhcp4-srv.rst +++ b/doc/sphinx/arm/dhcp4-srv.rst @@ -194,6 +194,11 @@ client will begin the renewal and rebind procedures. the minimum is returned) or greater than the maximum (in this case the maximum is used). +.. note:: + + Beginning with Kea 1.7.0 configured timers are silently limited to one + year (365 days or 31536000 seconds). + .. note:: Both ``renew-timer`` and ``rebind-timer`` diff --git a/doc/sphinx/arm/dhcp6-srv.rst b/doc/sphinx/arm/dhcp6-srv.rst index 55a70d7528..79f26c904b 100644 --- a/doc/sphinx/arm/dhcp6-srv.rst +++ b/doc/sphinx/arm/dhcp6-srv.rst @@ -2120,6 +2120,11 @@ zero values these values are used when they are between configured minimum (lower values are round up) and maximal (larger values are round down) bounds. +.. note:: + + Beginning with Kea 1.7.0 configured timers are silently limited to one + year (365 days or 31536000 seconds). + To send specific, fixed values use the following two parameters: - ``renew-timer`` - specifies the value of T1 in seconds. diff --git a/src/lib/dhcpsrv/network.h b/src/lib/dhcpsrv/network.h index 65848eb133..08d68b793f 100644 --- a/src/lib/dhcpsrv/network.h +++ b/src/lib/dhcpsrv/network.h @@ -27,7 +27,10 @@ namespace isc { namespace dhcp { -/// List of IOAddresses +/// @brief Number of seconds in one year (hard limit for timers). +const uint32_t ONEYEAR_LIFETIME = 365 * 24 * 60 * 60; + +/// @brief List of IOAddresses typedef std::vector IOAddressList; class Network; diff --git a/src/lib/dhcpsrv/parsers/base_network_parser.cc b/src/lib/dhcpsrv/parsers/base_network_parser.cc index a83614defe..93e598ae23 100644 --- a/src/lib/dhcpsrv/parsers/base_network_parser.cc +++ b/src/lib/dhcpsrv/parsers/base_network_parser.cc @@ -92,6 +92,16 @@ BaseNetworkParser::parseLifetime(const ConstElementPtr& scope, << min_value << ") and max-" << name << " (" << max_value << ")"); } + // Limit to one year. + if (value > ONEYEAR_LIFETIME) { + value = ONEYEAR_LIFETIME; + } + if (min_value > ONEYEAR_LIFETIME) { + min_value = ONEYEAR_LIFETIME; + } + if (max_value > ONEYEAR_LIFETIME) { + max_value = ONEYEAR_LIFETIME; + } return (Triplet(min_value, value, max_value)); } @@ -99,11 +109,19 @@ void BaseNetworkParser::parseCommonTimers(const ConstElementPtr& network_data, NetworkPtr& network) { if (network_data->contains("renew-timer")) { - network->setT1(getInteger(network_data, "renew-timer")); + uint32_t value = getInteger(network_data, "renew-timer"); + if (value > ONEYEAR_LIFETIME) { + value = ONEYEAR_LIFETIME; + } + network->setT1(value); } if (network_data->contains("rebind-timer")) { - network->setT2(getInteger(network_data, "rebind-timer")); + uint32_t value = getInteger(network_data, "rebind-timer"); + if (value > ONEYEAR_LIFETIME) { + value = ONEYEAR_LIFETIME; + } + network->setT2(value); } network->setValid(parseLifetime(network_data, "valid-lifetime")); diff --git a/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc b/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc index ce7e4cd0f8..e99c475e6a 100644 --- a/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc @@ -1494,6 +1494,51 @@ TEST(CfgSubnets4Test, validLifetimeValidation) { EXPECT_EQ("300", max_value->str()); } + { + SCOPED_TRACE("all 3 (min, max and default) very large valid-lifetime"); + data::ElementPtr copied = data::copy(elems); + // Limit is one year seconds so use more. + int oneyear = ONEYEAR_LIFETIME; + copied->set("min-valid-lifetime", + data::Element::create(oneyear + 100)); + // Use a different (and greater) value for the default. + copied->set("valid-lifetime", + data::Element::create(oneyear + 200)); + // Use a different (and greater than both) value for max. + copied->set("max-valid-lifetime", + data::Element::create(oneyear + 300)); + // Set renew and rebind timers too. + copied->set("renew-timer", + data::Element::create(oneyear + 100)); + copied->set("rebind-timer", + data::Element::create(oneyear + 200)); + Subnet4Ptr subnet; + Subnet4ConfigParser parser; + ASSERT_NO_THROW(subnet = parser.parse(copied)); + ASSERT_TRUE(subnet); + EXPECT_FALSE(subnet->getValid().unspecified()); + EXPECT_EQ(oneyear, subnet->getValid()); + EXPECT_EQ(oneyear, subnet->getValid().getMin()); + EXPECT_EQ(oneyear, subnet->getValid().getMax()); + EXPECT_EQ(oneyear, subnet->getT1()); + EXPECT_EQ(oneyear, subnet->getT2()); + data::ConstElementPtr repr = subnet->toElement(); + data::ConstElementPtr value = repr->get("valid-lifetime"); + ASSERT_TRUE(value); + ASSERT_EQ(data::Element::integer, value->getType()); + EXPECT_EQ(oneyear, value->intValue()); + EXPECT_FALSE(repr->get("min-valid-lifetime")); + EXPECT_FALSE(repr->get("max-valid-lifetime")); + data::ConstElementPtr t1_value = repr->get("renew-timer"); + ASSERT_TRUE(t1_value); + ASSERT_EQ(data::Element::integer, t1_value->getType()); + EXPECT_EQ(oneyear, t1_value->intValue()); + data::ConstElementPtr t2_value = repr->get("rebind-timer"); + ASSERT_TRUE(t2_value); + ASSERT_EQ(data::Element::integer, t2_value->getType()); + EXPECT_EQ(oneyear, t2_value->intValue()); + } + { SCOPED_TRACE("default value too small"); data::ElementPtr copied = data::copy(elems); diff --git a/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc b/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc index f2af0c58e7..a84dc3bd63 100644 --- a/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc @@ -1282,6 +1282,52 @@ TEST(CfgSubnets6Test, preferredLifetimeValidation) { EXPECT_EQ("300", max_value->str()); } + { + SCOPED_TRACE("all 3 (min, max and default) very large preferred-lifetime"); + data::ElementPtr copied = data::copy(elems); + // Limit is one year seconds so use more. + int oneyear = ONEYEAR_LIFETIME; + copied->set("min-preferred-lifetime", + data::Element::create(oneyear + 100)); + // Use a different (and greater) value for the default. + copied->set("preferred-lifetime", + data::Element::create(oneyear + 200)); + // Use a different (and greater than both) value for max. + copied->set("max-preferred-lifetime", + data::Element::create(oneyear + 300)); + // Set renew and rebind timers too. + copied->set("renew-timer", + data::Element::create(oneyear + 100)); + copied->set("rebind-timer", + data::Element::create(oneyear + 200)); + Subnet6Ptr subnet; + Subnet6ConfigParser parser; + ASSERT_NO_THROW(subnet = parser.parse(copied)); + ASSERT_TRUE(subnet); + EXPECT_FALSE(subnet->getPreferred().unspecified()); + EXPECT_EQ(oneyear, subnet->getPreferred()); + EXPECT_EQ(oneyear, subnet->getPreferred().getMin()); + EXPECT_EQ(oneyear, subnet->getPreferred().getMax()); + EXPECT_EQ(oneyear, subnet->getT1()); + EXPECT_EQ(oneyear, subnet->getT2()); + data::ConstElementPtr repr = subnet->toElement(); + data::ConstElementPtr value = repr->get("preferred-lifetime"); + ASSERT_TRUE(value); + ASSERT_TRUE(value); + ASSERT_EQ(data::Element::integer, value->getType()); + EXPECT_EQ(oneyear, value->intValue()); + EXPECT_FALSE(repr->get("min-preferred-lifetime")); + EXPECT_FALSE(repr->get("max-preferred-lifetime")); + data::ConstElementPtr t1_value = repr->get("renew-timer"); + ASSERT_TRUE(t1_value); + ASSERT_EQ(data::Element::integer, t1_value->getType()); + EXPECT_EQ(oneyear, t1_value->intValue()); + data::ConstElementPtr t2_value = repr->get("rebind-timer"); + ASSERT_TRUE(t2_value); + ASSERT_EQ(data::Element::integer, t2_value->getType()); + EXPECT_EQ(oneyear, t2_value->intValue()); + } + { SCOPED_TRACE("default value too small"); data::ElementPtr copied = data::copy(elems);