Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Kea
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
446
Issues
446
List
Boards
Labels
Service Desk
Milestones
Merge Requests
73
Merge Requests
73
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
Kea
Commits
7e9fdfa6
Commit
7e9fdfa6
authored
May 20, 2014
by
Tomek Mrugalski
🛰
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'trac3400'
parents
fccc9c59
5625dbfd
Changes
36
Show whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1628 additions
and
342 deletions
+1628
-342
ChangeLog
ChangeLog
+7
-0
configure.ac
configure.ac
+34
-0
doc/devel/mainpage.dox
doc/devel/mainpage.dox
+1
-0
doc/examples/kea6/several-subnets.json
doc/examples/kea6/several-subnets.json
+36
-0
doc/guide/bind10-guide.xml
doc/guide/bind10-guide.xml
+43
-1
src/bin/dhcp6/Makefile.am
src/bin/dhcp6/Makefile.am
+10
-2
src/bin/dhcp6/bundy_controller.cc
src/bin/dhcp6/bundy_controller.cc
+227
-0
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/bin/dhcp6/ctrl_dhcp6_srv.cc
+99
-210
src/bin/dhcp6/ctrl_dhcp6_srv.h
src/bin/dhcp6/ctrl_dhcp6_srv.h
+82
-55
src/bin/dhcp6/dhcp6.dox
src/bin/dhcp6/dhcp6.dox
+39
-0
src/bin/dhcp6/dhcp6_messages.mes
src/bin/dhcp6/dhcp6_messages.mes
+5
-4
src/bin/dhcp6/dhcp6_srv.h
src/bin/dhcp6/dhcp6_srv.h
+2
-7
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/json_config_parser.cc
+1
-1
src/bin/dhcp6/json_config_parser.h
src/bin/dhcp6/json_config_parser.h
+0
-0
src/bin/dhcp6/kea_controller.cc
src/bin/dhcp6/kea_controller.cc
+143
-0
src/bin/dhcp6/main.cc
src/bin/dhcp6/main.cc
+40
-20
src/bin/dhcp6/tests/Makefile.am
src/bin/dhcp6/tests/Makefile.am
+17
-4
src/bin/dhcp6/tests/bundy_controller_unittest.cc
src/bin/dhcp6/tests/bundy_controller_unittest.cc
+26
-0
src/bin/dhcp6/tests/config_parser_unittest.cc
src/bin/dhcp6/tests/config_parser_unittest.cc
+6
-1
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
+71
-20
src/bin/dhcp6/tests/d2_unittest.cc
src/bin/dhcp6/tests/d2_unittest.cc
+1
-1
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+3
-3
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
+1
-1
src/bin/dhcp6/tests/hooks_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc
+1
-1
src/bin/dhcp6/tests/kea_controller_unittest.cc
src/bin/dhcp6/tests/kea_controller_unittest.cc
+238
-0
src/bin/dhcp6/tests/rebind_unittest.cc
src/bin/dhcp6/tests/rebind_unittest.cc
+1
-1
src/lib/cc/data.cc
src/lib/cc/data.cc
+57
-6
src/lib/cc/data.h
src/lib/cc/data.h
+46
-3
src/lib/cc/tests/Makefile.am
src/lib/cc/tests/Makefile.am
+1
-0
src/lib/cc/tests/data_file_unittests.cc
src/lib/cc/tests/data_file_unittests.cc
+107
-0
src/lib/cc/tests/data_unittests.cc
src/lib/cc/tests/data_unittests.cc
+109
-1
src/lib/dhcpsrv/Makefile.am
src/lib/dhcpsrv/Makefile.am
+3
-0
src/lib/dhcpsrv/daemon.cc
src/lib/dhcpsrv/daemon.cc
+45
-0
src/lib/dhcpsrv/daemon.h
src/lib/dhcpsrv/daemon.h
+93
-0
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/Makefile.am
+1
-0
src/lib/dhcpsrv/tests/daemon_unittest.cc
src/lib/dhcpsrv/tests/daemon_unittest.cc
+32
-0
No files found.
ChangeLog
View file @
7e9fdfa6
7XX. [func]* tomek
b10-dhcp6: New parameter added to configure: --with-kea-config.
It allows selecting configuration backend and accepts one of two
values: BIND10, which uses BIND10 framework as Kea 0.8 did, or
JSON, which reads configuration from a JSON file.
(Trac #3400, git TBD)
782. [func] tmark
Added sender-ip, sender-port, and max-queue-size parameters to
the dhcp-ddns configuration section of both b10-dhcp4 and b10-dhcp6.
...
...
configure.ac
View file @
7e9fdfa6
...
...
@@ -565,6 +565,9 @@ AC_SUBST(PYCOVERAGE)
AC_SUBST(PYCOVERAGE_RUN)
AC_SUBST(USE_PYCOVERAGE)
enable_gtest="no"
GTEST_INCLUDES=
...
...
@@ -1282,6 +1285,34 @@ AC_SUBST(PERL)
AC_PATH_PROGS(AWK, gawk awk)
AC_SUBST(AWK)
# Kea configuration backend section
# Currently there are 2 backends available: BUNDY and JSON
# It is possible that we may extend this to accept additional backends.
AC_ARG_WITH(kea-config,
AC_HELP_STRING([--with-kea-config],
[Selects configuration backend; currently available options are: BUNDY (default,
Kea reads configuration and commands from Bundy framework) or JSON (Kea reads
configuration from a JSON file from disk)]),
[CONFIG_BACKEND="$withval"],
[CONFIG_BACKEND=BUNDY])
AM_CONDITIONAL(CONFIG_BACKEND_BUNDY, test "x$CONFIG_BACKEND" = "xBUNDY")
AM_CONDITIONAL(CONFIG_BACKEND_JSON, test "x$CONFIG_BACKEND" = "xJSON")
if test "x$CONFIG_BACKEND" = "xBUNDY"; then
AC_DEFINE(CONFIG_BACKEND_BUNDY, 1, [Define to 1 if Kea config was set to BUNDY])
fi
if test "x$CONFIG_BACKEND" = "xJSON"; then
AC_DEFINE(CONFIG_BACKEND_JSON, 1, [Define to 1 if Kea config was set to JSON])
fi
# Let's sanity check if the specified backend value is allowed
if test "x$CONFIG_BACKEND" != "xBUNDY" && test "x$CONFIG_BACKEND" != "xJSON"; then
AC_MSG_ERROR("Invalid configuration backend specified: $CONFIG_BACKEND. The only supported are: BUNDY JSON")
fi
AC_ARG_ENABLE(generate_docs, [AC_HELP_STRING([--enable-generate-docs],
[regenerate documentation using Docbook [default=no]])],
enable_generate_docs=$enableval, enable_generate_docs=no)
...
...
@@ -1620,6 +1651,9 @@ SQLite:
SQLITE_VERSION: ${SQLITE_VERSION}
SQLITE_CFLAGS: ${SQLITE_CFLAGS}
SQLITE_LIBS: ${SQLITE_LIBS}
Kea config backend:
CONFIG_BACKEND: ${CONFIG_BACKEND}
END
# Avoid confusion on DNS/DHCP and only mention MySQL if it
...
...
doc/devel/mainpage.dox
View file @
7e9fdfa6
...
...
@@ -63,6 +63,7 @@
* - @subpage dhcpv6DDNSIntegration
* - @subpage dhcpv6OptionsParse
* - @subpage dhcpv6Classifier
* - @subpage dhcpv6ConfigBackend
* - @subpage dhcpv6Other
* - @subpage d2
* - @subpage d2CPL
...
...
doc/examples/kea6/several-subnets.json
0 → 100644
View file @
7e9fdfa6
#
This
is
an
example
configuration
file
for
DHCPv
6
server
in
Kea.
#
It's
a
basic
scenario
with
four
IPv
6
subnets
configured.
In
each
#
subnet,
there's
a
smaller
pool
of
dynamic
addresses.
{
"Dhcp6"
:
{
#
Kea
is
told
to
listen
on
eth
0
interface
only.
"interfaces"
:
[
"eth0"
],
#
Addresses
will
be
assigned
with
preferred
and
valid
lifetimes
#
being
3000
and
4000
,
respectively.
Client
is
told
to
start
#
renewing
after
1000
seconds.
If
the
server
does
not
repond
#
after
2000
seconds
since
the
lease
was
granted
,
client
is
supposed
#
to
start
REBIND
procedure
(emergency
renewal
that
allows
switching
#
to
a
different
server).
"preferred-lifetime"
:
3000
,
"valid-lifetime"
:
4000
,
"renew-timer"
:
1000
,
"rebind-timer"
:
2000
,
#
The
following
list
defines
subnets.
Each
subnet
consists
of
at
#
least
subnet
and
pool
entries.
"subnet6"
:
[
{
"pool"
:
[
"2001:db8:1::/80"
],
"subnet"
:
"2001:db8:1::/64"
},
{
"pool"
:
[
"2001:db8:2::/80"
],
"subnet"
:
"2001:db8:2::/64"
},
{
"pool"
:
[
"2001:db8:3::/80"
],
"subnet"
:
"2001:db8:3::/64"
},
{
"pool"
:
[
"2001:db8:4::/80"
],
"subnet"
:
"2001:db8:4::/64"
}
]
}
}
doc/guide/bind10-guide.xml
View file @
7e9fdfa6
...
...
@@ -710,7 +710,9 @@ as a dependency earlier -->
<note>
<para>
For additional instructions concerning the building and installation of
Kea, see
<xref
linkend=
"dhcp-install-configure"
/>
.
Kea for various databases, see
<xref
linkend=
"dhcp-install-configure"
/>
.
For additional instructions concerning configuration backends, see
<xref
linkend=
"dhcp-config-backend"
/>
.
</para>
</note>
</para>
...
...
@@ -1864,6 +1866,46 @@ address, but the usual ones don't." mean? -->
The DHCP-DDNS server details are covered in
<xref
linkend=
"dhcp-ddns-server"
/>
</para>
<section
id=
"dhcp-config-backend"
>
<title>
Selecting configuration backend
</title>
<para>
Kea 0.9 introduces configuration backends that are switchable during
compilation phase. There is a new parameter for configure script:
--with-kea-config. It currently supports two values: BIND10 and
JSON. This is currently only supported by DHCPv6 component.
</para>
<variablelist>
<varlistentry>
<term>
BIND10
</term>
<listitem>
<simpara>
BIND10 (which is the default value as of April 2014) means
that Kea6 is linked with the BIND10 configuration backend that
connects to the BIND10 framework and in general works exactly the
same as Kea 0.8 and earlier versions. The benefits of that backend
are uniform integration with BIND10 framework, easy on-line
reconfiguration using bindctl, available RESTful API. On the other
hand, it requires the whole heavy BIND10 framework that requires
Python3 to be present. That backend is likely to go away with the
release of Kea 0.9.
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>
JSON
</term>
<listitem>
<simpara>
JSON is a new configuration backend that causes Kea to read
JSON configuration file from disk. It does not require any framework
and thus is considered more lightweight. It will allow dynamic
on-line reconfiguration, but will lack remote capabilities (i.e. no
RESTful API). This configuration backend is expected to be the
default for upcoming Kea 0.9.
</simpara>
</listitem>
</varlistentry>
</variablelist>
</section>
<section
id=
"dhcp-install-configure"
>
<title>
DHCP Database Installation and Configuration
</title>
<para>
...
...
src/bin/dhcp6/Makefile.am
View file @
7e9fdfa6
...
...
@@ -52,10 +52,18 @@ BUILT_SOURCES = spec_config.h dhcp6_messages.h dhcp6_messages.cc
pkglibexec_PROGRAMS
=
b10-dhcp6
b10_dhcp6_SOURCES
=
main.cc
b10_dhcp6_SOURCES
+=
ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
b10_dhcp6_SOURCES
+=
config_parser.cc config_parser.h
b10_dhcp6_SOURCES
+=
dhcp6_log.cc dhcp6_log.h
b10_dhcp6_SOURCES
+=
dhcp6_srv.cc dhcp6_srv.h
b10_dhcp6_SOURCES
+=
ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
b10_dhcp6_SOURCES
+=
json_config_parser.cc json_config_parser.h
if
CONFIG_BACKEND_BUNDY
b10_dhcp6_SOURCES
+=
bundy_controller.cc
endif
if
CONFIG_BACKEND_JSON
b10_dhcp6_SOURCES
+=
kea_controller.cc
endif
nodist_b10_dhcp6_SOURCES
=
dhcp6_messages.h dhcp6_messages.cc
EXTRA_DIST
+=
dhcp6_messages.mes
...
...
src/bin/dhcp6/bundy_controller.cc
0 → 100644
View file @
7e9fdfa6
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <asiolink/asiolink.h>
#include <cc/data.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/dhcp_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/spec_config.h>
#include <exceptions/exceptions.h>
#include <hooks/hooks_manager.h>
#include <util/buffer.h>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
cc
;
using
namespace
isc
::
config
;
using
namespace
isc
::
data
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
hooks
;
using
namespace
isc
::
log
;
using
namespace
isc
::
util
;
using
namespace
std
;
namespace
isc
{
namespace
dhcp
{
/// @brief Helper session object that represents raw connection to msgq.
isc
::
cc
::
Session
*
cc_session_
=
NULL
;
/// @brief Session that receives configuration and commands
isc
::
config
::
ModuleCCSession
*
config_session_
=
NULL
;
/// @brief A dummy configuration handler that always returns success.
///
/// This configuration handler does not perform configuration
/// parsing and always returns success. A dummy handler should
/// be installed using \ref isc::config::ModuleCCSession ctor
/// to get the initial configuration. This initial configuration
/// comprises values for only those elements that were modified
/// the previous session. The \ref dhcp6ConfigHandler can't be
/// used to parse the initial configuration because it needs the
/// full configuration to satisfy dependencies between the
/// various configuration values. Installing the dummy handler
/// that guarantees to return success causes initial configuration
/// to be stored for the session being created and that it can
/// be later accessed with
/// \ref isc::config::ConfigData::getFullConfig().
///
/// @param new_config new configuration.
///
/// @return success configuration status.
ConstElementPtr
dhcp6StubConfigHandler
(
ConstElementPtr
)
{
// This configuration handler is intended to be used only
// when the initial configuration comes in. To receive this
// configuration a pointer to this handler must be passed
// using ModuleCCSession constructor. This constructor will
// invoke the handler and will store the configuration for
// the configuration session when the handler returns success.
// Since this configuration is partial we just pretend to
// parse it and always return success. The function that
// initiates the session must get the configuration on its
// own using getFullConfig.
return
(
isc
::
config
::
createAnswer
(
0
,
"Configuration accepted."
));
}
ConstElementPtr
bundyConfigHandler
(
ConstElementPtr
new_config
)
{
if
(
!
ControlledDhcpv6Srv
::
getInstance
()
||
!
config_session_
)
{
// That should never happen as we install config_handler
// after we instantiate the server.
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Configuration rejected,"
" server is during startup/shutdown phase."
);
return
(
answer
);
}
// The configuration passed to this handler function is partial.
// In other words, it just includes the values being modified.
// In the same time, there are dependencies between various
// DHCP configuration parsers. For example: the option value can
// be set if the definition of this option is set. If someone removes
// an existing option definition then the partial configuration that
// removes that definition is triggered while a relevant option value
// may remain configured. This eventually results in the DHCP server
// configuration being in the inconsistent state.
// In order to work around this problem we need to merge the new
// configuration with the existing (full) configuration.
// Let's create a new object that will hold the merged configuration.
boost
::
shared_ptr
<
MapElement
>
merged_config
(
new
MapElement
());
// Let's get the existing configuration.
ConstElementPtr
full_config
=
config_session_
->
getFullConfig
();
// The full_config and merged_config should be always non-NULL
// but to provide some level of exception safety we check that they
// really are (in case we go out of memory).
if
(
full_config
&&
merged_config
)
{
merged_config
->
setValue
(
full_config
->
mapValue
());
// Merge an existing and new configuration.
isc
::
data
::
merge
(
merged_config
,
new_config
);
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_COMMAND
,
DHCP6_CONFIG_UPDATE
)
.
arg
(
merged_config
->
str
());
}
// Configure the server.
return
(
ControlledDhcpv6Srv
::
processConfig
(
merged_config
));
}
void
ControlledDhcpv6Srv
::
init
(
const
std
::
string
&
/* config_file*/
)
{
// This is Bundy configuration backed. It established control session
// that is used to connect to Bundy framework.
//
// Creates session that will be used to receive commands and updated
// configuration from cfgmgr (or indirectly from user via bindctl).
string
specfile
;
if
(
getenv
(
"B10_FROM_BUILD"
))
{
specfile
=
string
(
getenv
(
"B10_FROM_BUILD"
))
+
"/src/bin/dhcp6/dhcp6.spec"
;
}
else
{
specfile
=
string
(
DHCP6_SPECFILE_LOCATION
);
}
/// @todo: Check if session is not established already. Throw, if it is.
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_START
,
DHCP6_CCSESSION_STARTING
)
.
arg
(
specfile
);
cc_session_
=
new
Session
(
io_service_
.
get_io_service
());
// Create a session with the dummy configuration handler.
// Dumy configuration handler is internally invoked by the
// constructor and on success the constructor updates
// the current session with the configuration that had been
// committed in the previous session. If we did not install
// the dummy handler, the previous configuration would have
// been lost.
config_session_
=
new
ModuleCCSession
(
specfile
,
*
cc_session_
,
dhcp6StubConfigHandler
,
processCommand
,
false
);
config_session_
->
start
();
// The constructor already pulled the configuration that had
// been created in the previous session thanks to the dummy
// handler. We can switch to the handler that will be
// parsing future changes to the configuration.
config_session_
->
setConfigHandler
(
bundyConfigHandler
);
try
{
// Pull the full configuration out from the session.
processConfig
(
config_session_
->
getFullConfig
());
// Server will start DDNS communications if its enabled.
server_
->
startD2
();
// Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration.
openActiveSockets
(
getPort
());
}
catch
(
const
std
::
exception
&
ex
)
{
LOG_ERROR
(
dhcp6_logger
,
DHCP6_CONFIG_LOAD_FAIL
).
arg
(
ex
.
what
());
}
/// Integrate the asynchronous I/O model of Bundy configuration
/// control with the "select" model of the DHCP server. This is
/// fully explained in \ref dhcpv6Session.
int
ctrl_socket
=
cc_session_
->
getSocketDesc
();
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_START
,
DHCP6_CCSESSION_STARTED
)
.
arg
(
ctrl_socket
);
IfaceMgr
::
instance
().
addExternalSocket
(
ctrl_socket
,
sessionReader
);
return
;
}
void
ControlledDhcpv6Srv
::
cleanup
()
{
if
(
config_session_
)
{
delete
config_session_
;
config_session_
=
NULL
;
}
if
(
cc_session_
)
{
int
ctrl_socket
=
cc_session_
->
getSocketDesc
();
cc_session_
->
disconnect
();
// deregister session socket
IfaceMgr
::
instance
().
deleteExternalSocket
(
ctrl_socket
);
delete
cc_session_
;
cc_session_
=
NULL
;
}
}
void
Daemon
::
loggerInit
(
const
char
*
log_name
,
bool
verbose
,
bool
stand_alone
)
{
isc
::
log
::
initLogger
(
log_name
,
(
verbose
?
isc
::
log
::
DEBUG
:
isc
::
log
::
INFO
),
isc
::
log
::
MAX_DEBUG_LEVEL
,
NULL
,
!
stand_alone
);
}
};
// end of isc::dhcp namespace
};
// end of isc namespace
src/bin/dhcp6/ctrl_dhcp6_srv.cc
View file @
7e9fdfa6
// Copyright (C) 201
2-2013
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 201
4
Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -13,35 +13,14 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <asiolink/asiolink.h>
#include <cc/data.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/dhcp_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/spec_config.h>
#include <exceptions/exceptions.h>
#include <hooks/hooks_manager.h>
#include <util/buffer.h>
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include <dhcp6/json_config_parser.h>
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
cc
;
using
namespace
isc
::
config
;
using
namespace
isc
::
data
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
hooks
;
using
namespace
isc
::
log
;
using
namespace
isc
::
util
;
using
namespace
std
;
namespace
isc
{
...
...
@@ -50,113 +29,20 @@ namespace dhcp {
ControlledDhcpv6Srv
*
ControlledDhcpv6Srv
::
server_
=
NULL
;
ConstElementPtr
ControlledDhcpv6Srv
::
dhcp6StubConfigHandler
(
ConstElementPtr
)
{
// This configuration handler is intended to be used only
// when the initial configuration comes in. To receive this
// configuration a pointer to this handler must be passed
// using ModuleCCSession constructor. This constructor will
// invoke the handler and will store the configuration for
// the configuration session when the handler returns success.
// Since this configuration is partial we just pretend to
// parse it and always return success. The function that
// initiates the session must get the configuration on its
// own using getFullConfig.
return
(
isc
::
config
::
createAnswer
(
0
,
"Configuration accepted."
));
}
ConstElementPtr
ControlledDhcpv6Srv
::
dhcp6ConfigHandler
(
ConstElementPtr
new_config
)
{
if
(
!
server_
||
!
server_
->
config_session_
)
{
// That should never happen as we install config_handler
// after we instantiate the server.
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Configuration rejected,"
" server is during startup/shutdown phase."
);
return
(
answer
);
}
// The configuration passed to this handler function is partial.
// In other words, it just includes the values being modified.
// In the same time, there are dependencies between various
// DHCP configuration parsers. For example: the option value can
// be set if the definition of this option is set. If someone removes
// an existing option definition then the partial configuration that
// removes that definition is triggered while a relevant option value
// may remain configured. This eventually results in the DHCP server
// configuration being in the inconsistent state.
// In order to work around this problem we need to merge the new
// configuration with the existing (full) configuration.
// Let's create a new object that will hold the merged configuration.
boost
::
shared_ptr
<
MapElement
>
merged_config
(
new
MapElement
());
// Let's get the existing configuration.
ConstElementPtr
full_config
=
server_
->
config_session_
->
getFullConfig
();
// The full_config and merged_config should be always non-NULL
// but to provide some level of exception safety we check that they
// really are (in case we go out of memory).
if
(
full_config
&&
merged_config
)
{
merged_config
->
setValue
(
full_config
->
mapValue
());
// Merge an existing and new configuration.
isc
::
data
::
merge
(
merged_config
,
new_config
);
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_COMMAND
,
DHCP6_CONFIG_UPDATE
)
.
arg
(
merged_config
->
str
());
}
// Configure the server.
ConstElementPtr
answer
=
configureDhcp6Server
(
*
server_
,
merged_config
);
// Check that configuration was successful. If not, do not reopen sockets.
int
rcode
=
0
;
parseAnswer
(
rcode
,
answer
);
if
(
rcode
!=
0
)
{
return
(
answer
);
}
// Server will start DDNS communications if its enabled.
try
{
server_
->
startD2
();
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
ostringstream
err
;
err
<<
"error starting DHCP_DDNS client "
" after server reconfiguration: "
<<
ex
.
what
();
return
(
isc
::
config
::
createAnswer
(
1
,
err
.
str
()));
}
// Configuration may change active interfaces. Therefore, we have to reopen
// sockets according to new configuration. This operation is not exception
// safe and we really don't want to emit exceptions to the callback caller.
// Instead, catch an exception and create appropriate answer.
try
{
server_
->
openActiveSockets
(
server_
->
getPort
());
}
catch
(
const
std
::
exception
&
ex
)
{
std
::
ostringstream
err
;
err
<<
"failed to open sockets after server reconfiguration: "
<<
ex
.
what
();
answer
=
isc
::
config
::
createAnswer
(
1
,
err
.
str
());
}
return
(
answer
);
}
ConstElementPtr
ControlledDhcpv6Srv
::
dhcp6CommandHandler
(
const
string
&
command
,
ConstElementPtr
args
)
{
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_COMMAND
,
DHCP6_COMMAND_RECEIVED
)
.
arg
(
command
).
arg
(
args
->
str
());
if
(
command
==
"shutdown"
)
{
ControlledDhcpv6Srv
::
commandShutdownHandler
(
const
string
&
,
ConstElementPtr
)
{
if
(
ControlledDhcpv6Srv
::
server_
)
{
ControlledDhcpv6Srv
::
server_
->
shutdown
();
}
else
{
LOG_WARN
(
dhcp6_logger
,
DHCP6_NOT_RUNNING
);
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Shutdown failure."
);
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Shutdown failure."
);
return
(
answer
);
}
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
0
,
"Shutting down."
);
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
0
,
"Shutting down."
);
return
(
answer
);
}
}
else
if
(
command
==
"libreload"
)
{
ConstElementPtr
ControlledDhcpv6Srv
::
commandLibReloadHandler
(
const
string
&
,
ConstElementPtr
)
{
// TODO delete any stored CalloutHandles referring to the old libraries
// Get list of currently loaded libraries and reload them.
vector
<
string
>
loaded
=
HooksManager
::
getLibraryNames
();
...
...
@@ -170,100 +56,106 @@ ControlledDhcpv6Srv::dhcp6CommandHandler(const string& command, ConstElementPtr
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
0
,
"Hooks libraries successfully reloaded."
);
return
(
answer
);
}
}
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Unrecognized command."
);
ConstElementPtr
ControlledDhcpv6Srv
::
commandConfigReloadHandler
(
const
string
&
,
ConstElementPtr
args
)
{
return
(
answer
);
return
(
processConfig
(
args
)
);
}
void
ControlledDhcpv6Srv
::
sessionReader
(
void
)
{
// Process one asio event. If there are more events, iface_mgr will call
// this callback more than once.
if
(
server_
)
{
server_
->
io_service_
.
run_one
();
}
}
isc
::
data
::
ConstElementPtr
ControlledDhcpv6Srv
::
processCommand
(
const
std
::
string
&
command
,
isc
::
data
::
ConstElementPtr
args
)
{
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_COMMAND
,
DHCP6_COMMAND_RECEIVED
)
.
arg
(
command
).
arg
(
args
->
str
());
void
ControlledDhcpv6Srv
::
establishSession
()
{
ControlledDhcpv6Srv
*
srv
=
ControlledDhcpv6Srv
::
getInstance
();