Commit 67944844 authored by Thomas Markwalder's avatar Thomas Markwalder

[master] kea-dhcp4 can now calculate T1/T2

    Merge branch '365-automatically-calculate-the-values-for-options-58-and-59'
parents feb6a734 5faafeed
...@@ -231,16 +231,11 @@ defines how long the addresses (leases) given out by the ...@@ -231,16 +231,11 @@ defines how long the addresses (leases) given out by the
server are valid. If nothing changes, a client that got an address is allowed to server are valid. If nothing changes, a client that got an address is allowed to
use it for 4000 seconds. (Note that integer numbers are specified as is, use it for 4000 seconds. (Note that integer numbers are specified as is,
without any quotes around them.) <command>renew-timer</command> and without any quotes around them.) <command>renew-timer</command> and
<command>rebind-timer</command> are values (also in seconds) that <command>rebind-timer</command> are values (also in seconds) that may be
define T1 and T2 timers that govern when the client will begin the renewal and used to define T1 and T2 timers that govern when the client will begin the renewal
rebind procedures. <note> Both <command>renew-timer</command> and and rebind procedures. Please see this section:<xref linkend="dhcp4-t1-t2-times"/>
<command>rebind-timer</command> are optional. The server will only send for more details on generating T1 and T2.
rebind-timer to the client, via DHPv4 option code 59, if it is less than </para>
valid-lifetime; and it will only send renew-timer, via DHCPv4 option code 58,
if it is less than rebind-timer (or valid-lifetime if rebind-timer was not
specified). In their absence, the client should select values for T1 and T2
timers according to the <link xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="http://tools.ietf.org/html/rfc2131">RFC 2131</link>.</note></para>
<para>The <command>interfaces-config</command> map specifies the server <para>The <command>interfaces-config</command> map specifies the server
configuration concerning the network interfaces, on which the server should configuration concerning the network interfaces, on which the server should
...@@ -1141,10 +1136,75 @@ temporarily override a list of interface names and listen on all interfaces. ...@@ -1141,10 +1136,75 @@ temporarily override a list of interface names and listen on all interfaces.
address) and the last (typically broadcast address) address from that pool. address) and the last (typically broadcast address) address from that pool.
In the aforementioned example of pool 192.0.3.0/24, both 192.0.3.0 and In the aforementioned example of pool 192.0.3.0/24, both 192.0.3.0 and
192.0.3.255 addresses may be assigned as well. This may be invalid in some 192.0.3.255 addresses may be assigned as well. This may be invalid in some
network configurations. If you want to avoid this, please use the "min-max" notation. network configurations. If you want to avoid this, please use the "min-max"
notation.
</para> </para>
</section> </section>
<section xml:id="dhcp4-t1-t2-times">
<title>Sending T1 (Option 58) and T2 (Option 59)</title>
According to <link xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="http://tools.ietf.org/html/rfc2131">RFC 2131</link>,
servers should send values for T1 and T2 that are 50% and 87.5%
of the lease life time, repsectively. By default, kea-dhcp4 does
not send either value. It can be configured to send values that
are specified explicitly or that are calculated as percentages of
the lease time. The server's behavior is governed by combination of
configuration parameters, two of which have already been mentioned.
<para>
To send specific, fixed values use the following two parameters:
<itemizedlist>
<listitem>
<simpara><command>renew-timer</command> - specifies the value of T1 in
seconds.
</simpara>
</listitem>
<listitem>
<simpara><command>rebind-timer</command> - specifies the value of T2 in
seconds.
</simpara>
</listitem>
</itemizedlist>
The server will only send T2 if it is less than valid lease time. T1 will
only be sent if a: T2 is being sent and T1 is less than T2 or b: T2 is not being
sent and T1 is less than the valid lease time.
</para>
<para>
Calculating the values is controlled by the following three parameters.
<itemizedlist>
<listitem>
<simpara>
<command>calculate-tee-times</command> - when true, T1 and T2 will be
calculated as percentages of the valid lease time. It defaults to false.
</simpara>
</listitem>
<listitem>
<simpara>
<command>t1-percent</command> - the percentage of the valid lease time to
use for T1. It is expressed as a real number between 0.0 and 1.0 and must
be less than t2-percent. The default value is 0.50 per RFC 2131.
</simpara>
</listitem>
<listitem>
<simpara>
<command>t2-percent</command> - the percentage of the valid lease time to
use for T2. It is expressed as a real number between 0.0 and 1.0 and must
be greater than t1-percent. The default value is .875 per RFC 2131.
</simpara>
</listitem>
</itemizedlist>
</para>
<note>
In the event that both explicit values are specified and
calculate-tee-times is true, the server will use the explicit
values. If you plan on having a mixture where some subnets or
share-networks will use explicit values and some will use
calculated values you must not define the explicit values at any
level higher than where they will be used. Inheriting them from
too high of a scope, such as global, will cause them to have
values at every level underneath (shared-networks and subnets),
effectively disabling calculated values.
</note>
</section>
<section xml:id="dhcp4-std-options"> <section xml:id="dhcp4-std-options">
<title>Standard DHCPv4 Options</title> <title>Standard DHCPv4 Options</title>
<para> <para>
......
#line 1 "d2_lexer.cc" #line 2 "d2_lexer.cc"
#line 3 "d2_lexer.cc" #line 4 "d2_lexer.cc"
#define YY_INT_ALIGNED short int #define YY_INT_ALIGNED short int
...@@ -1146,7 +1146,7 @@ unsigned int comment_start_line = 0; ...@@ -1146,7 +1146,7 @@ unsigned int comment_start_line = 0;
/* To avoid the call to exit... oops! */ /* To avoid the call to exit... oops! */
#define YY_FATAL_ERROR(msg) isc::d2::D2ParserContext::fatal(msg) #define YY_FATAL_ERROR(msg) isc::d2::D2ParserContext::fatal(msg)
#line 1149 "d2_lexer.cc" #line 1150 "d2_lexer.cc"
/* noyywrap disables automatic rewinding for the next file to parse. Since we /* noyywrap disables automatic rewinding for the next file to parse. Since we
always parse only a single string, there's no need to do any wraps. And always parse only a single string, there's no need to do any wraps. And
using yywrap requires linking with -lfl, which provides the default yywrap using yywrap requires linking with -lfl, which provides the default yywrap
...@@ -1172,8 +1172,8 @@ unsigned int comment_start_line = 0; ...@@ -1172,8 +1172,8 @@ unsigned int comment_start_line = 0;
by moving it ahead by yyleng bytes. yyleng specifies the length of the by moving it ahead by yyleng bytes. yyleng specifies the length of the
currently matched token. */ currently matched token. */
#define YY_USER_ACTION driver.loc_.columns(yyleng); #define YY_USER_ACTION driver.loc_.columns(yyleng);
#line 1175 "d2_lexer.cc"
#line 1176 "d2_lexer.cc" #line 1176 "d2_lexer.cc"
#line 1177 "d2_lexer.cc"
#define INITIAL 0 #define INITIAL 0
#define COMMENT 1 #define COMMENT 1
...@@ -1491,7 +1491,7 @@ YY_DECL ...@@ -1491,7 +1491,7 @@ YY_DECL
} }
#line 1494 "d2_lexer.cc" #line 1495 "d2_lexer.cc"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{ {
...@@ -2393,7 +2393,7 @@ YY_RULE_SETUP ...@@ -2393,7 +2393,7 @@ YY_RULE_SETUP
#line 738 "d2_lexer.ll" #line 738 "d2_lexer.ll"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 2396 "d2_lexer.cc" #line 2397 "d2_lexer.cc"
case YY_END_OF_BUFFER: case YY_END_OF_BUFFER:
{ {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/* Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC") /* Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -841,6 +841,40 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} ...@@ -841,6 +841,40 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
} }
} }
\"calculate-tee-times\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::DHCP4:
case isc::dhcp::Parser4Context::SUBNET4:
case isc::dhcp::Parser4Context::SHARED_NETWORK:
return isc::dhcp::Dhcp4Parser::make_CALCULATE_TEE_TIMES(driver.loc_);
default:
return isc::dhcp::Dhcp4Parser::make_STRING("calculate-tee-times", driver.loc_);
}
}
\"t1-percent\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::DHCP4:
case isc::dhcp::Parser4Context::SUBNET4:
case isc::dhcp::Parser4Context::SHARED_NETWORK:
return isc::dhcp::Dhcp4Parser::make_T1_PERCENT(driver.loc_);
default:
return isc::dhcp::Dhcp4Parser::make_STRING("t1-percent", driver.loc_);
}
}
\"t2-percent\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::DHCP4:
case isc::dhcp::Parser4Context::SUBNET4:
case isc::dhcp::Parser4Context::SHARED_NETWORK:
return isc::dhcp::Dhcp4Parser::make_T2_PERCENT(driver.loc_);
default:
return isc::dhcp::Dhcp4Parser::make_STRING("t2-percent", driver.loc_);
}
}
\"Logging\" { \"Logging\" {
switch(driver.ctx_) { switch(driver.ctx_) {
case isc::dhcp::Parser4Context::CONFIG: case isc::dhcp::Parser4Context::CONFIG:
......
This diff is collapsed.
This diff is collapsed.
/* Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC") /* Copyright (C) 2016-2019 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -99,6 +99,9 @@ using namespace std; ...@@ -99,6 +99,9 @@ using namespace std;
VALID_LIFETIME "valid-lifetime" VALID_LIFETIME "valid-lifetime"
RENEW_TIMER "renew-timer" RENEW_TIMER "renew-timer"
REBIND_TIMER "rebind-timer" REBIND_TIMER "rebind-timer"
CALCULATE_TEE_TIMES "calculate-tee-times"
T1_PERCENT "t1-percent"
T2_PERCENT "t2-percent"
DECLINE_PROBATION_PERIOD "decline-probation-period" DECLINE_PROBATION_PERIOD "decline-probation-period"
SERVER_TAG "server-tag" SERVER_TAG "server-tag"
SUBNET4 "subnet4" SUBNET4 "subnet4"
...@@ -465,6 +468,9 @@ global_param: valid_lifetime ...@@ -465,6 +468,9 @@ global_param: valid_lifetime
| config_control | config_control
| server_tag | server_tag
| reservation_mode | reservation_mode
| calculate_tee_times
| t1_percent
| t2_percent
| unknown_map_entry | unknown_map_entry
; ;
...@@ -483,6 +489,21 @@ rebind_timer: REBIND_TIMER COLON INTEGER { ...@@ -483,6 +489,21 @@ rebind_timer: REBIND_TIMER COLON INTEGER {
ctx.stack_.back()->set("rebind-timer", prf); ctx.stack_.back()->set("rebind-timer", prf);
}; };
calculate_tee_times: CALCULATE_TEE_TIMES COLON BOOLEAN {
ElementPtr ctt(new BoolElement($3, ctx.loc2pos(@3)));
ctx.stack_.back()->set("calculate-tee-times", ctt);
};
t1_percent: T1_PERCENT COLON FLOAT {
ElementPtr t1(new DoubleElement($3, ctx.loc2pos(@3)));
ctx.stack_.back()->set("t1-percent", t1);
};
t2_percent: T2_PERCENT COLON FLOAT {
ElementPtr t2(new DoubleElement($3, ctx.loc2pos(@3)));
ctx.stack_.back()->set("t2-percent", t2);
};
decline_probation_period: DECLINE_PROBATION_PERIOD COLON INTEGER { decline_probation_period: DECLINE_PROBATION_PERIOD COLON INTEGER {
ElementPtr dpp(new IntElement($3, ctx.loc2pos(@3))); ElementPtr dpp(new IntElement($3, ctx.loc2pos(@3)));
ctx.stack_.back()->set("decline-probation-period", dpp); ctx.stack_.back()->set("decline-probation-period", dpp);
...@@ -1060,6 +1081,9 @@ subnet4_param: valid_lifetime ...@@ -1060,6 +1081,9 @@ subnet4_param: valid_lifetime
| subnet_4o6_subnet | subnet_4o6_subnet
| user_context | user_context
| comment | comment
| calculate_tee_times
| t1_percent
| t2_percent
| unknown_map_entry | unknown_map_entry
; ;
...@@ -1191,6 +1215,9 @@ shared_network_param: name ...@@ -1191,6 +1215,9 @@ shared_network_param: name
| valid_lifetime | valid_lifetime
| user_context | user_context
| comment | comment
| calculate_tee_times
| t1_percent
| t2_percent
| unknown_map_entry | unknown_map_entry
; ;
......
// Copyright (C) 2011-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -2190,32 +2190,8 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) { ...@@ -2190,32 +2190,8 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) {
// Subnet mask (type 1) // Subnet mask (type 1)
resp->addOption(getNetmaskOption(subnet)); resp->addOption(getNetmaskOption(subnet));
// rebind timer (type 59) - if specified then send it only it if // Set T1 and T2 per configuration.
// it is less than lease lifetime. Note we "sanity" check T1 setTeeTimes(lease, subnet, resp);
// and T2 against lease lifetime here in event the lifetime has
// been altered somewhere along the line.
uint32_t timer_ceiling = lease->valid_lft_;
if ((!subnet->getT2().unspecified()) &&
(subnet->getT2() < timer_ceiling)) {
OptionUint32Ptr t2(new OptionUint32(Option::V4,
DHO_DHCP_REBINDING_TIME,
subnet->getT2()));
resp->addOption(t2);
// If T2 is specified, then it becomes the ceiling for T1
timer_ceiling = subnet->getT2();
}
// renewal-timer (type 58) - if specified then send it only if
// it is less than the ceiling (T2 if given, lease life time if not)
if ((!subnet->getT1().unspecified()) &&
(subnet->getT1() < timer_ceiling)) {
OptionUint32Ptr t1(new OptionUint32(Option::V4,
DHO_DHCP_RENEWAL_TIME,
subnet->getT1()));
resp->addOption(t1);
}
// Create NameChangeRequests if DDNS is enabled and this is a // Create NameChangeRequests if DDNS is enabled and this is a
// real allocation. // real allocation.
...@@ -2250,6 +2226,46 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) { ...@@ -2250,6 +2226,46 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) {
} }
} }
void
Dhcpv4Srv::setTeeTimes(const Lease4Ptr& lease, const Subnet4Ptr& subnet, Pkt4Ptr resp) {
uint32_t t2_time = 0;
// If T2 is explicitly configured we'll use try value.
if (!subnet->getT2().unspecified()) {
t2_time = subnet->getT2();
} else if (subnet->getCalculateTeeTimes()) {
// Calculating tee times is enabled, so calculated it.
t2_time = static_cast<uint32_t>(subnet->getT2Percent() * (lease->valid_lft_));
}
// Send the T2 candidate value only if it's sane: to be sane it must be less than
// the valid life time.
uint32_t timer_ceiling = lease->valid_lft_;
if (t2_time > 0 && t2_time < timer_ceiling) {
OptionUint32Ptr t2(new OptionUint32(Option::V4, DHO_DHCP_REBINDING_TIME, t2_time));
resp->addOption(t2);
// When we send T2, timer ceiling for T1 becomes T2.
timer_ceiling = t2_time;
}
uint32_t t1_time = 0;
// If T1 is explicitly configured we'll use try value.
if (!subnet->getT1().unspecified()) {
t1_time = subnet->getT1();
} else if (subnet->getCalculateTeeTimes()) {
// Calculating tee times is enabled, so calculate it.
t1_time = static_cast<uint32_t>(subnet->getT1Percent() * (lease->valid_lft_));
}
// Send T1 if it's sane: If we sent T2, T1 must be less than that. If not it must be
// less than the valid life time.
if (t1_time > 0 && t1_time < timer_ceiling) {
OptionUint32Ptr t1(new OptionUint32(Option::V4, DHO_DHCP_RENEWAL_TIME, t1_time));
resp->addOption(t1);
}
}
uint16_t uint16_t
Dhcpv4Srv::checkRelayPort(const Dhcpv4Exchange& ex) { Dhcpv4Srv::checkRelayPort(const Dhcpv4Exchange& ex) {
......
// Copyright (C) 2011-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -539,6 +539,33 @@ protected: ...@@ -539,6 +539,33 @@ protected:
/// @param ex DHCPv4 exchange holding the client's message to be checked. /// @param ex DHCPv4 exchange holding the client's message to be checked.
void assignLease(Dhcpv4Exchange& ex); void assignLease(Dhcpv4Exchange& ex);
/// @brief Adds the T1 and T2 timers to the outbound response as appropriate
///
/// This method determines if either of the timers T1 (option 58) and T2
/// (option 59) should be sent to the client. It is influenced by the
/// lease's subnet's values for renew-timer, rebind-timer,
/// calculate-tee-times, t1-percent, and t2-percent as follows:
///
/// By default neither T1 nor T2 will be sent.
///
/// T2:
///
/// If rebind-timer is set use its value, otherwise if calculate-tee-times
/// is true use the value given by valid lease time * t2-percent. Either
/// way the value will only be sent if it is less than the valid lease time.
///
/// T1:
///
/// If renew-timer is set use its value, otherwise if calculate-tee-times
/// is true use the value given by valid lease time * t1-percent. Either
/// way the value will only be sent if it is less than T2 when T2 is being
/// sent, or less than the valid lease time if T2 is not being sent.
///
/// @param lease lease being assigned to the client
/// @param subnet the subnet to which the lease belongs
/// @param resp outbound response for the client to which timers are added.
void setTeeTimes(const Lease4Ptr& lease, const Subnet4Ptr& subnet, Pkt4Ptr resp);
/// @brief Append basic options if they are not present. /// @brief Append basic options if they are not present.
/// ///
/// This function adds the following basic options if they /// This function adds the following basic options if they
......
// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -546,7 +546,10 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set, ...@@ -546,7 +546,10 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
(config_pair.first == "server-hostname") || (config_pair.first == "server-hostname") ||
(config_pair.first == "boot-file-name") || (config_pair.first == "boot-file-name") ||
(config_pair.first == "server-tag") || (config_pair.first == "server-tag") ||
(config_pair.first == "reservation-mode")) { (config_pair.first == "reservation-mode") ||
(config_pair.first == "calculate-tee-times") ||
(config_pair.first == "t1-percent") ||
(config_pair.first == "t2-percent")) {
continue; continue;
} }
......
// Generated 201811271343 // Generated 201901101446
// A Bison parser, made by GNU Bison 3.2.1. // A Bison parser, made by GNU Bison 3.2.4.
// Locations for Bison parsers in C++ // Locations for Bison parsers in C++
......
// Generated 201811271343 // Generated 201901101446
// A Bison parser, made by GNU Bison 3.2.1. // A Bison parser, made by GNU Bison 3.2.4.
// Starting with Bison 3.2, this file is useless: the structure it // Starting with Bison 3.2, this file is useless: the structure it
// used to define is now defined in "location.hh". // used to define is now defined in "location.hh".
......
// Generated 201811271343 // Generated 201901101446
// A Bison parser, made by GNU Bison 3.2.1. // A Bison parser, made by GNU Bison 3.2.4.
// Starting with Bison 3.2, this file is useless: the structure it // Starting with Bison 3.2, this file is useless: the structure it
// used to define is now defined with the parser itself. // used to define is now defined with the parser itself.
......
// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <dhcpsrv/testutils/test_config_backend_dhcp4.h> #include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
#include <process/config_ctl_info.h> #include <process/config_ctl_info.h>
#include <hooks/hooks_manager.h> #include <hooks/hooks_manager.h>
#include <util/doubles.h>
#include "marker_file.h" #include "marker_file.h"
#include "test_libraries.h" #include "test_libraries.h"
...@@ -6633,4 +6634,69 @@ TEST_F(Dhcp4ParserTest, dhcpQueueControlInvalid) { ...@@ -6633,4 +6634,69 @@ TEST_F(Dhcp4ParserTest, dhcpQueueControlInvalid) {
} }
} }
// Checks inheritence of calculate-tee-times, t1-perecent, t2-percent
TEST_F(Dhcp4ParserTest, calculateTeeTimesInheritence) {
// Configure the server. This should succeed.
string config =
"{ \n"
" \"interfaces-config\": { \n"
" \"interfaces\": [\"*\" ] \n"
" }, \n"
" \"valid-lifetime\": 4000, \n"
" \"shared-networks\": [ { \n"
" \"name\": \"foo\", \n"
" \"calculate-tee-times\": true, \n"
" \"t1-percent\": .4, \n"
" \"t2-percent\": .75,\n"
" \"subnet4\": ["
" { "
" \"id\": 100,"
" \"subnet\": \"192.0.1.0/24\", \n"
" \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ], \n"
" \"calculate-tee-times\": false,\n"
" \"t1-percent\": .45, \n"
" \"t2-percent\": .65 \n"
" }, \n"
" { \n"
" \"id\": 200, \n"
" \"subnet\": \"192.0.2.0/24\", \n"
" \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\"} ] \n"
" } \n"
" ] \n"
" } ], \n"
" \"subnet4\": [ { \n"
" \"id\": 300, \n"
" \"subnet\": \"192.0.3.0/24\", \n"
" \"pools\": [ { \"pool\": \"192.0.3.0 - 192.0.3.15\" } ]\n"
" } ] \n"
"} \n";
extractConfig(config);
configure(config, CONTROL_RESULT_SUCCESS, "");
CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
// Subnet 100 should use it's own explicit values.
ConstSubnet4Ptr subnet4 = subnets4->getBySubnetId(100);
ASSERT_TRUE(subnet4);
EXPECT_EQ(false, subnet4->getCalculateTeeTimes());
EXPECT_TRUE(util::areDoublesEquivalent(0.45, subnet4->getT1Percent()));
EXPECT_TRUE(util::areDoublesEquivalent(0.65, subnet4->getT2Percent()));
// Subnet 200 should use the shared-network values.
subnet4 = subnets4->getBySubnetId(200);
ASSERT_TRUE(subnet4);
EXPECT_EQ(true, subnet4->getCalculateTeeTimes());
EXPECT_TRUE(util::areDoublesEquivalent(0.4, subnet4->getT1Percent()));
EXPECT_TRUE(util::areDoublesEquivalent(0.75, subnet4->getT2Percent()));
// Subnet 300 should use the global values.
subnet4 = subnets4->getBySubnetId(300);
ASSERT_TRUE(subnet4);
EXPECT_EQ(false, subnet4->getCalculateTeeTimes());
EXPECT_TRUE(util::areDoublesEquivalent(0.5, subnet4->getT1Percent()));
EXPECT_TRUE(util::areDoublesEquivalent(0.875, subnet4->getT2Percent()));
}
} }
// Copyright (C) 2011-2018 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC")
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
...@@ -761,7 +761,8 @@ TEST_F(Dhcpv4SrvTest, DiscoverBasic) { ...@@ -761,7 +761,8 @@ TEST_F(Dhcpv4SrvTest, DiscoverBasic) {
} }
// Check that option 58 and 59 are only included if they were specified // Check that option 58 and 59 are only included if they were specified
// and T2 is less than valid lft; T1 is less than T2 (if given) or valid // (and calculate-tee-times = false) and the values are sane:
// T2 is less than valid lft; T1 is less than T2 (if given) or valid
// lft if T2 is not given. // lft if T2 is not given.
TEST_F(Dhcpv4SrvTest, DiscoverTimers) { TEST_F(Dhcpv4SrvTest, DiscoverTimers) {
IfaceMgrTestConfig test_config(true); IfaceMgrTestConfig test_config(true);
...@@ -909,6 +910,144 @@ TEST_F(Dhcpv4SrvTest, DiscoverTimers) { ...@@ -909,6 +910,144 @@ TEST_F(Dhcpv4SrvTest, DiscoverTimers) {
} }
// Check that option 58 and 59 are included when calculate-tee-times
// is enabled, but only when they are not explicitly specified via
// renew-timer and rebinding-timer. This test does not check whether
// the subnet's for t1-percent and t2-percent are valid, as this is
// enforced by parsing and tested elsewhere.
TEST_F(Dhcpv4SrvTest, calculateTeeTimers) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
// Recreate subnet
Triplet<uint32_t> unspecified;
Triplet<uint32_t> valid_lft(1000);
subnet_.reset(new Subnet4(IOAddress("192.0.2.0"), 24,
unspecified,
unspecified,
valid_lft));
pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"),
IOAddress("192.0.2.110")));
subnet_->addPool(pool_);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_);
CfgMgr::instance().commit();
// Struct for describing an individual timer test scenario
struct TimerTest {
// logged test description
std::string description_;
// configured value for subnet's T1
Triplet<uint32_t> cfg_t1_;
// configured value for subnet's T1
Triplet<uint32_t> cfg_t2_;
// configured value for sunbet's t1_percent.
double t1_percent_;
// configured value for sunbet's t2_percent.
double t2_percent_;
// expected value for T1 in server response.
// A value of 0 means server should not have sent T1.
uint32_t t1_exp_value_;
// expected value for T2 in server response.
// A value of 0 means server should not have sent T2.
uint32_t t2_exp_value_;
};
// Convenience constant
uint32_t not_expected = 0;
// Test scenarios
std::vector<TimerTest> tests = {
{
"T1 and T2 calculated",
unspecified, unspecified,
0.4, 0.8,
400, 800
},
{
"T1 and T2 specified insane",
valid_lft + 1, valid_lft + 2,
0.4, 0.8,
not_expected, not_expected
},
{
"T1 should be calculated, T2 specified",
unspecified, valid_lft - 1,
0.4, 0.8,
400, valid_lft - 1
},
{
"T1 specified, T2 should be calculated",
299, unspecified,
0.4, 0.8,
299, 800
},
{
"T1 specified > T2, T2 should be calculated",
valid_lft - 1, unspecified,
0.4, 0.8,
not_expected, 800
}
};
// Calculation is enabled for all the scenarios.
subnet_->setCalculateTeeTimes(true);
// Create a discover packet to use
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));