Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
5cbbab2d
Commit
5cbbab2d
authored
Aug 27, 2014
by
Marcin Siodelski
Browse files
[master] Merge branch 'trac3512'
Conflicts: src/lib/dhcpsrv/configuration.h
parents
b46dd8a0
69c2e41c
Changes
38
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/bundy_controller.cc
View file @
5cbbab2d
...
...
@@ -177,7 +177,8 @@ void ControlledDhcpv4Srv::init(const std::string& config_file) {
// Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration.
openActiveSockets
(
getPort
(),
useBroadcast
());
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
getPort
(),
useBroadcast
());
}
catch
(
const
std
::
exception
&
ex
)
{
LOG_ERROR
(
dhcp4_logger
,
DHCP4_CONFIG_LOAD_FAIL
).
arg
(
ex
.
what
());
...
...
src/bin/dhcp4/ctrl_dhcp4_srv.cc
View file @
5cbbab2d
...
...
@@ -18,6 +18,7 @@
#include
<dhcp4/dhcp4_log.h>
#include
<hooks/hooks_manager.h>
#include
<dhcp4/json_config_parser.h>
#include
<dhcpsrv/cfgmgr.h>
using
namespace
isc
::
data
;
using
namespace
isc
::
hooks
;
...
...
@@ -117,7 +118,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
err
<<
"Server object not initialized, can't process config."
;
return
(
isc
::
config
::
createAnswer
(
1
,
err
.
str
()));
}
ConstElementPtr
answer
=
configureDhcp4Server
(
*
srv
,
config
);
...
...
@@ -148,7 +149,9 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
// safe and we really don't want to emit exceptions to whoever called this
// method. Instead, catch an exception and create appropriate answer.
try
{
srv
->
openActiveSockets
(
srv
->
getPort
(),
getInstance
()
->
useBroadcast
());
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
srv
->
getPort
(),
getInstance
()
->
useBroadcast
());
}
catch
(
std
::
exception
&
ex
)
{
err
<<
"failed to open sockets after server reconfiguration: "
<<
ex
.
what
();
...
...
src/bin/dhcp4/dhcp4_srv.cc
View file @
5cbbab2d
...
...
@@ -1795,55 +1795,6 @@ Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
}
}
void
Dhcpv4Srv
::
openActiveSockets
(
const
uint16_t
port
,
const
bool
use_bcast
)
{
IfaceMgr
::
instance
().
closeSockets
();
// Get the reference to the collection of interfaces. This reference should
// be valid as long as the program is run because IfaceMgr is a singleton.
// Therefore we can safely iterate over instances of all interfaces and
// modify their flags. Here we modify flags which indicate whether socket
// should be open for a particular interface or not.
const
IfaceMgr
::
IfaceCollection
&
ifaces
=
IfaceMgr
::
instance
().
getIfaces
();
for
(
IfaceMgr
::
IfaceCollection
::
const_iterator
iface
=
ifaces
.
begin
();
iface
!=
ifaces
.
end
();
++
iface
)
{
Iface
*
iface_ptr
=
IfaceMgr
::
instance
().
getIface
(
iface
->
getName
());
if
(
iface_ptr
==
NULL
)
{
isc_throw
(
isc
::
Unexpected
,
"Interface Manager returned NULL"
<<
" instance of the interface when DHCPv4 server was"
<<
" trying to reopen sockets after reconfiguration"
);
}
// Ignore loopback interfaces.
if
(
iface_ptr
->
flag_loopback_
)
{
iface_ptr
->
inactive4_
=
true
;
}
else
if
(
CfgMgr
::
instance
().
isActiveIface
(
iface
->
getName
()))
{
iface_ptr
->
inactive4_
=
false
;
LOG_INFO
(
dhcp4_logger
,
DHCP4_ACTIVATE_INTERFACE
)
.
arg
(
iface
->
getFullName
());
}
else
{
// For deactivating interface, it should be sufficient to log it
// on the debug level because it is more useful to know what
// interface is activated which is logged on the info level.
LOG_DEBUG
(
dhcp4_logger
,
DBG_DHCP4_BASIC
,
DHCP4_DEACTIVATE_INTERFACE
).
arg
(
iface
->
getName
());
iface_ptr
->
inactive4_
=
true
;
}
}
// Let's reopen active sockets. openSockets4 will check internally whether
// sockets are marked active or inactive.
/// @todo Optimization: we should not reopen all sockets but rather select
/// those that have been affected by the new configuration.
isc
::
dhcp
::
IfaceMgrErrorMsgCallback
error_handler
=
boost
::
bind
(
&
Dhcpv4Srv
::
ifaceMgrSocket4ErrorHandler
,
_1
);
if
(
!
IfaceMgr
::
instance
().
openSockets4
(
port
,
use_bcast
,
error_handler
))
{
LOG_WARN
(
dhcp4_logger
,
DHCP4_NO_SOCKETS_OPEN
);
}
}
size_t
Dhcpv4Srv
::
unpackOptions
(
const
OptionBuffer
&
buf
,
const
std
::
string
&
option_space
,
...
...
src/bin/dhcp4/dhcp4_srv.h
View file @
5cbbab2d
...
...
@@ -128,11 +128,6 @@ public:
///
/// @name Public accessors returning values required to (re)open sockets.
///
/// These accessors must be public because sockets are reopened from the
/// static configuration callback handler. This callback handler invokes
/// @c ControlledDhcpv4Srv::openActiveSockets which requires parameters
/// which has to be retrieved from the @c ControlledDhcpv4Srv object.
/// They are retrieved using these public functions
//@{
///
/// @brief Get UDP port on which server should listen.
...
...
@@ -154,17 +149,6 @@ public:
}
//@}
/// @brief Open sockets which are marked as active in @c CfgMgr.
///
/// This function reopens sockets according to the current settings in the
/// Configuration Manager. It holds the list of the interfaces which server
/// should listen on. This function will open sockets on these interfaces
/// only. This function is not exception safe.
///
/// @param port UDP port on which server should listen.
/// @param use_bcast should broadcast flags be set on the sockets.
static
void
openActiveSockets
(
const
uint16_t
port
,
const
bool
use_bcast
);
/// @brief Starts DHCP_DDNS client IO if DDNS updates are enabled.
///
/// If updates are enabled, it Instructs the D2ClientMgr singleton to
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
5cbbab2d
...
...
@@ -25,6 +25,7 @@
#include
<dhcp/option_int.h>
#include
<dhcp/docsis3_option_defs.h>
#include
<dhcp/classify.h>
#include
<dhcp/tests/iface_mgr_test_config.h>
#include
<dhcpsrv/subnet.h>
#include
<dhcpsrv/cfgmgr.h>
#include
<dhcpsrv/testutils/config_result_check.h>
...
...
@@ -77,7 +78,6 @@ public:
// deal with sockets here, just check if configuration handling
// is sane.
srv_
.
reset
(
new
Dhcpv4Srv
(
0
));
CfgMgr
::
instance
().
deleteActiveIfaces
();
// Create fresh context.
globalContext
()
->
copyContext
(
ParserContext
(
Option
::
V4
));
}
...
...
@@ -2895,6 +2895,8 @@ TEST_F(Dhcp4ParserTest, LibrariesSpecified) {
// This test verifies that it is possible to select subset of interfaces
// on which server should listen.
TEST_F
(
Dhcp4ParserTest
,
selectedInterfaces
)
{
IfaceMgrTestConfig
test_config
(
true
);
ConstElementPtr
x
;
string
config
=
"{
\"
interfaces
\"
: [
\"
eth0
\"
,
\"
eth1
\"
],"
"
\"
rebind-timer
\"
: 2000, "
...
...
@@ -2907,24 +2909,26 @@ TEST_F(Dhcp4ParserTest, selectedInterfaces) {
// Make sure the config manager is clean and there is no hanging
// interface configuration.
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
EXPECT_FALSE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET
));
EXPECT_FALSE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET
));
// Apply configuration.
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
0
);
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
10000
);
// eth0 and eth1 were explicitly selected. eth2 was not.
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
EXPECT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
EXPECT_TRUE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET
));
EXPECT_TRUE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET
));
}
// This test verifies that it is possible to configure the server in such a way
// that it listens on all interfaces.
TEST_F
(
Dhcp4ParserTest
,
allInterfaces
)
{
IfaceMgrTestConfig
test_config
(
true
);
ConstElementPtr
x
;
// This configuration specifies two interfaces on which server should listen
// but it also includes asterisk. The asterisk switches server into the
...
...
@@ -2940,19 +2944,19 @@ TEST_F(Dhcp4ParserTest, allInterfaces) {
ConstElementPtr
status
;
// Make sure there is no old configuration.
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
ASSERT_FALSE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET
));
ASSERT_FALSE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET
));
// Apply configuration.
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
0
);
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
10000
);
// All interfaces should be now active.
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
ASSERT_TRUE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET
));
ASSERT_TRUE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET
));
}
// This test checks the ability of the server to parse a configuration
...
...
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
View file @
5cbbab2d
...
...
@@ -420,26 +420,6 @@ TEST_F(Dhcpv4SrvTest, basic) {
ASSERT_NO_THROW
(
naked_srv
.
reset
(
new
NakedDhcpv4Srv
(
0
)));
}
// This test verifies that exception is not thrown when an error occurs during
// opening sockets. This test forces an error by adding a fictious interface
// to the IfaceMgr. An attempt to open socket on this interface must always
// fail. The DHCPv4 installs the error handler function to prevent exceptions
// being thrown from the openSockets4 function.
// @todo The server tests for socket should be extended but currently the
// ability to unit test the sockets code is somewhat limited.
TEST_F
(
Dhcpv4SrvTest
,
openActiveSockets
)
{
ASSERT_NO_THROW
(
CfgMgr
::
instance
().
activateAllIfaces
());
Iface
iface
(
"bogusiface"
,
255
);
iface
.
flag_loopback_
=
false
;
iface
.
flag_up_
=
true
;
iface
.
flag_running_
=
true
;
iface
.
inactive4_
=
false
;
iface
.
addAddress
(
IOAddress
(
"192.0.0.0"
));
IfaceMgr
::
instance
().
addInterface
(
iface
);
ASSERT_NO_THROW
(
Dhcpv4Srv
::
openActiveSockets
(
DHCP4_SERVER_PORT
,
false
));
}
// Verifies that DISCOVER message can be processed correctly,
// that the OFFER message generated in response is valid and
// contains necessary options.
...
...
@@ -2970,7 +2950,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) {
NakedDhcpv4Srv
srv
(
0
);
ConstElementPtr
x
;
string
config
=
"{
\"
interfaces
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
option-data
\"
: [ {"
...
...
@@ -3055,7 +3035,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) {
// src/lib/dhcp/docsis3_option_defs.h.
TEST_F
(
Dhcpv4SrvTest
,
vendorOptionsDocsisDefinitions
)
{
ConstElementPtr
x
;
string
config_prefix
=
"{
\"
interfaces
\"
: [
\"
all
\"
],"
string
config_prefix
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
option-data
\"
: [ {"
...
...
src/bin/dhcp4/tests/dhcp4_test_utils.cc
View file @
5cbbab2d
...
...
@@ -45,7 +45,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
pool_
=
Pool4Ptr
(
new
Pool4
(
IOAddress
(
"192.0.2.100"
),
IOAddress
(
"192.0.2.110"
)));
subnet_
->
addPool
(
pool_
);
CfgMgr
::
instance
().
deleteActiveIfaces
();
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
reset
();
CfgMgr
::
instance
().
deleteSubnets4
();
CfgMgr
::
instance
().
addSubnet4
(
subnet_
);
...
...
@@ -58,6 +58,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
Dhcpv4SrvTest
::~
Dhcpv4SrvTest
()
{
// Make sure that we revert to default value
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
reset
();
CfgMgr
::
instance
().
echoClientId
(
true
);
}
...
...
src/bin/dhcp4/tests/dora_unittest.cc
View file @
5cbbab2d
...
...
@@ -49,7 +49,7 @@ namespace {
/// - Quotes Servers option present: 192.0.2.202, 192.0.2.203.
const
char
*
DORA_CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
10.0.0.0/24
\"
, "
...
...
@@ -86,7 +86,7 @@ const char* DORA_CONFIGS[] = {
"}"
,
// Configuration 1
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
, "
...
...
src/bin/dhcp4/tests/inform_unittest.cc
View file @
5cbbab2d
...
...
@@ -48,7 +48,7 @@ namespace {
/// - Quotes Servers option present: 192.0.2.202, 192.0.2.203.
const
char
*
INFORM_CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
10.0.0.0/24
\"
, "
...
...
@@ -85,7 +85,7 @@ const char* INFORM_CONFIGS[] = {
"}"
,
// Configuration 1
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
, "
...
...
src/bin/dhcp6/bundy_controller.cc
View file @
5cbbab2d
...
...
@@ -183,7 +183,10 @@ ControlledDhcpv6Srv::init(const std::string& config_file) {
// Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration.
openActiveSockets
(
getPort
());
// Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration.
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
getPort
(),
useBroadcast
());
}
catch
(
const
std
::
exception
&
ex
)
{
LOG_ERROR
(
dhcp6_logger
,
DHCP6_CONFIG_LOAD_FAIL
).
arg
(
ex
.
what
());
...
...
src/bin/dhcp6/ctrl_dhcp6_srv.cc
View file @
5cbbab2d
...
...
@@ -14,6 +14,7 @@
#include
<config.h>
#include
<cc/data.h>
#include
<dhcpsrv/cfgmgr.h>
#include
<dhcp6/ctrl_dhcp6_srv.h>
#include
<dhcp6/dhcp6_log.h>
#include
<hooks/hooks_manager.h>
...
...
@@ -143,10 +144,13 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
// safe and we really don't want to emit exceptions to the callback caller.
// Instead, catch an exception and create appropriate answer.
try
{
srv
->
openActiveSockets
(
srv
->
getPort
());
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
srv
->
getPort
());
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
ostringstream
err
;
err
<<
"failed to open sockets after server reconfiguration: "
<<
ex
.
what
();
err
<<
"failed to open sockets after server reconfiguration: "
<<
ex
.
what
();
answer
=
isc
::
config
::
createAnswer
(
1
,
err
.
str
());
}
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
5cbbab2d
...
...
@@ -150,6 +150,12 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
// Instantiate allocation engine
alloc_engine_
.
reset
(
new
AllocEngine
(
AllocEngine
::
ALLOC_ITERATIVE
,
100
));
// We have to point out to the CfgMgr that the we are in the IPv6
// domain, so as the IPv6 sockets are opened rather than IPv4 sockets
// which are the default.
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
setFamily
(
CfgIface
::
V6
);
/// @todo call loadLibraries() when handling configuration changes
}
catch
(
const
std
::
exception
&
e
)
{
...
...
@@ -2429,64 +2435,6 @@ Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
return
reply
;
}
void
Dhcpv6Srv
::
openActiveSockets
(
const
uint16_t
port
)
{
IfaceMgr
::
instance
().
closeSockets
();
// Get the reference to the collection of interfaces. This reference should be
// valid as long as the program is run because IfaceMgr is a singleton.
// Therefore we can safely iterate over instances of all interfaces and modify
// their flags. Here we modify flags which indicate wheter socket should be
// open for a particular interface or not.
const
IfaceMgr
::
IfaceCollection
&
ifaces
=
IfaceMgr
::
instance
().
getIfaces
();
for
(
IfaceMgr
::
IfaceCollection
::
const_iterator
iface
=
ifaces
.
begin
();
iface
!=
ifaces
.
end
();
++
iface
)
{
Iface
*
iface_ptr
=
IfaceMgr
::
instance
().
getIface
(
iface
->
getName
());
if
(
iface_ptr
==
NULL
)
{
isc_throw
(
isc
::
Unexpected
,
"Interface Manager returned NULL"
<<
" instance of the interface when DHCPv6 server was"
<<
" trying to reopen sockets after reconfiguration"
);
}
// Ignore loopback interfaces.
if
(
iface_ptr
->
flag_loopback_
)
{
iface_ptr
->
inactive6_
=
true
;
}
else
if
(
CfgMgr
::
instance
().
isActiveIface
(
iface
->
getName
()))
{
iface_ptr
->
inactive6_
=
false
;
LOG_INFO
(
dhcp6_logger
,
DHCP6_ACTIVATE_INTERFACE
)
.
arg
(
iface
->
getFullName
());
}
else
{
// For deactivating interface, it should be sufficient to log it
// on the debug level because it is more useful to know what
// interface is activated which is logged on the info level.
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_BASIC
,
DHCP6_DEACTIVATE_INTERFACE
).
arg
(
iface
->
getName
());
iface_ptr
->
inactive6_
=
true
;
}
iface_ptr
->
clearUnicasts
();
const
IOAddress
*
unicast
=
CfgMgr
::
instance
().
getUnicast
(
iface
->
getName
());
if
(
unicast
)
{
LOG_INFO
(
dhcp6_logger
,
DHCP6_SOCKET_UNICAST
).
arg
(
unicast
->
toText
())
.
arg
(
iface
->
getName
());
iface_ptr
->
addUnicast
(
*
unicast
);
}
}
// Let's reopen active sockets. openSockets6 will check internally whether
// sockets are marked active or inactive.
// @todo Optimization: we should not reopen all sockets but rather select
// those that have been affected by the new configuration.
isc
::
dhcp
::
IfaceMgrErrorMsgCallback
error_handler
=
boost
::
bind
(
&
Dhcpv6Srv
::
ifaceMgrSocket6ErrorHandler
,
_1
);
if
(
!
IfaceMgr
::
instance
().
openSockets6
(
port
,
error_handler
))
{
LOG_WARN
(
dhcp6_logger
,
DHCP6_NO_SOCKETS_OPEN
);
}
}
size_t
Dhcpv6Srv
::
unpackOptions
(
const
OptionBuffer
&
buf
,
const
std
::
string
&
option_space
,
...
...
src/bin/dhcp6/dhcp6_srv.h
View file @
5cbbab2d
...
...
@@ -100,27 +100,11 @@ public:
/// Typically, server listens on UDP port 547. Other ports are only
/// used for testing purposes.
///
/// This accessor must be public because sockets are reopened from the
/// static configuration callback handler. This callback handler invokes
/// @c ControlledDhcpv4Srv::openActiveSockets which requires port parameter
/// which has to be retrieved from the @c ControlledDhcpv4Srv object.
/// They are retrieved using this public function.
///
/// @return UDP port on which server should listen.
uint16_t
getPort
()
const
{
return
(
port_
);
}
/// @brief Open sockets which are marked as active in @c CfgMgr.
///
/// This function reopens sockets according to the current settings in the
/// Configuration Manager. It holds the list of the interfaces which server
/// should listen on. This function will open sockets on these interfaces
/// only. This function is not exception safe.
///
/// @param port UDP port on which server should listen.
static
void
openActiveSockets
(
const
uint16_t
port
);
/// @brief Starts DHCP_DDNS client IO if DDNS updates are enabled.
///
/// If updates are enabled, it Instructs the D2ClientMgr singleton to
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
5cbbab2d
...
...
@@ -20,6 +20,7 @@
#include
<dhcp/iface_mgr.h>
#include
<dhcp/option_custom.h>
#include
<dhcp/option_int.h>
#include
<dhcp/tests/iface_mgr_test_config.h>
#include
<dhcp6/json_config_parser.h>
#include
<dhcp6/dhcp6_srv.h>
#include
<dhcpsrv/addr_utilities.h>
...
...
@@ -74,7 +75,8 @@ public:
// deal with sockets here, just check if configuration handling
// is sane.
const
IfaceMgr
::
IfaceCollection
&
ifaces
=
IfaceMgr
::
instance
().
getIfaces
();
const
IfaceMgr
::
IfaceCollection
&
ifaces
=
IfaceMgr
::
instance
().
getIfaces
();
// There must be some interface detected
if
(
ifaces
.
empty
())
{
...
...
@@ -341,7 +343,7 @@ public:
/// test to make sure that contents of the database do not affect the
/// results of subsequent tests.
void
resetConfiguration
()
{
string
config
=
"{
\"
interfaces
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
hooks-libraries
\"
: [ ],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
...
...
@@ -357,7 +359,9 @@ public:
// properly test interface configuration we disable listening on
// all interfaces before each test and later check that this setting
// has been overriden by the configuration used in the test.
CfgMgr
::
instance
().
deleteActiveIfaces
();
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
reset
();
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
setFamily
(
CfgIface
::
V6
);
// Create fresh context.
globalContext
()
->
copyContext
(
ParserContext
(
Option
::
V6
));
}
...
...
@@ -2892,7 +2896,7 @@ buildHooksLibrariesConfig(const std::vector<std::string>& libraries) {
// Create the first part of the configuration string.
string
config
=
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
hooks-libraries
\"
: ["
;
// Append the libraries (separated by commas if needed)
...
...
@@ -3030,15 +3034,15 @@ TEST_F(Dhcp6ParserTest, LibrariesSpecified) {
// This test verifies that it is possible to select subset of interfaces on
// which server should listen.
TEST_F
(
Dhcp6ParserTest
,
selectedInterfaces
)
{
IfaceMgrTestConfig
test_config
(
true
);
// Make sure there is no garbage interface configuration in the CfgMgr.
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
ASSERT_FALSE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET6
));
ASSERT_FALSE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET6
));
ConstElementPtr
status
;
string
config
=
"{
\"
interfaces
\"
: [
\"
eth0
\"
,
\"
eth1
\"
],"
string
config
=
"{
\"
interfaces
\"
: [
\"
eth0
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -3053,20 +3057,20 @@ TEST_F(Dhcp6ParserTest, selectedInterfaces) {
// as the pool does not belong to that subnet
checkResult
(
status
,
0
);
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
10000
);
// eth0 and eth1 were explicitly selected. eth2 was not.
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
EXPECT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
EXPECT_TRUE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET6
));
EXPECT_FALSE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET6
));
}
// This test verifies that it is possible to configure the server to listen on
// all interfaces.
TEST_F
(
Dhcp6ParserTest
,
allInterfaces
)
{
IfaceMgrTestConfig
test_config
(
true
);
// Make sure there is no garbage interface configuration in the CfgMgr.
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
ASSERT_FALSE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET6
));
ASSERT_FALSE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET6
));
ConstElementPtr
status
;
...
...
@@ -3084,15 +3088,13 @@ TEST_F(Dhcp6ParserTest, allInterfaces) {
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
json
));
// returned value must be 1 (values error)
// as the pool does not belong to that subnet
checkResult
(
status
,
0
);
CfgMgr
::
instance
().
getConfiguration
()
->
cfg_iface_
.
openSockets
(
10000
);
// All interfaces should be now active.
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
EXPECT_TRUE
(
test_config
.
socketOpen
(
"eth0"
,
AF_INET6
));
EXPECT_TRUE
(
test_config
.
socketOpen
(
"eth1"
,
AF_INET6
));
}
...
...
src/bin/dhcp6/tests/confirm_unittest.cc
View file @
5cbbab2d
...
...
@@ -42,7 +42,7 @@ namespace {
///
const
char
*
CONFIRM_CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -61,7 +61,7 @@ const char* CONFIRM_CONFIGS[] = {
"
\"
valid-lifetime
\"
: 4000 }"
,
// Configuration 1
"{
\"
interfaces
\"
: [
\"
all
\"
],"
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
src/bin/dhcp6/tests/d2_unittest.cc
View file @
5cbbab2d
...
...
@@ -75,7 +75,7 @@ Dhcp6SrvD2Test::buildTestNcr(uint32_t dhcid_id_num) {
void
Dhcp6SrvD2Test
::
reset
()
{
std
::
string
config
=
"{
\"
interfaces
\"
: [
\"
all
\"
],"
std
::
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
hooks-libraries
\"
: [ ],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
...
...
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
View file @
5cbbab2d
...
...
@@ -289,7 +289,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
IfaceMgrTestConfig
test_config
(
true
);
ConstElementPtr
x
;
string
config
=
"{
\"
interfaces
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interfaces
\"
: [
\"
*
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -1557,7 +1557,7 @@ TEST_F(Dhcpv6SrvTest, vendorOptionsORO) {
IfaceMgrTestConfig
test_config
(
true
);