BIND 10 master, updated. 68ebb92883a7cd9bb84b3b39cab2049b59119e36 [master] ChangeLog entry for ticket 1545.
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Sep 17 11:01:36 UTC 2012
The branch, master has been updated
via 68ebb92883a7cd9bb84b3b39cab2049b59119e36 (commit)
via de69a92613b36bd3944cb061e1b7c611c3c85506 (commit)
via 38c6a4866e5be6f6a7ed3497f0fef252583b5be4 (commit)
via d6f3e1aa02ffc1de9d55a586174022eb60f43887 (commit)
via 23ba7abb4e2fe826bf536c822fb7eef20ebcd689 (commit)
via c7a025395cf01c95cee3430fdd94256ab3350244 (commit)
via 9c0444c02ef367b397f6c189fdba6bab717c7ec3 (commit)
via 6f7afc7ded635b4f40704b334d9d3cefbd46ab55 (commit)
via 71555cfc1c317e6ed98f9fd231f5c62c1df10910 (commit)
via d06ad334dd0e8005172025cfb85409d4d1ccc996 (commit)
via 5b16ceda16bffe94ea993e3d3011dd4e1a701eb9 (commit)
from 15560cac16e4c52129322e3cb1787e0f47cf7850 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 68ebb92883a7cd9bb84b3b39cab2049b59119e36
Author: Stephen Morris <stephen at isc.org>
Date: Mon Sep 17 11:54:07 2012 +0100
[master] ChangeLog entry for ticket 1545.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 4 +
src/bin/dhcp4/Makefile.am | 17 ++-
src/bin/dhcp4/ctrl_dhcp4_srv.cc | 43 ++++----
.../asiodns/logger.cc => bin/dhcp4/dhcp4_log.cc} | 13 ++-
src/bin/{auth/auth_log.h => dhcp4/dhcp4_log.h} | 45 ++++----
src/bin/dhcp4/dhcp4_messages.mes | 98 +++++++++++++++++
src/bin/dhcp4/dhcp4_srv.cc | 93 +++++++++++-----
src/bin/dhcp4/dhcp4_srv.h | 25 ++++-
src/bin/dhcp4/main.cc | 60 +++++-----
src/bin/dhcp4/tests/Makefile.am | 2 +
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc | 34 +++++-
src/bin/dhcp4/tests/dhcp4_test.py | 56 +++++-----
src/bin/dhcp6/Makefile.am | 17 ++-
src/bin/dhcp6/ctrl_dhcp6_srv.cc | 43 ++++----
.../asiodns/logger.cc => bin/dhcp6/dhcp6_log.cc} | 13 ++-
src/bin/{auth/auth_log.h => dhcp6/dhcp6_log.h} | 45 ++++----
src/bin/dhcp6/dhcp6_messages.mes | 101 +++++++++++++++++
src/bin/dhcp6/dhcp6_srv.cc | 115 +++++++++++++++-----
src/bin/dhcp6/dhcp6_srv.h | 18 +++
src/bin/dhcp6/main.cc | 58 +++++-----
src/bin/dhcp6/tests/Makefile.am | 7 +-
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 47 +++++++-
src/bin/dhcp6/tests/dhcp6_test.py | 53 ++++-----
23 files changed, 729 insertions(+), 278 deletions(-)
copy src/{lib/asiodns/logger.cc => bin/dhcp4/dhcp4_log.cc} (80%)
copy src/bin/{auth/auth_log.h => dhcp4/dhcp4_log.h} (55%)
create mode 100644 src/bin/dhcp4/dhcp4_messages.mes
copy src/{lib/asiodns/logger.cc => bin/dhcp6/dhcp6_log.cc} (80%)
copy src/bin/{auth/auth_log.h => dhcp6/dhcp6_log.h} (55%)
create mode 100644 src/bin/dhcp6/dhcp6_messages.mes
-----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index da4a826..dfcfa60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+474. [func] stephen
+ DHCP servers now use the BIND 10 logging system for messages.
+ (Trac #1545, git de69a92613b36bd3944cb061e1b7c611c3c85506)
+
473. [bug] jelte
TCP connections now time out in b10-auth if no (or not all) query
data is sent by the client. The timeout value defaults to 5000
diff --git a/src/bin/dhcp4/Makefile.am b/src/bin/dhcp4/Makefile.am
index 295ab41..e0c97d1 100644
--- a/src/bin/dhcp4/Makefile.am
+++ b/src/bin/dhcp4/Makefile.am
@@ -12,7 +12,7 @@ endif
pkglibexecdir = $(libexecdir)/@PACKAGE@
-CLEANFILES = spec_config.h
+CLEANFILES = *.gcno *.gcda spec_config.h dhcp4_messages.h dhcp4_messages.cc
man_MANS = b10-dhcp4.8
DISTCLEANFILES = $(man_MANS)
@@ -35,11 +35,20 @@ endif
spec_config.h: spec_config.h.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
-BUILT_SOURCES = spec_config.h
+dhcp4_messages.h dhcp4_messages.cc: dhcp4_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/bin/dhcp4/dhcp4_messages.mes
+
+BUILT_SOURCES = spec_config.h dhcp4_messages.h dhcp4_messages.cc
+
pkglibexec_PROGRAMS = b10-dhcp4
-b10_dhcp4_SOURCES = main.cc dhcp4_srv.cc dhcp4_srv.h
+b10_dhcp4_SOURCES = main.cc
b10_dhcp4_SOURCES += ctrl_dhcp4_srv.cc ctrl_dhcp4_srv.h
+b10_dhcp4_SOURCES += dhcp4_log.cc dhcp4_log.h
+b10_dhcp4_SOURCES += dhcp4_srv.cc dhcp4_srv.h
+
+nodist_b10_dhcp4_SOURCES = dhcp4_messages.h dhcp4_messages.cc
+EXTRA_DIST += dhcp4_messages.mes
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
@@ -47,7 +56,7 @@ if USE_CLANGPP
b10_dhcp4_CXXFLAGS = -Wno-unused-parameter
endif
-b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
+b10_dhcp4_LDADD = $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc
index 724ddf2..4bd3103 100644
--- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc
+++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc
@@ -13,28 +13,30 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
+
#include <cassert>
#include <iostream>
-#include <cc/session.h>
+#include <asiolink/asiolink.h>
#include <cc/data.h>
-#include <exceptions/exceptions.h>
+#include <cc/session.h>
#include <cc/session.h>
#include <config/ccsession.h>
-#include <util/buffer.h>
-#include <dhcp4/spec_config.h>
#include <dhcp4/ctrl_dhcp4_srv.h>
+#include <dhcp4/dhcp4_log.h>
+#include <dhcp4/spec_config.h>
#include <dhcp/iface_mgr.h>
-#include <asiolink/asiolink.h>
+#include <exceptions/exceptions.h>
+#include <util/buffer.h>
-using namespace std;
-using namespace isc::util;
-using namespace isc::dhcp;
-using namespace isc::util;
-using namespace isc::data;
+using namespace isc::asiolink;
using namespace isc::cc;
using namespace isc::config;
-using namespace isc::asiolink;
+using namespace isc::data;
+using namespace isc::dhcp;
+using namespace isc::log;
+using namespace isc::util;
+using namespace std;
namespace isc {
namespace dhcp {
@@ -43,7 +45,8 @@ ControlledDhcpv4Srv* ControlledDhcpv4Srv::server_ = NULL;
ConstElementPtr
ControlledDhcpv4Srv::dhcp4ConfigHandler(ConstElementPtr new_config) {
- cout << "b10-dhcp4: Received new config:" << new_config->str() << endl;
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_CONFIG_UPDATE)
+ .arg(new_config->str());
ConstElementPtr answer = isc::config::createAnswer(0,
"Thank you for sending config.");
return (answer);
@@ -51,13 +54,14 @@ ControlledDhcpv4Srv::dhcp4ConfigHandler(ConstElementPtr new_config) {
ConstElementPtr
ControlledDhcpv4Srv::dhcp4CommandHandler(const string& command, ConstElementPtr args) {
- cout << "b10-dhcp4: Received new command: [" << command << "], args="
- << args->str() << endl;
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_COMMAND_RECEIVED)
+ .arg(command).arg(args->str());
+
if (command == "shutdown") {
if (ControlledDhcpv4Srv::server_) {
ControlledDhcpv4Srv::server_->shutdown();
} else {
- cout << "Server not initialized yet or already shut down." << endl;
+ LOG_WARN(dhcp4_logger, DHCP4_NOT_RUNNING);
ConstElementPtr answer = isc::config::createAnswer(1,
"Shutdown failure.");
return (answer);
@@ -93,10 +97,9 @@ void ControlledDhcpv4Srv::establishSession() {
/// @todo: Check if session is not established already. Throw, if it is.
- cout << "b10-dhcp4: my specfile is " << specfile << endl;
-
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_CCSESSION_STARTING)
+ .arg(specfile);
cc_session_ = new Session(io_service_.get_io_service());
-
config_session_ = new ModuleCCSession(specfile, *cc_session_,
dhcp4ConfigHandler,
dhcp4CommandHandler, false);
@@ -106,8 +109,8 @@ void ControlledDhcpv4Srv::establishSession() {
/// control with the "select" model of the DHCP server. This is
/// fully explained in \ref dhcpv4Session.
int ctrl_socket = cc_session_->getSocketDesc();
- cout << "b10-dhcp4: Control session started, socket="
- << ctrl_socket << endl;
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_CCSESSION_STARTED)
+ .arg(ctrl_socket);
IfaceMgr::instance().set_session_socket(ctrl_socket, sessionReader);
}
diff --git a/src/bin/dhcp4/dhcp4_log.cc b/src/bin/dhcp4/dhcp4_log.cc
new file mode 100644
index 0000000..678223b
--- /dev/null
+++ b/src/bin/dhcp4/dhcp4_log.cc
@@ -0,0 +1,26 @@
+// 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.
+
+/// Defines the logger used by the top-level component of b10-dhcp4.
+
+#include "dhcp4_log.h"
+
+namespace isc {
+namespace dhcp {
+
+isc::log::Logger dhcp4_logger("dhcp4");
+
+} // namespace dhcp
+} // namespace isc
+
diff --git a/src/bin/dhcp4/dhcp4_log.h b/src/bin/dhcp4/dhcp4_log.h
new file mode 100644
index 0000000..3717b62
--- /dev/null
+++ b/src/bin/dhcp4/dhcp4_log.h
@@ -0,0 +1,59 @@
+// 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 __DHCP4_LOG__H
+#define __DHCP4_LOG__H
+
+#include <log/macros.h>
+#include <log/logger_support.h>
+#include <dhcp4/dhcp4_messages.h>
+
+namespace isc {
+namespace dhcp {
+
+/// \brief DHCP4 Logging
+///
+/// Defines the levels used to output debug messages in the non-library part of
+/// the b10-dhcp4 program. Higher numbers equate to more verbose (and detailed)
+/// output.
+
+// Debug levels used to log information during startup and shutdown.
+const int DBG_DHCP4_START = DBGLVL_START_SHUT;
+const int DBG_DHCP4_SHUT = DBGLVL_START_SHUT;
+
+// Debug level used to log setting information (such as configuration changes).
+const int DBG_DHCP4_COMMAND = DBGLVL_COMMAND;
+
+// Trace basic operations within the code.
+const int DBG_DHCP4_BASIC = DBGLVL_TRACE_BASIC;
+
+// Trace detailed operations, including errors raised when processing invalid
+// packets. (These are not logged at severities of WARN or higher for fear
+// that a set of deliberately invalid packets set to the server could overwhelm
+// the logging.)
+const int DBG_DHCP4_DETAIL = DBGLVL_TRACE_DETAIL;
+
+// This level is used to log the contents of packets received and sent.
+const int DBG_DHCP4_DETAIL_DATA = DBGLVL_TRACE_DETAIL_DATA;
+
+/// Define the logger for the "dhcp4" module part of b10-dhcp4. We could define
+/// a logger in each file, but we would want to define a common name to avoid
+/// spelling mistakes, so it is just one small step from there to define a
+/// module-common logger.
+extern isc::log::Logger dhcp4_logger;
+
+} // namespace dhcp4
+} // namespace isc
+
+#endif // __DHCP4_LOG__H
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
new file mode 100644
index 0000000..98e402d
--- /dev/null
+++ b/src/bin/dhcp4/dhcp4_messages.mes
@@ -0,0 +1,98 @@
+# 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.
+
+$NAMESPACE isc::dhcp
+
+% DHCP4_CCSESSION_STARTED control channel session started on socket %1
+A debug message issued during startup after the IPv4 DHCP server has
+successfully established a session with the BIND 10 control channel.
+
+% DHCP4_CCSESSION_STARTING starting control channel session, specfile: %1
+This debug message is issued just before the IPv4 DHCP server attempts
+to establish a session with the BIND 10 control channel.
+
+% DHCP4_COMMAND_RECEIVED received command %1, arguments: %2
+A debug message listing the command (and possible arguments) received
+from the BIND 10 control system by the IPv4 DHCP server.
+
+% DHCP4_CONFIG_UPDATE updated configuration received: %1
+A debug message indicating that the IPv4 DHCP server has received an
+updated configuration from the BIND 10 configuration system.
+
+% DHCP4_NOT_RUNNING IPv4 DHCP server is not running
+A warning message is issued when an attempt is made to shut down the
+IPv4 DHCP server but it is not running.
+
+% DHCP4_OPEN_SOCKET opening sockets on port %1
+A debug message issued during startup, this indicates that the IPv4 DHCP
+server is about to open sockets on the specified port.
+
+% DHCP4_PACKET_PARSE_FAIL failed to parse incoming packet: %1
+The IPv4 DHCP server has received a packet that it is unable to
+interpret. The reason why the packet is invalid is included in the message.
+
+% DHCP4_PACKET_RECEIVED %1 (type %2) packet received on interface %3
+A debug message noting that the server has received the specified type of
+packet on the specified interface. Note that a packet marked as UNKNOWN
+may well be a valid DHCP packet, just a type not expected by the server
+(e.g. it will report a received OFFER packet as UNKNOWN).
+
+% DHCP4_PACK_FAIL failed to assemble response correctly
+This error is output if the server failed to assemble the data to be
+returned to the client into a valid packet. The cause is most likely
+to be a programming error: please raise a bug report.
+
+% DHCP4_QUERY_DATA received packet type %1, data is <%2>
+A debug message listing the data received from the client.
+
+% DHCP4_RESPONSE_DATA responding with packet type %1, data is <%2>
+A debug message listing the data returned to the client.
+
+% DHCP4_SERVER_FAILED server failed: %1
+The IPv4 DHCP server has encountered a fatal error and is terminating.
+The reason for the failure is included in the message.
+
+% DHCP4_SESSION_FAIL failed to establish BIND 10 session (%1), running stand-alone
+The server has failed to establish communication with the rest of BIND
+10 and is running in stand-alone mode. (This behavior will change once
+the IPv4 DHCP server is properly integrated with the rest of BIND 10.)
+
+% DHCP4_SHUTDOWN server shutdown
+The IPv4 DHCP server has terminated normally.
+
+% DHCP4_SHUTDOWN_REQUEST shutdown of server requested
+This debug message indicates that a shutdown of the IPv4 server has
+been requested via a call to the 'shutdown' method of the core Dhcpv4Srv
+object.
+
+% DHCP4_SRV_CONSTRUCT_ERROR error creating Dhcpv4Srv object, reason: %1
+This error message indicates that during startup, the construction of a
+core component within the IPv4 DHCP server (the Dhcpv4 server object)
+has failed. As a result, the server will exit. The reason for the
+failure is given within the message.
+
+% DHCP4_STANDALONE skipping message queue, running standalone
+This is a debug message indicating that the IPv4 server is running in
+standalone mode, not connected to the message queue. Standalone mode
+is only useful during program development, and should not be used in a
+production environment.
+
+% DHCP4_STARTING server starting
+This informational message indicates that the IPv4 DHCP server has
+processed any command-line switches and is starting.
+
+% DHCP4_START_INFO pid: %1, port: %2, verbose: %3, standalone: %4
+This is a debug message issued during the IPv4 DHCP server startup.
+It lists some information about the parameters with which the server
+is running.
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
index a86b010..2bbc075 100644
--- a/src/bin/dhcp4/dhcp4_srv.cc
+++ b/src/bin/dhcp4/dhcp4_srv.cc
@@ -16,13 +16,15 @@
#include <dhcp/pkt4.h>
#include <dhcp/iface_mgr.h>
#include <dhcp4/dhcp4_srv.h>
+#include <dhcp4/dhcp4_log.h>
#include <asiolink/io_address.h>
#include <dhcp/option4_addrlst.h>
-using namespace std;
using namespace isc;
-using namespace isc::dhcp;
using namespace isc::asiolink;
+using namespace isc::dhcp;
+using namespace isc::log;
+using namespace std;
// These are hardcoded parameters. Currently this is a skeleton server that only
// grants those options and a single, fixed, hardcoded lease.
@@ -35,20 +37,19 @@ const std::string HARDCODED_DOMAIN_NAME = "isc.example.com";
const std::string HARDCODED_SERVER_ID = "192.0.2.1";
Dhcpv4Srv::Dhcpv4Srv(uint16_t port) {
- cout << "Initialization: opening sockets on port " << port << endl;
-
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_OPEN_SOCKET).arg(port);
try {
- // first call to instance() will create IfaceMgr (it's a singleton)
+ // First call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong
IfaceMgr::instance();
/// @todo: instantiate LeaseMgr here once it is imlpemented.
-
IfaceMgr::instance().openSockets4(port);
setServerID();
+
} catch (const std::exception &e) {
- cerr << "Error during DHCPv4 server startup: " << e.what() << endl;
+ LOG_ERROR(dhcp4_logger, DHCP4_SRV_CONSTRUCT_ERROR).arg(e.what());
shutdown_ = true;
return;
}
@@ -57,12 +58,11 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port) {
}
Dhcpv4Srv::~Dhcpv4Srv() {
- cout << "b10-dhcp4: DHCPv4 server terminating." << endl;
IfaceMgr::instance().closeSockets();
}
void Dhcpv4Srv::shutdown() {
- cout << "b10-dhcp4: DHCPv4 server shutdown." << endl;
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_SHUTDOWN_REQUEST);
shutdown_ = true;
}
@@ -79,39 +79,48 @@ Dhcpv4Srv::run() {
if (query) {
try {
query->unpack();
+
} catch (const std::exception& e) {
- /// TODO: Printout reasons of failed parsing
- cout << "Failed to parse incoming packet " << endl;
+ // Failed to parse the packet.
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL,
+ DHCP4_PACKET_PARSE_FAIL).arg(e.what());
continue;
}
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_PACKET_RECEIVED)
+ .arg(serverReceivedPacketName(query->getType()))
+ .arg(query->getType())
+ .arg(query->getIface());
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL_DATA, DHCP4_QUERY_DATA)
+ .arg(query->toText());
switch (query->getType()) {
case DHCPDISCOVER:
rsp = processDiscover(query);
break;
+
case DHCPREQUEST:
rsp = processRequest(query);
break;
+
case DHCPRELEASE:
processRelease(query);
break;
+
case DHCPDECLINE:
processDecline(query);
break;
+
case DHCPINFORM:
processInform(query);
break;
+
default:
- cout << "Unknown pkt type received:"
- << query->getType() << endl;
+ // Only action is to output a message if debug is enabled,
+ // and that will be covered by the debug statement before
+ // the "switch" statement.
+ ;
}
- cout << "Received message type " << int(query->getType()) << endl;
-
- // TODO: print out received packets only if verbose (or debug)
- // mode is enabled
- cout << query->toText();
-
if (rsp) {
if (rsp->getRemoteAddr().toText() == "0.0.0.0") {
rsp->setRemoteAddr(query->getRemoteAddr());
@@ -127,14 +136,15 @@ Dhcpv4Srv::run() {
rsp->setIface(query->getIface());
rsp->setIndex(query->getIndex());
- cout << "Replying with message type "
- << static_cast<int>(rsp->getType()) << ":" << endl;
- cout << rsp->toText();
- cout << "----" << endl;
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL_DATA,
+ DHCP4_RESPONSE_DATA)
+ .arg(rsp->getType()).arg(rsp->toText());
+
if (rsp->pack()) {
- cout << "Packet assembled correctly." << endl;
+ IfaceMgr::instance().send(rsp);
+ } else {
+ LOG_ERROR(dhcp4_logger, DHCP4_PACK_FAIL);
}
- IfaceMgr::instance().send(rsp);
}
}
@@ -266,15 +276,44 @@ Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
/// TODO: Implement this.
- cout << "Received RELEASE on " << release->getIface() << " interface." << endl;
}
void Dhcpv4Srv::processDecline(Pkt4Ptr& decline) {
/// TODO: Implement this.
- cout << "Received DECLINE on " << decline->getIface() << " interface." << endl;
}
Pkt4Ptr Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
/// TODO: Currently implemented echo mode. Implement this for real
return (inform);
}
+
+const char*
+Dhcpv4Srv::serverReceivedPacketName(uint8_t type) {
+ static const char* DISCOVER = "DISCOVER";
+ static const char* REQUEST = "REQUEST";
+ static const char* RELEASE = "RELEASE";
+ static const char* DECLINE = "DECLINE";
+ static const char* INFORM = "INFORM";
+ static const char* UNKNOWN = "UNKNOWN";
+
+ switch (type) {
+ case DHCPDISCOVER:
+ return (DISCOVER);
+
+ case DHCPREQUEST:
+ return (REQUEST);
+
+ case DHCPRELEASE:
+ return (RELEASE);
+
+ case DHCPDECLINE:
+ return (DECLINE);
+
+ case DHCPINFORM:
+ return (INFORM);
+
+ default:
+ ;
+ }
+ return (UNKNOWN);
+}
diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h
index dc087ff..f677259 100644
--- a/src/bin/dhcp4/dhcp4_srv.h
+++ b/src/bin/dhcp4/dhcp4_srv.h
@@ -44,7 +44,7 @@ class Dhcpv4Srv : public boost::noncopyable {
public:
/// @brief Default constructor.
///
- /// Instantiates necessary services, required to run DHCPv6 server.
+ /// Instantiates necessary services, required to run DHCPv4 server.
/// In particular, creates IfaceMgr that will be responsible for
/// network interaction. Will instantiate lease manager, and load
/// old or create new DUID. It is possible to specify alternate
@@ -54,7 +54,7 @@ class Dhcpv4Srv : public boost::noncopyable {
/// @param port specifies port number to listen on
Dhcpv4Srv(uint16_t port = DHCP4_SERVER_PORT);
- /// @brief Destructor. Used during DHCPv6 service shutdown.
+ /// @brief Destructor. Used during DHCPv4 service shutdown.
~Dhcpv4Srv();
/// @brief Main server processing loop.
@@ -70,6 +70,23 @@ class Dhcpv4Srv : public boost::noncopyable {
/// @brief Instructs the server to shut down.
void shutdown();
+ /// @brief Return textual type of packet received by server
+ ///
+ /// Returns the name of valid packet received by the server (e.g. DISCOVER).
+ /// If the packet is unknown - or if it is a valid DHCP packet but not one
+ /// expected to be received by the server (such as an OFFER), the string
+ /// "UNKNOWN" is returned. This method is used in debug messages.
+ ///
+ /// As the operation of the method does not depend on any server state, it
+ /// is declared static.
+ ///
+ /// @param type DHCPv4 packet type
+ ///
+ /// @return Pointer to "const" string containing the packet name.
+ /// Note that this string is statically allocated and MUST NOT
+ /// be freed by the caller.
+ static const char* serverReceivedPacketName(uint8_t type);
+
protected:
/// @brief Processes incoming DISCOVER and returns response.
///
@@ -89,11 +106,11 @@ protected:
/// is valid, not expired, not reserved, not used by other client and
/// that requesting client is allowed to use it.
///
- /// Returns ACK message, NACK message, or NULL
+ /// Returns ACK message, NAK message, or NULL
///
/// @param request a message received from client
///
- /// @return ACK or NACK message
+ /// @return ACK or NAK message
Pkt4Ptr processRequest(Pkt4Ptr& request);
/// @brief Stub function that will handle incoming RELEASE messages.
diff --git a/src/bin/dhcp4/main.cc b/src/bin/dhcp4/main.cc
index 1087cc7..31f0b02 100644
--- a/src/bin/dhcp4/main.cc
+++ b/src/bin/dhcp4/main.cc
@@ -14,13 +14,15 @@
#include <config.h>
#include <iostream>
-#include <log/dummylog.h>
-#include <log/logger_support.h>
-#include <dhcp4/ctrl_dhcp4_srv.h>
+
#include <boost/lexical_cast.hpp>
-using namespace std;
+#include <dhcp4/ctrl_dhcp4_srv.h>
+#include <dhcp4/dhcp4_log.h>
+#include <log/logger_support.h>
+
using namespace isc::dhcp;
+using namespace std;
/// This file contains entry point (main() function) for standard DHCPv4 server
/// component for BIND10 framework. It parses command-line arguments and
@@ -37,11 +39,10 @@ const char* const DHCP4_NAME = "b10-dhcp4";
void
usage() {
- cerr << "Usage: b10-dhcp4 [-v]"
- << endl;
- cerr << "\t-v: verbose output" << endl;
- cerr << "\t-s: stand-alone mode (don't connect to BIND10)" << endl;
- cerr << "\t-p number: specify non-standard port number 1-65535 "
+ cerr << "Usage: " << DHCP4_NAME << " [-v] [-s] [-p number]" << endl;
+ cerr << " -v: verbose output" << endl;
+ cerr << " -s: stand-alone mode (don't connect to BIND10)" << endl;
+ cerr << " -p number: specify non-standard port number 1-65535 "
<< "(useful for testing only)" << endl;
exit(EXIT_FAILURE);
}
@@ -50,20 +51,21 @@ usage() {
int
main(int argc, char* argv[]) {
int ch;
- bool verbose_mode = false; // should server be verbose?
int port_number = DHCP4_SERVER_PORT; // The default. any other values are
// useful for testing only.
- bool stand_alone = false; // should be connect to BIND10 msgq?
+ bool stand_alone = false; // Should be connect to BIND10 msgq?
+ bool verbose_mode = false; // Should server be verbose?
while ((ch = getopt(argc, argv, "vsp:")) != -1) {
switch (ch) {
case 'v':
verbose_mode = true;
- isc::log::denabled = true;
break;
+
case 's':
stand_alone = true;
break;
+
case 'p':
try {
port_number = boost::lexical_cast<int>(optarg);
@@ -78,50 +80,46 @@ main(int argc, char* argv[]) {
usage();
}
break;
- case ':':
+
default:
usage();
}
}
+ // Check for extraneous parameters.
+ if (argc > optind) {
+ usage();
+ }
+
// Initialize logging. If verbose, we'll use maximum verbosity.
isc::log::initLogger(DHCP4_NAME,
(verbose_mode ? isc::log::DEBUG : isc::log::INFO),
isc::log::MAX_DEBUG_LEVEL, NULL);
+ LOG_INFO(dhcp4_logger, DHCP4_STARTING);
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_START_INFO)
+ .arg(getpid()).arg(port_number).arg(verbose_mode ? "yes" : "no")
+ .arg(stand_alone ? "yes" : "no" );
- cout << "b10-dhcp4: My pid=" << getpid() << ", binding to port "
- << port_number << ", verbose " << (verbose_mode?"yes":"no")
- << ", stand-alone=" << (stand_alone?"yes":"no") << endl;
-
- if (argc - optind > 0) {
- usage();
- }
int ret = EXIT_SUCCESS;
-
try {
-
- cout << "[b10-dhcp4] Initiating DHCPv4 server operation." << endl;
-
- /// @todo: pass verbose to the actul server once logging is implemented
ControlledDhcpv4Srv server(port_number);
-
if (!stand_alone) {
try {
server.establishSession();
} catch (const std::exception& ex) {
- cerr << "Failed to establish BIND10 session. "
- "Running in stand-alone mode:" << ex.what() << endl;
+ LOG_ERROR(dhcp4_logger, DHCP4_SESSION_FAIL).arg(ex.what());
// Let's continue. It is useful to have the ability to run
// DHCP server in stand-alone mode, e.g. for testing
}
} else {
- cout << "Skipping connection to the BIND10 msgq." << endl;
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_START, DHCP4_STANDALONE);
}
-
server.run();
+ LOG_INFO(dhcp4_logger, DHCP4_SHUTDOWN);
+
} catch (const std::exception& ex) {
- cerr << "[b10-dhcp4] Server failed: " << ex.what() << endl;
+ LOG_FATAL(dhcp4_logger, DHCP4_SERVER_FAILED).arg(ex.what());
ret = EXIT_FAILURE;
}
diff --git a/src/bin/dhcp4/tests/Makefile.am b/src/bin/dhcp4/tests/Makefile.am
index 402af60..0e96d70 100644
--- a/src/bin/dhcp4/tests/Makefile.am
+++ b/src/bin/dhcp4/tests/Makefile.am
@@ -47,6 +47,8 @@ if HAVE_GTEST
TESTS += dhcp4_unittests
dhcp4_unittests_SOURCES = ../dhcp4_srv.h ../dhcp4_srv.cc ../ctrl_dhcp4_srv.cc
+dhcp4_unittests_SOURCES += ../dhcp4_log.h ../dhcp4_log.cc
+dhcp4_unittests_SOURCES += ../dhcp4_messages.h ../dhcp4_messages.cc
dhcp4_unittests_SOURCES += dhcp4_unittests.cc
dhcp4_unittests_SOURCES += dhcp4_srv_unittest.cc
dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
index cfc12fb..fca06ad 100644
--- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
+++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-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
@@ -271,4 +271,36 @@ TEST_F(Dhcpv4SrvTest, processInform) {
delete srv;
}
+TEST_F(Dhcpv4SrvTest, serverReceivedPacketName) {
+ // Check all possible packet types
+ for (int itype = 0; itype < 256; ++itype) {
+ uint8_t type = itype;
+
+ switch (type) {
+ case DHCPDECLINE:
+ EXPECT_STREQ("DECLINE", Dhcpv4Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPDISCOVER:
+ EXPECT_STREQ("DISCOVER", Dhcpv4Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPINFORM:
+ EXPECT_STREQ("INFORM", Dhcpv4Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPRELEASE:
+ EXPECT_STREQ("RELEASE", Dhcpv4Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPREQUEST:
+ EXPECT_STREQ("REQUEST", Dhcpv4Srv::serverReceivedPacketName(type));
+ break;
+
+ default:
+ EXPECT_STREQ("UNKNOWN", Dhcpv4Srv::serverReceivedPacketName(type));
+ }
+ }
+}
+
} // end of anonymous namespace
diff --git a/src/bin/dhcp4/tests/dhcp4_test.py b/src/bin/dhcp4/tests/dhcp4_test.py
index 935bba6..444dfcf 100644
--- a/src/bin/dhcp4/tests/dhcp4_test.py
+++ b/src/bin/dhcp4/tests/dhcp4_test.py
@@ -27,16 +27,27 @@ import fcntl
class TestDhcpv4Daemon(unittest.TestCase):
def setUp(self):
- # don't redirect stdout/stderr here as we want to print out things
+ # Don't redirect stdout/stderr here as we want to print out things
# during the test
- pass
+ #
+ # However, we do want to set the logging lock directory to somewhere
+ # to which we can write - use the current working directory. We then
+ # set the appropriate environment variable. os.putenv() may be not
+ # supported on some platforms as suggested in
+ # http://docs.python.org/release/3.2/library/os.html?highlight=putenv#os.environ:
+ # "If the platform supports the putenv() function...". It was checked
+ # that it does not work on Ubuntu. To overcome this problem we access
+ # os.environ directly.
+ lockdir_envvar = "B10_LOCKFILE_DIR_FROM_BUILD"
+ if lockdir_envvar not in os.environ:
+ os.environ[lockdir_envvar] = os.getcwd()
def tearDown(self):
pass
def runCommand(self, params, wait=1):
"""
- This method runs dhcp4 and returns a touple: (returncode, stdout, stderr)
+ This method runs dhcp4 and returns a tuple: (returncode, stdout, stderr)
"""
## @todo: Convert this into generic method and reuse it in dhcp6
@@ -79,9 +90,9 @@ class TestDhcpv4Daemon(unittest.TestCase):
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
# There's potential problem if b10-dhcp4 prints out more
- # than 4k of text
+ # than 16kB of text
try:
- output = os.read(self.stdout_pipes[0], 4096)
+ output = os.read(self.stdout_pipes[0], 16384)
except OSError:
print("No data available from stdout")
output = ""
@@ -91,7 +102,7 @@ class TestDhcpv4Daemon(unittest.TestCase):
output = ""
try:
- error = os.read(self.stderr_pipes[0], 4096)
+ error = os.read(self.stderr_pipes[0], 16384)
except OSError:
print("No data available on stderr")
error = ""
@@ -128,13 +139,13 @@ class TestDhcpv4Daemon(unittest.TestCase):
print(" not that is can bind sockets correctly. Please ignore binding errors.")
(returncode, output, error) = self.runCommand(["../b10-dhcp4", "-v"])
-
- self.assertEqual( str(output).count("[b10-dhcp4] Initiating DHCPv4 server operation."), 1)
+ output_text = str(output) + str(error)
+ self.assertEqual(output_text.count("DHCP4_STARTING"), 1)
def test_portnumber_0(self):
print("Check that specifying port number 0 is not allowed.")
- (returncode, output, error) = self.runCommand(['../b10-dhcp4', '-p', '0'])
+ (returncode, output, error) = self.runCommand(['../b10-dhcp4', '-v', '-p', '0'])
# When invalid port number is specified, return code must not be success
self.assertTrue(returncode != 0)
@@ -178,28 +189,19 @@ class TestDhcpv4Daemon(unittest.TestCase):
def test_portnumber_nonroot(self):
print("Check that specifying unprivileged port number will work.")
- (returncode, output, error) = self.runCommand(['../b10-dhcp4', '-s', '-p', '10057'])
-
- # When invalid port number is specified, return code must not be success
- # TODO: Temporarily commented out as socket binding on systems that do not have
- # interface detection implemented currently fails.
- # self.assertTrue(returncode == 0)
-
- # Check that there is an error message about invalid port number printed on stderr
- self.assertEqual( str(output).count("opening sockets on port 10057"), 1)
+ # Check that there is a message about running with an unprivileged port
+ (returncode, output, error) = self.runCommand(['../b10-dhcp4', '-v', '-s', '-p', '10057'])
+ output_text = str(output) + str(error)
+ self.assertEqual(output_text.count("DHCP4_OPEN_SOCKET opening sockets on port 10057"), 1)
def test_skip_msgq(self):
print("Check that connection to BIND10 msgq can be disabled.")
- (returncode, output, error) = self.runCommand(['../b10-dhcp4', '-s', '-p', '10057'])
-
- # When invalid port number is specified, return code must not be success
- # TODO: Temporarily commented out as socket binding on systems that do not have
- # interface detection implemented currently fails.
- # self.assertTrue(returncode == 0)
-
- # Check that there is an error message about invalid port number printed on stderr
- self.assertEqual( str(output).count("Skipping connection to the BIND10 msgq."), 1)
+ # Check that the system outputs a message on one of its streams about running
+ # standalone.
+ (returncode, output, error) = self.runCommand(['../b10-dhcp4', '-v', '-s', '-p', '10057'])
+ output_text = str(output) + str(error)
+ self.assertEqual(output_text.count("DHCP4_STANDALONE"), 1)
if __name__ == '__main__':
unittest.main()
diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am
index f711c97..4dec4e7 100644
--- a/src/bin/dhcp6/Makefile.am
+++ b/src/bin/dhcp6/Makefile.am
@@ -13,7 +13,7 @@ endif
pkglibexecdir = $(libexecdir)/@PACKAGE@
-CLEANFILES = spec_config.h
+CLEANFILES = spec_config.h dhcp6_messages.h dhcp6_messages.cc
man_MANS = b10-dhcp6.8
DISTCLEANFILES = $(man_MANS)
@@ -37,11 +37,20 @@ endif
spec_config.h: spec_config.h.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
-BUILT_SOURCES = spec_config.h
+dhcp6_messages.h dhcp6_messages.cc: dhcp6_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/bin/dhcp6/dhcp6_messages.mes
+
+BUILT_SOURCES = spec_config.h dhcp6_messages.h dhcp6_messages.cc
+
pkglibexec_PROGRAMS = b10-dhcp6
-b10_dhcp6_SOURCES = main.cc dhcp6_srv.cc dhcp6_srv.h
+b10_dhcp6_SOURCES = main.cc
b10_dhcp6_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
+b10_dhcp6_SOURCES += dhcp6_log.cc dhcp6_log.h
+b10_dhcp6_SOURCES += dhcp6_srv.cc dhcp6_srv.h
+
+nodist_b10_dhcp6_SOURCES = dhcp6_messages.h dhcp6_messages.cc
+EXTRA_DIST += dhcp6_messages.mes
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
@@ -49,7 +58,7 @@ if USE_CLANGPP
b10_dhcp6_CXXFLAGS = -Wno-unused-parameter
endif
-b10_dhcp6_LDADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
+b10_dhcp6_LDADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc
index 461d5f1..4afb203 100644
--- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc
+++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc
@@ -13,28 +13,30 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
+
#include <cassert>
#include <iostream>
-#include <cc/session.h>
+#include <asiolink/asiolink.h>
#include <cc/data.h>
-#include <exceptions/exceptions.h>
+#include <cc/session.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 <dhcp6/dhcp6_log.h>
+#include <dhcp6/spec_config.h>
#include <dhcp/iface_mgr.h>
-#include <asiolink/asiolink.h>
+#include <exceptions/exceptions.h>
+#include <util/buffer.h>
-using namespace std;
-using namespace isc::util;
-using namespace isc::dhcp;
-using namespace isc::util;
-using namespace isc::data;
+using namespace isc::asiolink;
using namespace isc::cc;
using namespace isc::config;
-using namespace isc::asiolink;
+using namespace isc::data;
+using namespace isc::dhcp;
+using namespace isc::log;
+using namespace isc::util;
+using namespace std;
namespace isc {
namespace dhcp {
@@ -43,7 +45,8 @@ ControlledDhcpv6Srv* ControlledDhcpv6Srv::server_ = NULL;
ConstElementPtr
ControlledDhcpv6Srv::dhcp6ConfigHandler(ConstElementPtr new_config) {
- cout << "b10-dhcp6: Received new config:" << new_config->str() << endl;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_UPDATE)
+ .arg(new_config->str());
ConstElementPtr answer = isc::config::createAnswer(0,
"Thank you for sending config.");
return (answer);
@@ -51,13 +54,14 @@ ControlledDhcpv6Srv::dhcp6ConfigHandler(ConstElementPtr new_config) {
ConstElementPtr
ControlledDhcpv6Srv::dhcp6CommandHandler(const string& command, ConstElementPtr args) {
- cout << "b10-dhcp6: Received new command: [" << command << "], args="
- << args->str() << endl;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_COMMAND_RECEIVED)
+ .arg(command).arg(args->str());
+
if (command == "shutdown") {
if (ControlledDhcpv6Srv::server_) {
ControlledDhcpv6Srv::server_->shutdown();
} else {
- cout << "Server not initialized yet or already shut down." << endl;
+ LOG_WARN(dhcp6_logger, DHCP6_NOT_RUNNING);
ConstElementPtr answer = isc::config::createAnswer(1,
"Shutdown failure.");
return (answer);
@@ -93,10 +97,9 @@ void ControlledDhcpv6Srv::establishSession() {
/// @todo: Check if session is not established already. Throw, if it is.
- cout << "b10-dhcp6: my specfile is " << specfile << endl;
-
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_CCSESSION_STARTING)
+ .arg(specfile);
cc_session_ = new Session(io_service_.get_io_service());
-
config_session_ = new ModuleCCSession(specfile, *cc_session_,
dhcp6ConfigHandler,
dhcp6CommandHandler, false);
@@ -106,8 +109,8 @@ void ControlledDhcpv6Srv::establishSession() {
/// 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;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_CCSESSION_STARTED)
+ .arg(ctrl_socket);
IfaceMgr::instance().set_session_socket(ctrl_socket, sessionReader);
}
diff --git a/src/bin/dhcp6/dhcp6_log.cc b/src/bin/dhcp6/dhcp6_log.cc
new file mode 100644
index 0000000..d893834
--- /dev/null
+++ b/src/bin/dhcp6/dhcp6_log.cc
@@ -0,0 +1,26 @@
+// 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.
+
+/// Defines the logger used by the top-level component of b10-dhcp6.
+
+#include "dhcp6_log.h"
+
+namespace isc {
+namespace dhcp {
+
+isc::log::Logger dhcp6_logger("dhcp6");
+
+} // namespace dhcp
+} // namespace isc
+
diff --git a/src/bin/dhcp6/dhcp6_log.h b/src/bin/dhcp6/dhcp6_log.h
new file mode 100644
index 0000000..6d7f4e3
--- /dev/null
+++ b/src/bin/dhcp6/dhcp6_log.h
@@ -0,0 +1,59 @@
+// 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 __DHCP6_LOG__H
+#define __DHCP6_LOG__H
+
+#include <log/macros.h>
+#include <log/logger_support.h>
+#include <dhcp6/dhcp6_messages.h>
+
+namespace isc {
+namespace dhcp {
+
+/// \brief DHCP6 Logging
+///
+/// Defines the levels used to output debug messages in the non-library part of
+/// the b10-dhcp6 program. Higher numbers equate to more verbose (and detailed)
+/// output.
+
+// Debug levels used to log information during startup and shutdown.
+const int DBG_DHCP6_START = DBGLVL_START_SHUT;
+const int DBG_DHCP6_SHUT = DBGLVL_START_SHUT;
+
+// Debug level used to log setting information (such as configuration changes).
+const int DBG_DHCP6_COMMAND = DBGLVL_COMMAND;
+
+// Trace basic operations within the code.
+const int DBG_DHCP6_BASIC = DBGLVL_TRACE_BASIC;
+
+// Trace detailed operations, including errors raised when processing invalid
+// packets. (These are not logged at severities of WARN or higher for fear
+// that a set of deliberately invalid packets set to the server could overwhelm
+// the logging.)
+const int DBG_DHCP6_DETAIL = DBGLVL_TRACE_DETAIL;
+
+// This level is used to log the contents of packets received and sent.
+const int DBG_DHCP6_DETAIL_DATA = DBGLVL_TRACE_DETAIL_DATA;
+
+/// Define the logger for the "dhcp6" module part of b10-dhcp6. We could define
+/// a logger in each file, but we would want to define a common name to avoid
+/// spelling mistakes, so it is just one small step from there to define a
+/// module-common logger.
+extern isc::log::Logger dhcp6_logger;
+
+} // namespace dhcp6
+} // namespace isc
+
+#endif // __DHCP6_LOG__H
diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
new file mode 100644
index 0000000..a361531
--- /dev/null
+++ b/src/bin/dhcp6/dhcp6_messages.mes
@@ -0,0 +1,101 @@
+# 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.
+
+$NAMESPACE isc::dhcp
+
+% DHCP6_CCSESSION_STARTED control channel session started on socket %1
+A debug message issued during startup after the IPv6 DHCP server has
+successfully established a session with the BIND 10 control channel.
+
+% DHCP6_CCSESSION_STARTING starting control channel session, specfile: %1
+This debug message is issued just before the IPv6 DHCP server attempts
+to establish a session with the BIND 10 control channel.
+
+% DHCP6_COMMAND_RECEIVED received command %1, arguments: %2
+A debug message listing the command (and possible arguments) received
+from the BIND 10 control system by the IPv6 DHCP server.
+
+% DHCP6_CONFIG_UPDATE updated configuration received: %1
+A debug message indicating that the IPv6 DHCP server has received an
+updated configuration from the BIND 10 configuration system.
+
+% DHCP6_NOT_RUNNING IPv6 DHCP server is not running
+A warning message is issued when an attempt is made to shut down the
+IPv6 DHCP server but it is not running.
+
+% DHCP6_NO_INTERFACES failed to detect any network interfaces
+During startup the IPv6 DHCP server failed to detect any network
+interfaces and is therefore shutting down.
+
+% DHCP6_OPEN_SOCKET opening sockets on port %1
+A debug message issued during startup, this indicates that the IPv6 DHCP
+server is about to open sockets on the specified port.
+
+% DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
+The IPv6 DHCP server has received a packet that it is unable to interpret.
+
+% DHCP6_PACKET_RECEIVED %1 (type %2) packet received
+A debug message noting that the server has received the specified type
+of packet. Note that a packet marked as UNKNOWN may well be a valid
+DHCP packet, just a type not expected by the server (e.g. it will report
+a received OFFER packet as UNKNOWN).
+
+% DHCP6_PACK_FAIL failed to assemble response correctly
+This error is output if the server failed to assemble the data to be
+returned to the client into a valid packet. The reason is most likely
+to be to a programming error: please raise a bug report.
+
+% DHCP6_QUERY_DATA received packet length %1, data length %2, data is <%3>
+A debug message listing the data received from the client or relay.
+
+% DHCP6_RESPONSE_DATA responding with packet type %1 data is <%2>
+A debug message listing the data returned to the client.
+
+% DHCP6_SERVER_FAILED server failed: %1
+The IPv6 DHCP server has encountered a fatal error and is terminating.
+The reason for the failure is included in the message.
+
+% DHCP6_SESSION_FAIL failed to establish BIND 10 session (%1), running stand-alone
+The server has failed to establish communication with the rest of BIND
+10 and is running in stand-alone mode. (This behavior will change once
+the IPv6 DHCP server is properly integrated with the rest of BIND 10.)
+
+% DHCP6_SHUTDOWN server shutdown
+The IPv6 DHCP server has terminated normally.
+
+% DHCP6_SHUTDOWN_REQUEST shutdown of server requested
+This debug message indicates that a shutdown of the IPv6 server has
+been requested via a call to the 'shutdown' method of the core Dhcpv6Srv
+object.
+
+% DHCP6_SRV_CONSTRUCT_ERROR error creating Dhcpv6Srv object, reason: %1
+This error message indicates that during startup, the construction of a
+core component within the IPv6 DHCP server (the Dhcpv6 server object)
+has failed. As a result, the server will exit. The reason for the
+failure is given within the message.
+
+% DHCP6_STANDALONE skipping message queue, running standalone
+This is a debug message indicating that the IPv6 server is running in
+standalone mode, not connected to the message queue. Standalone mode
+is only useful during program development, and should not be used in a
+production environment.
+
+% DHCP6_STARTING server starting
+This informational message indicates that the IPv6 DHCP server has
+processed any command-line switches and is starting.
+
+% DHCP6_START_INFO pid: %1, port: %2, verbose: %3, standalone: %4
+This is a debug message issued during the IPv6 DHCP server startup.
+It lists some information about the parameters with which the server
+is running.
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 9b43f53..7c21941 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -14,23 +14,25 @@
#include <stdlib.h>
#include <time.h>
+
+#include <asiolink/io_address.h>
+#include <dhcp6/dhcp6_log.h>
+#include <dhcp6/dhcp6_srv.h>
#include <dhcp/dhcp6.h>
-#include <dhcp/pkt6.h>
#include <dhcp/iface_mgr.h>
-#include <dhcp6/dhcp6_srv.h>
-#include <dhcp/option6_ia.h>
-#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_addrlst.h>
-#include <asiolink/io_address.h>
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_ia.h>
+#include <dhcp/pkt6.h>
#include <exceptions/exceptions.h>
#include <util/io_utilities.h>
#include <util/range_utilities.h>
-using namespace std;
using namespace isc;
-using namespace isc::dhcp;
using namespace isc::asiolink;
+using namespace isc::dhcp;
using namespace isc::util;
+using namespace std;
const std::string HARDCODED_LEASE = "2001:db8:1::1234:abcd";
const uint32_t HARDCODED_T1 = 1500; // in seconds
@@ -40,14 +42,14 @@ const uint32_t HARDCODED_VALID_LIFETIME = 7200; // in seconds
const std::string HARDCODED_DNS_SERVER = "2001:db8:1::1";
Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
- cout << "Initialization: opening sockets on port " << port << endl;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_OPEN_SOCKET).arg(port);
- // first call to instance() will create IfaceMgr (it's a singleton)
+ // First call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong
try {
if (IfaceMgr::instance().countIfaces() == 0) {
- cout << "Failed to detect any network interfaces. Aborting." << endl;
+ LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
shutdown_ = true;
return;
}
@@ -59,7 +61,7 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
/// @todo: instantiate LeaseMgr here once it is imlpemented.
} catch (const std::exception &e) {
- cerr << "Error during DHCPv4 server startup: " << e.what() << endl;
+ LOG_ERROR(dhcp6_logger, DHCP6_SRV_CONSTRUCT_ERROR).arg(e.what());
shutdown_ = true;
return;
}
@@ -68,13 +70,11 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port) {
}
Dhcpv6Srv::~Dhcpv6Srv() {
- cout << "DHCPv6 Srv shutdown." << endl;
-
IfaceMgr::instance().closeSockets();
}
void Dhcpv6Srv::shutdown() {
- cout << "b10-dhcp6: DHCPv6 server shutdown." << endl;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_SHUTDOWN_REQUEST);
shutdown_ = true;
}
@@ -89,42 +89,58 @@ bool Dhcpv6Srv::run() {
if (query) {
if (!query->unpack()) {
- cout << "Failed to parse incoming packet" << endl;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
+ DHCP6_PACKET_PARSE_FAIL);
continue;
}
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PACKET_RECEIVED)
+ .arg(serverReceivedPacketName(query->getType()))
+ .arg(query->getType());
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_QUERY_DATA)
+ .arg(query->getType())
+ .arg(query->getBuffer().getLength())
+ .arg(query->toText());
+
switch (query->getType()) {
case DHCPV6_SOLICIT:
rsp = processSolicit(query);
break;
+
case DHCPV6_REQUEST:
rsp = processRequest(query);
break;
+
case DHCPV6_RENEW:
rsp = processRenew(query);
break;
+
case DHCPV6_REBIND:
rsp = processRebind(query);
break;
+
case DHCPV6_CONFIRM:
rsp = processConfirm(query);
break;
+
case DHCPV6_RELEASE:
rsp = processRelease(query);
break;
+
case DHCPV6_DECLINE:
rsp = processDecline(query);
break;
+
case DHCPV6_INFORMATION_REQUEST:
rsp = processInfRequest(query);
break;
+
default:
- cout << "Unknown pkt type received:"
- << query->getType() << endl;
+ // Only action is to output a message if debug is enabled,
+ // and that will be covered by the debug statement before
+ // the "switch" statement.
+ ;
}
- cout << "Received " << query->getBuffer().getLength() << " bytes packet type="
- << query->getType() << endl;
- cout << query->toText();
if (rsp) {
rsp->setRemoteAddr(query->getRemoteAddr());
rsp->setLocalAddr(query->getLocalAddr());
@@ -132,14 +148,16 @@ bool Dhcpv6Srv::run() {
rsp->setLocalPort(DHCP6_SERVER_PORT);
rsp->setIndex(query->getIndex());
rsp->setIface(query->getIface());
- cout << "Replying with:" << rsp->getType() << endl;
- cout << rsp->toText();
- cout << "----" << endl;
- if (!rsp->pack()) {
- cout << "Failed to assemble response packet." << endl;
- continue;
+
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA,
+ DHCP6_RESPONSE_DATA)
+ .arg(rsp->getType()).arg(rsp->toText());
+
+ if (rsp->pack()) {
+ IfaceMgr::instance().send(rsp);
+ } else {
+ LOG_ERROR(dhcp6_logger, DHCP6_PACK_FAIL);
}
- IfaceMgr::instance().send(rsp);
}
}
@@ -350,3 +368,46 @@ Pkt6Ptr Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, infRequest->getTransid()));
return reply;
}
+
+const char*
+Dhcpv6Srv::serverReceivedPacketName(uint8_t type) {
+ static const char* CONFIRM = "CONFIRM";
+ static const char* DECLINE = "DECLINE";
+ static const char* INFORMATION_REQUEST = "INFORMATION_REQUEST";
+ static const char* REBIND = "REBIND";
+ static const char* RELEASE = "RELEASE";
+ static const char* RENEW = "RENEW";
+ static const char* REQUEST = "REQUEST";
+ static const char* SOLICIT = "SOLICIT";
+ static const char* UNKNOWN = "UNKNOWN";
+
+ switch (type) {
+ case DHCPV6_CONFIRM:
+ return (CONFIRM);
+
+ case DHCPV6_DECLINE:
+ return (DECLINE);
+
+ case DHCPV6_INFORMATION_REQUEST:
+ return (INFORMATION_REQUEST);
+
+ case DHCPV6_REBIND:
+ return (REBIND);
+
+ case DHCPV6_RELEASE:
+ return (RELEASE);
+
+ case DHCPV6_RENEW:
+ return (RENEW);
+
+ case DHCPV6_REQUEST:
+ return (REQUEST);
+
+ case DHCPV6_SOLICIT:
+ return (SOLICIT);
+
+ default:
+ ;
+ }
+ return (UNKNOWN);
+}
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index 9d1bf19..1cb3236 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -69,6 +69,24 @@ public:
/// @brief Instructs the server to shut down.
void shutdown();
+
+ /// @brief Return textual type of packet received by server
+ ///
+ /// Returns the name of valid packet received by the server (e.g. SOLICIT).
+ /// If the packet is unknown - or if it is a valid DHCP packet but not one
+ /// expected to be received by the server (such as an ADVERTISE), the string
+ /// "UNKNOWN" is returned. This method is used in debug messages.
+ ///
+ /// As the operation of the method does not depend on any server state, it
+ /// is declared static.
+ ///
+ /// @param type DHCPv4 packet type
+ ///
+ /// @return Pointer to "const" string containing the packet name.
+ /// Note that this string is statically allocated and MUST NOT
+ /// be freed by the caller.
+ static const char* serverReceivedPacketName(uint8_t type);
+
protected:
/// @brief Processes incoming SOLICIT and returns response.
///
diff --git a/src/bin/dhcp6/main.cc b/src/bin/dhcp6/main.cc
index aebee90..8eaf60c 100644
--- a/src/bin/dhcp6/main.cc
+++ b/src/bin/dhcp6/main.cc
@@ -14,13 +14,15 @@
#include <config.h>
#include <iostream>
-#include <log/dummylog.h>
-#include <log/logger_support.h>
-#include <dhcp6/ctrl_dhcp6_srv.h>
+
#include <boost/lexical_cast.hpp>
-using namespace std;
+#include <dhcp6/ctrl_dhcp6_srv.h>
+#include <dhcp6/dhcp6_log.h>
+#include <log/logger_support.h>
+
using namespace isc::dhcp;
+using namespace std;
/// This file contains entry point (main() function) for standard DHCPv6 server
/// component for BIND10 framework. It parses command-line arguments and
@@ -37,11 +39,10 @@ const char* const DHCP6_NAME = "b10-dhcp6";
void
usage() {
- cerr << "Usage: b10-dhcp6 [-v]"
- << endl;
- cerr << "\t-v: verbose output" << endl;
- cerr << "\t-s: stand-alone mode (don't connect to BIND10)" << endl;
- cerr << "\t-p number: specify non-standard port number 1-65535 "
+ cerr << "Usage: " << DHCP6_NAME << " [-v] [-s] [-p number]" << endl;
+ cerr << " -v: verbose output" << endl;
+ cerr << " -s: stand-alone mode (don't connect to BIND10)" << endl;
+ cerr << " -p number: specify non-standard port number 1-65535 "
<< "(useful for testing only)" << endl;
exit(EXIT_FAILURE);
}
@@ -52,18 +53,19 @@ main(int argc, char* argv[]) {
int ch;
int port_number = DHCP6_SERVER_PORT; // The default. Any other values are
// useful for testing only.
+ bool stand_alone = false; // Should be connect to BIND10 msgq?
bool verbose_mode = false; // Should server be verbose?
- bool stand_alone = false; // should be connect to BIND10 msgq?
while ((ch = getopt(argc, argv, "vsp:")) != -1) {
switch (ch) {
case 'v':
verbose_mode = true;
- isc::log::denabled = true;
break;
+
case 's':
stand_alone = true;
break;
+
case 'p':
try {
port_number = boost::lexical_cast<int>(optarg);
@@ -78,51 +80,45 @@ main(int argc, char* argv[]) {
usage();
}
break;
- case ':':
+
default:
usage();
}
}
+ // Check for extraneous parameters.
+ if (argc > optind) {
+ usage();
+ }
+
// 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")
- << ", stand-alone=" << (stand_alone?"yes":"no") << endl;
-
- if (argc - optind > 0) {
- usage();
- }
+ LOG_INFO(dhcp6_logger, DHCP6_STARTING);
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_START_INFO)
+ .arg(getpid()).arg(port_number).arg(verbose_mode ? "yes" : "no")
+ .arg(stand_alone ? "yes" : "no" );
int ret = EXIT_SUCCESS;
-
try {
-
- cout << "b10-dhcp6: Initiating DHCPv6 server operation." << endl;
-
- /// @todo: pass verbose to the actual server once logging is implemented
ControlledDhcpv6Srv server(port_number);
-
if (!stand_alone) {
try {
server.establishSession();
} catch (const std::exception& ex) {
- cerr << "Failed to establish BIND10 session. "
- "Running in stand-alone mode:" << ex.what() << endl;
+ LOG_ERROR(dhcp6_logger, DHCP6_SESSION_FAIL).arg(ex.what());
// Let's continue. It is useful to have the ability to run
// DHCP server in stand-alone mode, e.g. for testing
}
} else {
- cout << "Skipping connection to the BIND10 msgq." << endl;
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_STANDALONE);
}
-
server.run();
+ LOG_INFO(dhcp6_logger, DHCP6_SHUTDOWN);
} catch (const std::exception& ex) {
- cerr << "[b10-dhcp6] Server failed: " << ex.what() << endl;
+ LOG_FATAL(dhcp6_logger, DHCP6_SERVER_FAILED).arg(ex.what());
ret = EXIT_FAILURE;
}
diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am
index 66dc252..97d2d08 100644
--- a/src/bin/dhcp6/tests/Makefile.am
+++ b/src/bin/dhcp6/tests/Makefile.am
@@ -42,10 +42,13 @@ if HAVE_GTEST
TESTS += dhcp6_unittests
-dhcp6_unittests_SOURCES = ../dhcp6_srv.h ../dhcp6_srv.cc ../ctrl_dhcp6_srv.cc
-dhcp6_unittests_SOURCES += dhcp6_unittests.cc
+dhcp6_unittests_SOURCES = dhcp6_unittests.cc
dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES += ctrl_dhcp6_srv_unittest.cc
+dhcp6_unittests_SOURCES += ../dhcp6_srv.h ../dhcp6_srv.cc
+dhcp6_unittests_SOURCES += ../dhcp6_log.h ../dhcp6_log.cc
+dhcp6_unittests_SOURCES += ../dhcp6_messages.h ../dhcp6_messages.cc
+dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index 5e98e18..2028706 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-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
@@ -223,4 +223,49 @@ TEST_F(Dhcpv6SrvTest, Solicit_basic) {
// more checks to be implemented
}
+TEST_F(Dhcpv6SrvTest, serverReceivedPacketName) {
+ // Check all possible packet types
+ for (int itype = 0; itype < 256; ++itype) {
+ uint8_t type = itype;
+
+ switch (type) {
+ case DHCPV6_CONFIRM:
+ EXPECT_STREQ("CONFIRM", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_DECLINE:
+ EXPECT_STREQ("DECLINE", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_INFORMATION_REQUEST:
+ EXPECT_STREQ("INFORMATION_REQUEST",
+ Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_REBIND:
+ EXPECT_STREQ("REBIND", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_RELEASE:
+ EXPECT_STREQ("RELEASE", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_RENEW:
+ EXPECT_STREQ("RENEW", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_REQUEST:
+ EXPECT_STREQ("REQUEST", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ case DHCPV6_SOLICIT:
+ EXPECT_STREQ("SOLICIT", Dhcpv6Srv::serverReceivedPacketName(type));
+ break;
+
+ default:
+ EXPECT_STREQ("UNKNOWN", Dhcpv6Srv::serverReceivedPacketName(type));
+ }
+ }
}
+
+} // end of anonymous namespace
diff --git a/src/bin/dhcp6/tests/dhcp6_test.py b/src/bin/dhcp6/tests/dhcp6_test.py
index 399c370..f3099b9 100644
--- a/src/bin/dhcp6/tests/dhcp6_test.py
+++ b/src/bin/dhcp6/tests/dhcp6_test.py
@@ -27,16 +27,27 @@ import fcntl
class TestDhcpv6Daemon(unittest.TestCase):
def setUp(self):
- # don't redirect stdout/stderr here as we want to print out things
+ # Don't redirect stdout/stderr here as we want to print out things
# during the test
- pass
+ #
+ # However, we do want to set the logging lock directory to somewhere
+ # to which we can write - use the current working directory. We then
+ # set the appropriate environment variable. os.putenv() may be not
+ # supported on some platforms as suggested in
+ # http://docs.python.org/release/3.2/library/os.html?highlight=putenv#os.environ:
+ # "If the platform supports the putenv() function...". It was checked
+ # that it does not work on Ubuntu. To overcome this problem we access
+ # os.environ directly.
+ lockdir_envvar = "B10_LOCKFILE_DIR_FROM_BUILD"
+ if lockdir_envvar not in os.environ:
+ os.environ[lockdir_envvar] = os.getcwd()
def tearDown(self):
pass
def runCommand(self, params, wait=1):
"""
- This method runs a command and returns a touple: (returncode, stdout, stderr)
+ This method runs a command and returns a tuple: (returncode, stdout, stderr)
"""
## @todo: Convert this into generic method and reuse it in dhcp4 and dhcp6
@@ -79,9 +90,9 @@ class TestDhcpv6Daemon(unittest.TestCase):
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
# There's potential problem if b10-dhcp4 prints out more
- # than 4k of text
+ # than 16k of text
try:
- output = os.read(self.stdout_pipes[0], 4096)
+ output = os.read(self.stdout_pipes[0], 16384)
except OSError:
print("No data available from stdout")
output = ""
@@ -91,7 +102,7 @@ class TestDhcpv6Daemon(unittest.TestCase):
output = ""
try:
- error = os.read(self.stderr_pipes[0], 4096)
+ error = os.read(self.stderr_pipes[0], 16384)
except OSError:
print("No data available on stderr")
error = ""
@@ -130,8 +141,8 @@ class TestDhcpv6Daemon(unittest.TestCase):
print("Note: Purpose of some of the tests is to check if DHCPv6 server can be started,")
print(" not that is can bind sockets correctly. Please ignore binding errors.")
(returncode, output, error) = self.runCommand(["../b10-dhcp6", "-v"])
-
- self.assertEqual( str(output).count("b10-dhcp6: Initiating DHCPv6 server operation."), 1)
+ output_text = str(output) + str(error)
+ self.assertEqual(output_text.count("DHCP6_STARTING"), 1)
def test_portnumber_0(self):
print("Check that specifying port number 0 is not allowed.")
@@ -180,27 +191,19 @@ class TestDhcpv6Daemon(unittest.TestCase):
def test_portnumber_nonroot(self):
print("Check that specifying unprivileged port number will work.")
- (returncode, output, error) = self.runCommand(['../b10-dhcp6', '-s', '-p', '10547'])
-
- # When invalid port number is specified, return code must not be success
- # TODO: Temporarily commented out as socket binding on systems that do not have
- # interface detection implemented currently fails.
- # self.assertTrue(returncode == 0)
-
- self.assertEqual( str(output).count("opening sockets on port 10547"), 1)
+ # Check that there is a message about running with an unprivileged port
+ (returncode, output, error) = self.runCommand(['../b10-dhcp6', '-v', '-s', '-p', '10547'])
+ output_text = str(output) + str(error)
+ self.assertEqual(output_text.count("DHCP6_OPEN_SOCKET opening sockets on port 10547"), 1)
def test_skip_msgq(self):
print("Check that connection to BIND10 msgq can be disabled.")
- (returncode, output, error) = self.runCommand(['../b10-dhcp6', '-s', '-p', '10547'])
-
- # When invalid port number is specified, return code must not be success
- # TODO: Temporarily commented out as socket binding on systems that do not have
- # interface detection implemented currently fails.
- # self.assertTrue(returncode == 0)
-
- self.assertEqual( str(output).count("Skipping connection to the BIND10 msgq."), 1)
-
+ # Check that the system outputs a message on one of its streams about running
+ # standalone.
+ (returncode, output, error) = self.runCommand(['../b10-dhcp6', '-v', '-s', '-p', '10547'])
+ output_text = str(output) + str(error)
+ self.assertEqual(output_text.count("DHCP6_STANDALONE"), 1)
if __name__ == '__main__':
unittest.main()
More information about the bind10-changes
mailing list