Commit 7e11527e authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[4277] Pull 4275 changes

    Merge branch 'master' into trac4277
parents 33428957 f15c1a11
1132. [func] tmark
The Postgresql schema has been updated to support host reservations and its
version number has been bumped to 3.0. This schema is content equivlent to
the MySQL schema version 4.2.
(Trac #4275, git 6f8e646bee9de22c921ed26409f3d1856ebce9e6)
1131. [func] fdupont
Update the DHCPv4-over-DHCPv6 inter-process communication code.
(Trac #4106, git 1ce1cba00af5d81822d5bbe26ddd28b718f51d54)
1130. [func] marcin
DHCPv6 server assigns DHCP options specified for hosts. Host
specific options take precedence over class specific options,
......
......@@ -1485,6 +1485,7 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/share/database/scripts/mysql/upgrade_4.0_to_4.1.sh
src/share/database/scripts/pgsql/Makefile
src/share/database/scripts/pgsql/upgrade_1.0_to_2.0.sh
src/share/database/scripts/pgsql/upgrade_2.0_to_3.0.sh
tools/Makefile
tools/path_replacer.sh
])
......
address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,state
12,21,30,<timestamp3>,40,50,IA_TA,60,70,1,1,three.example.com,expired-reclaimed
11,,30,<timestamp2>,40,50,IA_TA,60,70,1,1,,declined
10,20,30,<timestamp1>,40,50,IA_TA,60,70,1,1,one.example.com,default
address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,state,hwaddr,hwtype,hwaddr_source
10,20,30,<timestamp1>,40,50,IA_TA,60,70,1,1,one.example.com,default,80,90,HWADDR_SOURCE_REMOTE_ID
11,,30,<timestamp2>,40,50,IA_TA,60,70,1,1,,declined,80,90,HWADDR_SOURCE_RAW
12,21,30,<timestamp3>,40,50,IA_TA,60,70,1,1,three.example.com,expired-reclaimed,80,90,HWADDR_SOURCE_DUID
......@@ -88,7 +88,7 @@ pgsql_lease_version_test() {
# Verfiy that kea-admin lease-version returns the correct version
version=$(${keaadmin} lease-version pgsql -u $db_user -p $db_password -n $db_name)
assert_str_eq "2.0" ${version} "Expected kea-admin to return %s, returned value was %s"
assert_str_eq "3.0" ${version} "Expected kea-admin to return %s, returned value was %s"
# Let's wipe the whole database
pgsql_wipe
......@@ -96,30 +96,18 @@ pgsql_lease_version_test() {
test_finish 0
}
pgsql_upgrade_test() {
test_start "pgsql.upgrade-test"
# Wipe the whole database
pgsql_wipe
# Initialize database to schema 1.0.
pgsql_execute_script @abs_top_srcdir@/src/bin/admin/tests/dhcpdb_create_1.0.pgsql
assert_eq 0 $? "cannot initialize the database, expected exit code: %d, actual: %d"
${keaadmin} lease-upgrade pgsql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir
assert_eq 0 $? "lease-upgrade failed, expected exit code: %d, actual: %d"
#table: state column added to lease4 (upgrade 1.0 -> 2.0)
output=`pgsql_execute "SELECT state from lease4;"`
pgsql_upgrade_1_0_to_2_0() {
# Added state column to lease4
output=`pgsql_execute "select state from lease4;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "lease4 is missing state column. (returned status code %d, expected %d)"
#table: state column added to lease6 (upgrade 1.0 -> 2.0)
output=`pgsql_execute "SELECT state from lease6;"`
# Added state column to lease6
output=`pgsql_execute "select state from lease6;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "lease6 is missing state column. (returned status code %d, expected %d)"
#table: stored procedures for lease dumps added (upgrade 1.0 -> 2.0)
# Added stored procedures for lease dumps
output=`pgsql_execute "select lease4DumpHeader from lease4DumpHeader();"`
assert_eq 0 $ERRCODE "function lease4DumpHeader() broken or missing. (returned status code %d, expected %d)"
......@@ -131,6 +119,107 @@ pgsql_upgrade_test() {
output=`pgsql_execute "select address from lease6DumpData();"`
assert_eq 0 $ERRCODE "function lease6DumpData() broken or missing. (returned status code %d, expected %d)"
}
pgsql_upgrade_2_0_to_3_0() {
# Added hwaddr, hwtype, and hwaddr_source columns to lease6 table
output=`pgsql_execute "select hwaddr, hwtype, hwaddr_source from lease6;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "lease6 table not upgraded to 3.0 (returned status code %d, expected %d)"
# Added lease_hwaddr_source table
output=`pgsql_execute "select hwaddr_source, name from lease_hwaddr_source;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "lease_hwaddr_source table is missing or broken. (returned status code %d, expected %d)"
# Added hosts table
output=`pgsql_execute "select host_id, dhcp_identifier, dhcp_identifier_type, dhcp4_subnet_id, dhcp6_subnet_id, ipv4_address, hostname, dhcp4_client_classes, dhcp6_client_classes from hosts;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "hosts table is missing or broken. (returned status code %d, expected %d)"
# Added ipv6_reservations table
output=`pgsql_execute "select reservation_id, address, prefix_len, type, dhcp6_iaid, host_id from ipv6_reservations;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "ipv6_reservations table is missing or broken. (returned status code %d, expected %d)"
# Added dhcp4_options table
output=`pgsql_execute "select option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp4_subnet_id, host_id, scope_id from dhcp4_options;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "dhcp4_options table is missing or broken. (returned status code %d, expected %d)"
# Added dhcp6_options table
output=`pgsql_execute "select option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp6_subnet_id, host_id,scope_id from dhcp6_options;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "dhcp6_options table is missing or broken. (returned status code %d, expected %d)"
# Added host_identifier_type table
output=`pgsql_execute "select type, name from host_identifier_type;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "host_identifier_type table is missing or broken. (returned status code %d, expected %d)"
# Added dhcp_option_scope table
output=`pgsql_execute "select scope_id, scope_name from dhcp_option_scope;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "dhcp_option_scope table is missing or broken. (returned status code %d, expected %d)"
# Added dhcp6_options table
output=`pgsql_execute "select option_id, code, value, formatted_value, space, persistent, dhcp_client_class, dhcp6_subnet_id, host_id,scope_id from dhcp6_options;"`
ERRCODE=$?
assert_eq 0 $ERRCODE "dhcp6_options table is missing or broken. (returned status code %d, expected %d)"
# Added order by clause to lease4DumpData
output=`pgsql_execute "select address from lease4DumpData();"`
assert_eq 0 $ERRCODE "function lease4DumpData() broken or missing. (returned status code %d, expected %d)"
output=`pgsql_execute "\sf lease4DumpData"`
assert_eq 0 $ERRCODE "\sf of lease4DumpData failed. (returned status code %d, expected %d)"
count=`echo $output | grep -ic "order by l\.address"`
assert_eq 1 $count "lease4DumpData is missing order by clause"
# Added hwaddr columns to lease6DumpHeader
output=`pgsql_execute "select lease6DumpHeader from lease6DumpHeader();"`
assert_eq 0 $ERRCODE "function lease6DumpHeader() broken or missing. (returned status code %d, expected %d)"
count=`echo $output | grep -ic "hwaddr,hwtype,hwaddr_source"`
assert_eq 1 $count "lease6DumpHeader is missing hwaddr columns"
# Added hwaddr columns to lease6DumpData
output=`pgsql_execute "select hwaddr,hwttype,hwaddr_source from lease6DumpData();"`
assert_eq 0 $ERRCODE "function lease6DumpData() broken or missing. (returned status code %d, expected %d)"
# Added order by clause to lease6DumpData
output=`pgsql_execute "\sf lease4DumpData"`
assert_eq 0 $ERRCODE "\sf of lease4DumpData failed. (returned status code %d, expected %d)"
count=`echo $output | grep -ic "order by l\.address"`
assert_eq 1 $count "lease4DumpData is missing order by clause"
# lease_hardware_source should have row for source = 0
output=`pgsql_execute "select count(hwaddr_source) from lease_hwaddr_source where hwaddr_source = 0 and name='HWADDR_SOURCE_UNKNOWN';"`
ERRCODE=$?
assert_eq 0 $ERRCODE "select from lease_hwaddr_source failed. (returned status code %d, expected %d)"
assert_eq 1 "$output" "lease_hwaddr_source does not contain entry for HWADDR_SOURCE_UKNOWN. (record count %d, expected %d)"
# Verify upgraded schemd reports version 3.0.
version=$(${keaadmin} lease-version pgsql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir)
assert_str_eq "3.0" ${version} "Expected kea-admin to return %s, returned value was %s"
}
pgsql_upgrade_test() {
test_start "pgsql.upgrade-test"
# Wipe the whole database
pgsql_wipe
# Initialize database to schema 1.0.
pgsql_execute_script @abs_top_srcdir@/src/bin/admin/tests/dhcpdb_create_1.0.pgsql
assert_eq 0 $? "cannot initialize the database, expected exit code: %d, actual: %d"
${keaadmin} lease-upgrade pgsql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir
assert_eq 0 $? "lease-upgrade failed, expected exit code: %d, actual: %d"
# Check 1.0 to 2.0 upgrade
pgsql_upgrade_1_0_to_2_0
# Check 2.0 to 3.0 upgrade
pgsql_upgrade_2_0_to_3_0
# Let's wipe the whole database
pgsql_wipe
......@@ -145,7 +234,7 @@ get_local_time() {
# Expiration field is a "timestamp with timezone" so we need a reference
# time for the machine/DB this test is running upon.
ref_timestamp=`pgsql_execute "SELECT timestamptz '$1';"`
ref_timestamp=`pgsql_execute "select timestamptz '$1';"`
ERRCODE=$?
assert_eq 0 $ERRCODE "reference time query failed for [$timestamp], expected exit code %d, actual %d"
echo $ref_timestamp
......@@ -297,9 +386,9 @@ pgsql_lease6_dump_test() {
# Insert the reference records
insert_sql="\
insert into lease6 values(10,E'\\x20',30,'$timestamp1',40,50,1,60,70,'t','t','one.example.com', 0);\
insert into lease6 values(11,'',30,'$timestamp2',40,50,1,60,70,'t','t','', 1);\
insert into lease6 values(12,E'\\x21',30,'$timestamp3',40,50,1,60,70,'t','t','three.example.com', 2);"
insert into lease6 values(10,E'\\x20',30,'$timestamp1',40,50,1,60,70,'t','t','one.example.com', 0,decode('80','hex'),90,16);\
insert into lease6 values(11,'',30,'$timestamp2',40,50,1,60,70,'t','t','', 1,decode('80','hex'),90,1);\
insert into lease6 values(12,E'\\x21',30,'$timestamp3',40,50,1,60,70,'t','t','three.example.com', 2,decode('80','hex'),90,4);"
pgsql_execute "$insert_sql"
ERRCODE=$?
......
......@@ -62,7 +62,7 @@ libdhcp4_la_SOURCES += ctrl_dhcp4_srv.cc ctrl_dhcp4_srv.h
libdhcp4_la_SOURCES += json_config_parser.cc json_config_parser.h
libdhcp4_la_SOURCES += dhcp4_log.cc dhcp4_log.h
libdhcp4_la_SOURCES += dhcp4_srv.cc dhcp4_srv.h
libdhcp4_la_SOURCES += dhcp4_dhcp4o6_ipc.cc dhcp4_dhcp4o6_ipc.h
libdhcp4_la_SOURCES += dhcp4to6_ipc.cc dhcp4to6_ipc.h
libdhcp4_la_SOURCES += kea_controller.cc
......
......@@ -8,7 +8,7 @@
#include <cc/data.h>
#include <dhcp4/ctrl_dhcp4_srv.h>
#include <dhcp4/dhcp4_log.h>
#include <dhcp4/dhcp4_dhcp4o6_ipc.h>
#include <dhcp4/dhcp4to6_ipc.h>
#include <hooks/hooks_manager.h>
#include <dhcp4/json_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
......@@ -192,7 +192,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
// Setup DHCPv4-over-DHCPv6 IPC
try {
Dhcp4o6Ipc::instance().open();
Dhcp4to6Ipc::instance().open();
} catch (const std::exception& ex) {
std::ostringstream err;
err << "error starting DHCPv4-over-DHCPv6 IPC "
......
// Copyright (C) 2015-2016 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.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <util/buffer.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp4/dhcp4_dhcp4o6_ipc.h>
#include <dhcp4/dhcp4to6_ipc.h>
using namespace std;
namespace isc {
namespace dhcp {
Dhcp4o6Ipc::Dhcp4o6Ipc() : Dhcp4o6IpcBase() {}
Dhcp4to6Ipc::Dhcp4to6Ipc() : Dhcp4o6IpcBase() {}
Dhcp4o6Ipc& Dhcp4o6Ipc::instance() {
static Dhcp4o6Ipc dhcp4o6_ipc;
return (dhcp4o6_ipc);
Dhcp4to6Ipc& Dhcp4to6Ipc::instance() {
static Dhcp4to6Ipc dhcp4to6_ipc;
return (dhcp4to6_ipc);
}
void Dhcp4o6Ipc::open() {
void Dhcp4to6Ipc::open() {
uint32_t port = CfgMgr::instance().getStagingCfg()->getDhcp4o6Port();
if (port == 0) {
Dhcp4o6IpcBase::close();
......@@ -42,31 +34,48 @@ void Dhcp4o6Ipc::open() {
}
int old_fd = socket_fd_;
socket_fd_ = Dhcp4o6IpcBase::open(static_cast<uint16_t>(port), 4);
socket_fd_ = Dhcp4o6IpcBase::open(static_cast<uint16_t>(port),
ENDPOINT_TYPE_V4);
if ((old_fd == -1) && (socket_fd_ != old_fd)) {
IfaceMgr::instance().addExternalSocket(socket_fd_, Dhcp4o6Ipc::handler);
IfaceMgr::instance().addExternalSocket(socket_fd_,
Dhcp4to6Ipc::handler);
}
}
void Dhcp4o6Ipc::handler() {
Dhcp4o6Ipc& ipc = Dhcp4o6Ipc::instance();
void Dhcp4to6Ipc::handler() {
Dhcp4to6Ipc& ipc = Dhcp4to6Ipc::instance();
// Reset received message in case we return from this method before the
// received message pointer is updated.
ipc.received_.reset();
// Receive message from the IPC socket.
Pkt6Ptr pkt = ipc.receive();
if (!pkt) {
return;
}
// Each message must contain option holding DHCPv4 message.
OptionCollection msgs = pkt->getOptions(D6O_DHCPV4_MSG);
if (msgs.size() != 1) {
return;
if (msgs.empty()) {
isc_throw(Dhcp4o6IpcError, "DHCPv4 message option not present in the"
" DHCPv4o6 message received by the DHCPv4 server");
} else if (msgs.size() > 1) {
isc_throw(Dhcp4o6IpcError, "expected exactly one DHCPv4 message within"
" DHCPv4 message option received by the DHCPv4 server");
}
OptionPtr msg = pkt->getOption(D6O_DHCPV4_MSG);
OptionPtr msg = msgs.begin()->second;
if (!msg) {
isc_throw(Unexpected, "Can't get DHCPv4 message option");
isc_throw(Dhcp4o6IpcError, "null DHCPv4 message option in the"
" DHCPv4o6 message received by the DHCPv4 server");
}
instance().received_.reset(new Pkt4o6(msg->getData(), pkt));
// Record this message.
ipc.received_.reset(new Pkt4o6(msg->getData(), pkt));
}
Pkt4o6Ptr& Dhcp4o6Ipc::getReceived() {
Pkt4o6Ptr& Dhcp4to6Ipc::getReceived() {
return (received_);
}
......
// Copyright (C) 2015-2016 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.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef DHCP4_DHCP4O6_IPC_H
#define DHCP4_DHCP4O6_IPC_H
#ifndef DHCP4TO6_IPC_H
#define DHCP4TO6_IPC_H
/// @file dhcp4_dhcp4o6_ipc.h Defines the Dhcp4o6Ipc class.
/// @file dhcp4to6_ipc.h Defines the Dhcp4o6Ipc class.
/// This file defines the class Kea uses to act as the DHCPv4 server
/// side of DHCPv4-over-DHCPv6 communication between servers.
///
......@@ -28,23 +20,23 @@ namespace isc {
namespace dhcp {
/// @brief Handles DHCPv4-over-DHCPv6 IPC on the DHCPv4 server side
class Dhcp4o6Ipc : public Dhcp4o6IpcBase {
class Dhcp4to6Ipc : public Dhcp4o6IpcBase {
protected:
/// @brief Constructor
///
/// Default constructor
Dhcp4o6Ipc();
Dhcp4to6Ipc();
/// @brief Destructor.
virtual ~Dhcp4o6Ipc() { }
virtual ~Dhcp4to6Ipc() { }
public:
/// @brief Returns pointer to the sole instance of Dhcp4o6Ipc
/// @brief Returns pointer to the sole instance of Dhcp4to6Ipc
///
/// Dhcp4o6Ipc is a singleton class
/// Dhcp4to6Ipc is a singleton class
///
/// @return the only existing instance of DHCP4o6 IPC
static Dhcp4o6Ipc& instance();
static Dhcp4to6Ipc& instance();
/// @brief Open communication socket
///
......
......@@ -94,6 +94,7 @@ dhcp4_unittests_SOURCES += release_unittest.cc
dhcp4_unittests_SOURCES += out_of_range_unittest.cc
dhcp4_unittests_SOURCES += decline_unittest.cc
dhcp4_unittests_SOURCES += kea_controller_unittest.cc
dhcp4_unittests_SOURCES += dhcp4to6_ipc_unittest.cc
nodist_dhcp4_unittests_SOURCES = marker_file.h test_libraries.h
......
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcp/pkt4o6.h>
#include <dhcp/pkt6.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp4/dhcp4to6_ipc.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/testutils/dhcp4o6_test_ipc.h>
#include <gtest/gtest.h>
#include <stdint.h>
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace isc::util;
namespace {
/// @brief Port number used in tests.
const uint16_t TEST_PORT = 32000;
/// @brief Define short name for the test IPC.
typedef Dhcp4o6TestIpc TestIpc;
/// @brief Test fixture class for DHCPv4 endpoint of DHCPv4o6 IPC.
class Dhcp4to6IpcTest : public ::testing::Test {
public:
/// @brief Constructor
///
/// Configures IPC to use a test port. It also provides a fake
/// configuration of interfaces.
Dhcp4to6IpcTest()
: iface_mgr_test_config_(true) {
configurePort(TEST_PORT);
}
/// @brief Configure DHCP4o6 port.
///
/// @param port New port.
void configurePort(uint16_t port);
/// @brief Creates an instance of the DHCPv4o6 Message option.
///
/// The option will contain an empty DHCPREQUEST message, with
/// just the Message Type option inside and nothing else.
///
/// @return Pointer to the instance of the DHCPv4-query Message option.
OptionPtr createDHCPv4MsgOption() const;
private:
/// @brief Provides fake configuration of interfaces.
IfaceMgrTestConfig iface_mgr_test_config_;
};
void
Dhcp4to6IpcTest::configurePort(uint16_t port) {
CfgMgr::instance().getStagingCfg()->setDhcp4o6Port(port);
}
OptionPtr
Dhcp4to6IpcTest::createDHCPv4MsgOption() const {
// Create the DHCPv4 message.
Pkt4Ptr pkt(new Pkt4(DHCPREQUEST, 1234));
// Make a wire representation of the DHCPv4 message.
pkt->pack();
OutputBuffer& output_buffer = pkt->getBuffer();
const uint8_t* data = static_cast<const uint8_t*>(output_buffer.getData());
OptionBuffer option_buffer(data, data + output_buffer.getLength());
// Create the DHCPv4 Message option holding the created message.
OptionPtr opt_msg(new Option(Option::V6, D6O_DHCPV4_MSG, option_buffer));
return (opt_msg);
}
// This test verifies that the IPC returns an error when trying to bind
// to the out of range port.
TEST_F(Dhcp4to6IpcTest, invalidPortError) {
// Create instance of the IPC endpoint under test with out-of-range port.
configurePort(65535);
Dhcp4to6Ipc& ipc = Dhcp4to6Ipc::instance();
EXPECT_THROW(ipc.open(), isc::OutOfRange);
}
// This test verifies that the DHCPv4 endpoint of the DHCPv4o6 IPC can
// receive messages.
TEST_F(Dhcp4to6IpcTest, receive) {
// Create instance of the IPC endpoint under test.
Dhcp4to6Ipc& ipc = Dhcp4to6Ipc::instance();
// Create instance of the IPC endpoint being used as a source of messages.
TestIpc src_ipc(TEST_PORT, TestIpc::ENDPOINT_TYPE_V6);
// Open both endpoints.
ASSERT_NO_THROW(ipc.open());
ASSERT_NO_THROW(src_ipc.open());
// Create message to be sent over IPC.
Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
pkt->addOption(createDHCPv4MsgOption());
pkt->setIface("eth0");
pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
ASSERT_NO_THROW(pkt->pack());
// Send and wait up to 1 second to receive it.
ASSERT_NO_THROW(src_ipc.send(pkt));
ASSERT_NO_THROW(IfaceMgr::instance().receive6(1, 0));
// Make sure that the message has been received.
Pkt4o6Ptr pkt_received = ipc.getReceived();
ASSERT_TRUE(pkt_received);
Pkt6Ptr pkt6_received = pkt_received->getPkt6();
ASSERT_TRUE(pkt6_received);
EXPECT_EQ("eth0", pkt6_received->getIface());
EXPECT_EQ("2001:db8:1::123", pkt6_received->getRemoteAddr().toText());
}
// This test verifies that message with multiple DHCPv4 query options
// is rejected.
TEST_F(Dhcp4to6IpcTest, receiveMultipleQueries) {
// Create instance of the IPC endpoint under test.
Dhcp4to6Ipc& ipc = Dhcp4to6Ipc::instance();
// Create instance of the IPC endpoint being used as a source of messages.
TestIpc src_ipc(TEST_PORT, TestIpc::ENDPOINT_TYPE_V6);
// Open both endpoints.
ASSERT_NO_THROW(ipc.open());
ASSERT_NO_THROW(src_ipc.open());
// Create message to be sent over IPC.
Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
// Add two DHCPv4 query options.
pkt->addOption(createDHCPv4MsgOption());
pkt->addOption(createDHCPv4MsgOption());
pkt->setIface("eth0");
pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
ASSERT_NO_THROW(pkt->pack());
// Send message.
ASSERT_NO_THROW(src_ipc.send(pkt));
// Reception handler should throw exception.
EXPECT_THROW(IfaceMgr::instance().receive6(1, 0), Dhcp4o6IpcError);
}
// This test verifies that message with no DHCPv4 query options is rejected.
TEST_F(Dhcp4to6IpcTest, receiveNoQueries) {
// Create instance of the IPC endpoint under test.
Dhcp4to6Ipc& ipc = Dhcp4to6Ipc::instance();
// Create instance of the IPC endpoint being used as a source of messages.
TestIpc src_ipc(TEST_PORT, TestIpc::ENDPOINT_TYPE_V6);
// Open both endpoints.
ASSERT_NO_THROW(ipc.open());
ASSERT_NO_THROW(src_ipc.open());
// Create message to be sent over IPC without DHCPv4 query option.
Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
pkt->setIface("eth0");
pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
ASSERT_NO_THROW(pkt->pack());
// Send message.
ASSERT_NO_THROW(src_ipc.send(pkt));
// Reception handler should throw exception.
EXPECT_THROW(IfaceMgr::instance().receive6(1, 0), Dhcp4o6IpcError);
}
} // end of anonymous namespace
......@@ -63,7 +63,7 @@ libdhcp6_la_SOURCES += dhcp6_log.cc dhcp6_log.h
libdhcp6_la_SOURCES += dhcp6_srv.cc dhcp6_srv.h
libdhcp6_la_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
libdhcp6_la_SOURCES += json_config_parser.cc json_config_parser.h
libdhcp6_la_SOURCES += dhcp6_dhcp4o6_ipc.cc dhcp6_dhcp4o6_ipc.h
libdhcp6_la_SOURCES += dhcp6to4_ipc.cc dhcp6to4_ipc.h
libdhcp6_la_SOURCES += kea_controller.cc
......
......@@ -11,7 +11,7 @@
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/cfg_db_access.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp6/dhcp6_dhcp4o6_ipc.h>
#include <dhcp6/dhcp6to4_ipc.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/json_config_parser.h>
#include <hooks/hooks_manager.h>
......@@ -216,7 +216,7 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
// Setup DHCPv4-over-DHCPv6 IPC
try {
Dhcp4o6Ipc::instance().open();
Dhcp6to4Ipc::instance().open();
} catch (const std::exception& ex) {
std::ostringstream err;
err << "error starting DHCPv4-over-DHCPv6 IPC "
......