Commit f4566355 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[1708] msgq support in DHCPv6 added.

parent 713e3482
......@@ -72,11 +72,13 @@
* DHCPv6 server component does not support relayed traffic yet, as
* support for relay decapsulation is not implemented yet.
*
* DHCPv6 server component does not listen to BIND10 message queue.
*
* DHCPv6 server component does not use BIND10 logging yet.
*
* DHCPv6 server component is not integrated with boss yet.
* @section dhcpv6Session BIND10 message queue integration
*
* DHCPv4 server component is now integrated with BIND10 message queue.
* It follows the same principle as DHCPv4. See \ref dhcpv4Session for
* details.
*
* @page libdhcp libdhcp++
*
......
This diff is collapsed.
This diff is collapsed.
......@@ -2455,7 +2455,7 @@ then change those defaults with config set Resolver/forward_addresses[0]/address
&gt; <userinput>config commit</userinput></screen></para>
<para>
At start, the server will detect available network interfaces
During start-up the server will detect available network interfaces
and will attempt to open UDP sockets on all interfaces that
are up, running, are not loopback, and have IPv4 address
assigned.
......@@ -2465,17 +2465,8 @@ then change those defaults with config set Resolver/forward_addresses[0]/address
will respond to them with OFFER and ACK, respectively.
Since the DHCPv4 server opens privileged ports, it requires root
access. Make sure you run this daemon as root.</para>
<note>
<para>
Integration with <command>bind10</command> is
planned. Ultimately, <command>b10-dhcp4</command> will not
be started directly, but rather via
<command>bind10</command>. Please be aware of this planned
change.
</para>
</note>
access. Make sure you run this daemon as root.
</para>
</section>
......@@ -2640,22 +2631,25 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
</para>
<para>
The DHCPv6 server is implemented as <command>b10-dhcp6</command>
daemon. As it is not configurable yet, it is fully autonomous,
that is it does not interact with <command>b10-cfgmgr</command>.
To start DHCPv6 server, simply input:
<screen>
#<userinput>cd src/bin/dhcp6</userinput>
#<userinput>./b10-dhcp6</userinput>
</screen>
<command>b10-dhcp6</command> is a BIND10 component and is being
run under BIND10 framework. To add a DHCPv6 process to the set of running
BIND10 services, you can use following commands in <command>bindctl</command>:
<screen>&gt; <userinput>config add Boss/components b10-dhcp6</userinput>
&gt; <userinput>config set Boss/components/b10-dhcp6/kind dispensable</userinput>
&gt; <userinput>config commit</userinput></screen>
</para>
Depending on your installation, <command>b10-dhcp6</command>
binary may reside in src/bin/dhcp6 in your source code
directory, in /usr/local/bin/b10-dhcp6 or other directory
you specified during compilation.
<para>
To shutdown running <command>b10-dhcp6</command>, please use the
following command:
<screen>&gt; <userinput>Dhcp6 shutdown</userinput></screen>
or
<screen>&gt; <userinput>config remove Boss/components b10-dhcp6</userinput>
&gt; <userinput>config commit</userinput></screen>
</para>
At start, server will detect available network interfaces
<para>
During start-up the server will detect available network interfaces
and will attempt to open UDP sockets on all interfaces that
are up, running, are not loopback, are multicast-capable, and
have IPv6 address assigned.
......@@ -2668,16 +2662,6 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
access. Make sure you run this daemon as root.
</para>
<note>
<para>
Integration with <command>bind10</command> is
planned. Ultimately, <command>b10-dhcp6</command> will not
be started directly, but rather via
<command>bind10</command>. Please be aware of this planned
change.
</para>
</note>
</section>
<section id="dhcp6-config">
......@@ -2691,7 +2675,7 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";</screen>
<para>
At this stage of development, the only way to alter server
configuration is to tweak its source code. To do so, please
edit src/bin/dhcp6/dhcp6_srv.cc file and modify following
edit src/bin/dhcp6/dhcp6_srv.cc file, modify the following
parameters and recompile:
<screen>
const std::string HARDCODED_LEASE = "2001:db8:1::1234:abcd";
......
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Messages Manual</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the messages manual for BIND 10 version 20120405. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Messages Manual"><div class="titlepage"><div><div><h1 class="title"><a name="id1168229451102"></a>BIND 10 Messages Manual</h1></div><div><p class="releaseinfo">This is the messages manual for BIND 10 version
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Messages Manual</title><link rel="stylesheet" type="text/css" href="./bind10-guide.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the messages manual for BIND 10 version 20120405. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Messages Manual"><div class="titlepage"><div><div><h1 class="title"><a name="idm25567040"></a>BIND 10 Messages Manual</h1></div><div><p class="releaseinfo">This is the messages manual for BIND 10 version
20120405.</p></div><div><p class="copyright">Copyright © 2011-2012 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
Internet Systems Consortium (ISC). It includes DNS libraries
and modular components for controlling authoritative and
......
......@@ -33,6 +33,7 @@ BUILT_SOURCES = spec_config.h
pkglibexec_PROGRAMS = b10-dhcp6
b10_dhcp6_SOURCES = main.cc dhcp6_srv.cc dhcp6_srv.h
b10_dhcp6_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
......@@ -44,6 +45,8 @@ b10_dhcp6_LDADD = $(top_builddir)/src/lib/exceptions/libexceptions.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/liblog.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp/libdhcp++.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/cc/libcc.la
b10_dhcp6dir = $(pkgdatadir)
b10_dhcp6_DATA = dhcp6.spec
// Copyright (C) 2012 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 <cassert>
#include <iostream>
#include <cc/session.h>
#include <cc/data.h>
#include <exceptions/exceptions.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <util/buffer.h>
#include <dhcp6/spec_config.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp/iface_mgr.h>
#include <asiolink/asiolink.h>
using namespace std;
using namespace isc::util;
using namespace isc::dhcp;
using namespace isc::util;
using namespace isc::data;
using namespace isc::cc;
using namespace isc::config;
using namespace isc::asiolink;
namespace isc {
namespace dhcp {
ControlledDhcpv6Srv* ControlledDhcpv6Srv::server_ = NULL;
ConstElementPtr
ControlledDhcpv6Srv::dhcp6ConfigHandler(ConstElementPtr new_config) {
cout << "b10-dhcp6: Received new config:" << new_config->str() << endl;
ConstElementPtr answer = isc::config::createAnswer(0,
"Thank you for sending config.");
return (answer);
}
ConstElementPtr
ControlledDhcpv6Srv::dhcp6CommandHandler(const string& command, ConstElementPtr args) {
cout << "b10-dhcp6: Received new command: [" << command << "], args="
<< args->str() << endl;
if (command == "shutdown") {
if (ControlledDhcpv6Srv::server_) {
ControlledDhcpv6Srv::server_->shutdown();
} else {
cout << "Server not initialized yet or already shut down." << endl;
ConstElementPtr answer = isc::config::createAnswer(1,
"Shutdown failure.");
return (answer);
}
ConstElementPtr answer = isc::config::createAnswer(0,
"Shutting down.");
return (answer);
}
ConstElementPtr answer = isc::config::createAnswer(1,
"Unrecognized command.");
return (answer);
}
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();
}
}
void ControlledDhcpv6Srv::establishSession() {
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.
cout << "b10-dhcp6: my specfile is " << specfile << endl;
cc_session_ = new Session(io_service_.get_io_service());
config_session_ = new ModuleCCSession(specfile, *cc_session_,
dhcp6ConfigHandler,
dhcp6CommandHandler, false);
config_session_->start();
/// Integrate the asynchronous I/O model of BIND 10 configuration
/// control with the "select" model of the DHCP server. This is
/// fully explained in \ref dhcpv6Session.
int ctrl_socket = cc_session_->getSocketDesc();
cout << "b10-dhcp6: Control session started, socket="
<< ctrl_socket << endl;
IfaceMgr::instance().set_session_socket(ctrl_socket, sessionReader);
}
void ControlledDhcpv6Srv::disconnectSession() {
if (config_session_) {
delete config_session_;
config_session_ = NULL;
}
if (cc_session_) {
cc_session_->disconnect();
delete cc_session_;
cc_session_ = NULL;
}
// deregister session socket
IfaceMgr::instance().set_session_socket(IfaceMgr::INVALID_SOCKET, NULL);
}
ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port /*= DHCP6_SERVER_PORT*/)
:Dhcpv6Srv(port), cc_session_(NULL), config_session_(NULL) {
server_ = this; // remember this instance for use in callback
}
void ControlledDhcpv6Srv::shutdown() {
io_service_.stop(); // Stop ASIO transmissions
Dhcpv6Srv::shutdown(); // Initiate DHCPv6 shutdown procedure.
}
ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
disconnectSession();
server_ = NULL; // forget this instance. There should be no callback anymore
// at this stage anyway.
}
isc::data::ConstElementPtr
ControlledDhcpv6Srv::execDhcpv6ServerCommand(const std::string& command_id,
isc::data::ConstElementPtr args) {
try {
return (dhcp6CommandHandler(command_id, args));
} catch (const Exception& ex) {
ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
return (answer);
}
}
};
};
// Copyright (C) 2012 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.
#ifndef CTRL_DHCPV6_SRV_H
#define CTRL_DHCPV6_SRV_H
#include <dhcp6/dhcp6_srv.h>
#include <asiolink/asiolink.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <cc/data.h>
namespace isc {
namespace dhcp {
/// @brief Controlled version of the DHCPv6 server
///
/// This is a class that is responsible for establishing connection
/// with msqg (receving commands and configuration). This is an extended
/// version of Dhcpv6Srv class that is purely a DHCPv6 server, without
/// external control. ControlledDhcpv6Srv should be used in typical BIND10
/// (i.e. featuring msgq) environment, while Dhcpv6Srv should be used in
/// embedded environments.
///
/// For detailed explanation or relations between main(), ControlledDhcpv6Srv,
/// Dhcpv6Srv and other classes, see \ref dhcpv6Session.
class ControlledDhcpv6Srv : public isc::dhcp::Dhcpv6Srv {
public:
/// @brief Constructor
///
/// @param port UDP port to be opened for DHCP traffic
ControlledDhcpv6Srv(uint16_t port = DHCP6_SERVER_PORT);
/// @brief Destructor.
~ControlledDhcpv6Srv();
/// @brief Establishes msgq session.
///
/// Creates session that will be used to receive commands and updated
/// configuration from boss (or indirectly from user via bindctl).
void establishSession();
/// @brief Terminates existing msgq session.
///
/// This method terminates existing session with msgq. After calling
/// it, no further messages over msgq (commands or configuration updates)
/// may be received.
///
/// It is ok to call this method when session is disconnected already.
void disconnectSession();
/// @brief Initiates shutdown procedure for the whole DHCPv6 server.
void shutdown();
/// @brief Session callback, processes received commands.
///
/// @param command_id text represenation of the command (e.g. "shutdown")
/// @param args optional parameters
///
/// @return status of the command
static isc::data::ConstElementPtr
execDhcpv6ServerCommand(const std::string& command,
isc::data::ConstElementPtr args);
protected:
/// @brief Static pointer to the sole instance of the DHCP server.
///
/// This is required for config and command handlers to gain access to
/// the server
static ControlledDhcpv6Srv* server_;
/// @brief A callback for handling incoming configuration updates.
///
/// As pointer to this method is used a callback in ASIO used in
/// ModuleCCSession, it has to be static.
///
/// @param new_config textual representation of the new configuration
///
/// @return status of the config update
static isc::data::ConstElementPtr
dhcp6ConfigHandler(isc::data::ConstElementPtr new_config);
/// @brief A callback for handling incoming commands.
///
/// @param command textual representation of the command
/// @param args parameters of the command
///
/// @return status of the processed command
static isc::data::ConstElementPtr
dhcp6CommandHandler(const std::string& command, isc::data::ConstElementPtr args);
/// @brief Callback that will be called from iface_mgr when command/config arrives.
///
/// This static callback method is called from IfaceMgr::receive6() method,
/// when there is a new command or configuration sent over msgq.
static void sessionReader(void);
/// @brief IOService object, used for all ASIO operations.
isc::asiolink::IOService io_service_;
/// @brief Helper session object that represents raw connection to msgq.
isc::cc::Session* cc_session_;
/// @brief Session that receives configuation and commands
isc::config::ModuleCCSession* config_session_;
};
}; // namespace isc::dhcp
}; // namespace isc
#endif
......@@ -48,12 +48,12 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
IfaceMgr::instance();
} catch (const std::exception &e) {
cout << "Failed to instantiate InterfaceManager:" << e.what() << ". Aborting." << endl;
shutdown = true;
shutdown_ = true;
}
if (IfaceMgr::instance().countIfaces() == 0) {
cout << "Failed to detect any network interfaces. Aborting." << endl;
shutdown = true;
shutdown_ = true;
}
// Now try to open IPv6 sockets on detected interfaces.
......@@ -63,7 +63,7 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
setServerID();
shutdown = false;
shutdown_ = false;
}
Dhcpv6Srv::~Dhcpv6Srv() {
......@@ -72,8 +72,13 @@ Dhcpv6Srv::~Dhcpv6Srv() {
IfaceMgr::instance().closeSockets();
}
void Dhcpv6Srv::shutdown() {
cout << "b10-dhcp6: DHCPv6 server shutdown." << endl;
shutdown_ = true;
}
bool Dhcpv6Srv::run() {
while (!shutdown) {
while (!shutdown_) {
// client's message and server's response
Pkt6Ptr query = IfaceMgr::instance().receive6();
......
......@@ -67,6 +67,8 @@ public:
/// critical error.
bool run();
/// @brief Instructs the server to shut down.
void shutdown();
protected:
/// @brief Processes incoming SOLICIT and returns response.
///
......@@ -184,7 +186,7 @@ protected:
/// indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
volatile bool shutdown;
volatile bool shutdown_;
};
}; // namespace isc::dhcp
......
......@@ -13,47 +13,34 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <cassert>
#include <iostream>
#include <exceptions/exceptions.h>
#if 0
// TODO cc is not used yet. It should be eventually
#include <cc/session.h>
#include <config/ccsession.h>
#endif
#include <util/buffer.h>
#include <log/dummylog.h>
#include <dhcp6/spec_config.h>
#include "dhcp6/dhcp6_srv.h"
#include <log/logger_support.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
using namespace std;
using namespace isc::util;
using namespace isc;
using namespace isc::dhcp;
/// This file contains entry point (main() function) for standard DHCPv6 server
/// component for BIND10 framework. It parses command-line arguments and
/// instantiates ControlledDhcpv6Srv class that is responsible for establishing
/// connection with msgq (receiving commands and configuration) and also
/// creating Dhcpv6 server object as well.
///
/// For detailed explanation or relations between main(), ControlledDhcpv6Srv,
/// Dhcpv6Srv and other classes, see \ref dhcpv6Session.
namespace {
bool verbose_mode = false;
const char* const DHCP6_NAME = "b10-dhcp6";
void
usage() {
cerr << "Usage: b10-dhcp6 [-v]"
cerr << "Usage: b10-dhcp6 [-v]"
<< endl;
cerr << "\t-v: verbose output" << endl;
cerr << "\t-p number: specify non-standard port number 1-65535 (useful for testing only)" << endl;
cerr << "\t-p number: specify non-standard port number 1-65535 "
<< "(useful for testing only)" << endl;
exit(EXIT_FAILURE);
}
} // end of anonymous namespace
......@@ -63,6 +50,7 @@ main(int argc, char* argv[]) {
int ch;
int port_number = DHCP6_SERVER_PORT; // The default. Any other values are
// useful for testing only.
bool verbose_mode = false; // Should server be verbose?
while ((ch = getopt(argc, argv, "vp:")) != -1) {
switch (ch) {
......@@ -84,7 +72,13 @@ main(int argc, char* argv[]) {
}
}
cout << "My pid=" << getpid() << endl;
// Initialize logging. If verbose, we'll use maximum verbosity.
isc::log::initLogger(DHCP6_NAME,
(verbose_mode ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL);
cout << "b10-dhcp6: My pid=" << getpid() << ", binding to port "
<< port_number << ", verbose " << (verbose_mode?"yes":"no") << endl;
if (argc - optind > 0) {
usage();
......@@ -92,24 +86,18 @@ main(int argc, char* argv[]) {
int ret = EXIT_SUCCESS;
// TODO remainder of auth to dhcp6 code copy. We need to enable this in
// dhcp6 eventually
#if 0
Session* cc_session = NULL;
Session* statistics_session = NULL;
ModuleCCSession* config_session = NULL;
#endif
try {
string specfile;
if (getenv("B10_FROM_BUILD")) {
specfile = string(getenv("B10_FROM_BUILD")) +
"/src/bin/auth/dhcp6.spec";
} else {
specfile = string(DHCP6_SPECFILE_LOCATION);
}
cout << "b10-dhcp6: Initiating DHCPv6 server operation." << endl;
ControlledDhcpv6Srv* server = new ControlledDhcpv6Srv(port_number);
server->run();
delete server;
server = NULL;
cout << "[b10-dhcp6] Initiating DHCPv6 operation." << endl;
/// @todo: pass verbose to the actual server once logging is implemented
Dhcpv6Srv* srv = new Dhcpv6Srv(port_number);
srv->run();
......
......@@ -42,9 +42,10 @@ if HAVE_GTEST
TESTS += dhcp6_unittests
dhcp6_unittests_SOURCES = ../dhcp6_srv.h ../dhcp6_srv.cc
dhcp6_unittests_SOURCES = ../dhcp6_srv.h ../dhcp6_srv.cc ../ctrl_dhcp6_srv.cc
dhcp6_unittests_SOURCES += dhcp6_unittests.cc
dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES += ctrl_dhcp6_srv_unittest.cc
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
......@@ -59,6 +60,8 @@ dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libdhcp++.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
endif
......
// Copyright (C) 2012 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.
//