|
@@ -0,0 +1,159 @@
|
|
|
|
+// 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);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+};
|
|
|
|
+};
|