2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 14:05:33 +00:00

[#1548] DDNS tuning hook removed

This commit is contained in:
Tomek Mrugalski
2022-03-14 13:49:23 +01:00
committed by Thomas Markwalder
parent 771e8bff20
commit d7fe847ce1
18 changed files with 1 additions and 1131 deletions

View File

@@ -1461,9 +1461,6 @@ AC_CONFIG_FILES([src/hooks/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/Makefile]) AC_CONFIG_FILES([src/hooks/dhcp/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/bootp/Makefile]) AC_CONFIG_FILES([src/hooks/dhcp/bootp/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/bootp/tests/Makefile]) AC_CONFIG_FILES([src/hooks/dhcp/bootp/tests/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/ddns_tuning/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/ddns_tuning/libloadtests/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/ddns_tuning/tests/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/flex_option/Makefile]) AC_CONFIG_FILES([src/hooks/dhcp/flex_option/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/flex_option/libloadtests/Makefile]) AC_CONFIG_FILES([src/hooks/dhcp/flex_option/libloadtests/Makefile])
AC_CONFIG_FILES([src/hooks/dhcp/flex_option/tests/Makefile]) AC_CONFIG_FILES([src/hooks/dhcp/flex_option/tests/Makefile])

View File

@@ -1,4 +1,4 @@
SUBDIRS = bootp ddns_tuning flex_option high_availability lease_cmds SUBDIRS = bootp flex_option high_availability lease_cmds
if HAVE_MYSQL if HAVE_MYSQL
SUBDIRS += mysql_cb SUBDIRS += mysql_cb

View File

@@ -1,88 +0,0 @@
SUBDIRS = . libloadtests tests
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CXXFLAGS = $(KEA_CXXFLAGS)
HOOK_NAME=ddns_tuning
# Ensure that the message file and doxygen file is included in the distribution
EXTRA_DIST = $(HOOK_NAME)_messages.mes
EXTRA_DIST += $(HOOK_NAME).dox
CLEANFILES = *.gcno *.gcda
# convenience archive
noinst_LTLIBRARIES = libddns_tuning.la
libddns_tuning_la_SOURCES = $(HOOK_NAME).cc $(HOOK_NAME).h
libddns_tuning_la_SOURCES += $(HOOK_NAME)_callouts.cc
libddns_tuning_la_SOURCES += $(HOOK_NAME)_log.cc $(HOOK_NAME)_log.h
libddns_tuning_la_SOURCES += $(HOOK_NAME)_messages.cc $(HOOK_NAME)_messages.h
libddns_tuning_la_SOURCES += version.cc
ddns_tuning_la_CXXFLAGS = $(AM_CXXFLAGS)
ddns_tuning_la_CPPFLAGS = $(AM_CPPFLAGS)
# install the shared object into $(libdir)/kea/hooks
lib_hooksdir = $(libdir)/kea/hooks
lib_hooks_LTLIBRARIES = libdhcp_ddns_tuning.la
libdhcp_ddns_tuning_la_SOURCES =
libdhcp_ddns_tuning_la_LDFLAGS = $(AM_LDFLAGS)
libdhcp_ddns_tuning_la_LDFLAGS += -avoid-version -export-dynamic -module
libdhcp_ddns_tuning_la_LIBADD = lib$(HOOK_NAME).la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/process/libkea-process.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/eval/libkea-eval.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/stats/libkea-stats.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/http/libkea-http.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
libdhcp_ddns_tuning_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
libdhcp_ddns_tuning_la_LIBADD += $(LOG4CPLUS_LIBS)
libdhcp_ddns_tuning_la_LIBADD += $(CRYPTO_LIBS)
libdhcp_ddns_tuning_la_LIBADD += $(BOOST_LIBS)
# If we want to get rid of all generated messages files, we need to use
# make maintainer-clean. The proper way to introduce custom commands for
# that operation is to define maintainer-clean-local target. However,
# make maintainer-clean also removes Makefile, so running configure script
# is required. To make it easy to rebuild messages without going through
# reconfigure, a new target messages-clean has been added.
maintainer-clean-local:
rm -f $(HOOK_NAME)_messages.h $(HOOK_NAME)_messages.cc
# To regenerate messages files, one can do:
#
# make messages-clean
# make messages
#
# This is needed only when a .mes file is modified.
messages-clean: maintainer-clean-local
if GENERATE_MESSAGES
# Define rule to build logging source files from message file
messages: $(HOOK_NAME)_messages.h $(HOOK_NAME)_messages.cc
@echo Message files regenerated
$(HOOK_NAME)_messages.h $(HOOK_NAME)_messages.cc: $(HOOK_NAME)_messages.mes
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/hooks/dhcp/$(HOOK_NAME)/$(HOOK_NAME)_messages.mes
else
messages $(HOOK_NAME)_messages.h $(HOOK_NAME)_messages.cc:
@echo Messages generation disabled. Configure with --enable-generate-messages to enable it.
endif

View File

@@ -1,53 +0,0 @@
// Copyright (C) 2022 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 <ddns_tuning.h>
#include <ddns_tuning_log.h>
#include <util/strutil.h>
#include <cc/simple_parser.h>
#include <dhcp/dhcp4.h>
#include <dhcp/libdhcp++.h>
#include <eval/eval_context.h>
using namespace isc;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::eval;
using namespace isc::log;
using namespace isc::util;
using namespace std;
namespace isc {
namespace ddns_tuning {
DdnsTuningImpl::DdnsTuningImpl() {
}
DdnsTuningImpl::~DdnsTuningImpl() {
}
void DdnsTuningImpl::configure(isc::data::ConstElementPtr params) {
if (!params) {
isc_throw(BadValue, "missing parameters");
}
ConstElementPtr hostname = params->get("hostname-expr");
if (!hostname) {
isc_throw(BadValue, "hostname-expr parameter missing");
}
if (hostname->getType() != Element::string) {
isc_throw(BadValue, "'hostname-expr' must e a string");
}
/// @todo: Parse expression
setText(hostname->str());
}
} // end of namespace ddns_tuning
} // end of namespace isc

View File

@@ -1,103 +0,0 @@
// Copyright (C) 2022 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/.
#ifndef DDNS_TUNING_H
#define DDNS_TUNING_H
#include <cc/data.h>
#include <dhcp/libdhcp++.h>
#include <dhcp/option.h>
#include <eval/evaluate.h>
#include <eval/token.h>
#include <util/strutil.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <map>
#include <string>
namespace isc {
namespace ddns_tuning {
/// @brief DDNS Tuning implementation.
///
/// The implementation can be divided into two parts:
/// - the configuration parsed and stored by load()
/// - the response packet processing performed by the process method
///
class DdnsTuningImpl {
public:
/// @brief Set textual expression.
///
/// @param text the textual expression.
void setText(const std::string& text) {
text_ = text;
};
/// @brief Get textual expression.
///
/// @return textual expression.
const std::string& getText() const {
return (text_);
}
/// @brief Set match expression.
///
/// @param expr the match expression.
void setExpr(const isc::dhcp::ExpressionPtr expr) {
expr_ = expr;
}
/// @brief Get match expression.
///
/// @return the match expression.
const isc::dhcp::ExpressionPtr& getExpr() const {
return (expr_);
}
/// @brief Constructor.
DdnsTuningImpl();
/// @brief Destructor.
~DdnsTuningImpl();
/// @brief Configure the Ddns Tuning implementation.
///
/// @param hostname The JSON element with the expression.
/// @throw BadValue and similar exceptions on error.
void configure(isc::data::ConstElementPtr hostname);
/// @brief Process a query / response pair.
///
/// @tparam PktType The type of pointers to packets: Pkt4Ptr or Pkt6Ptr.
/// @param universe The option universe: Option::V4 or Option::V6.
/// @param query The query packet.
/// @param response The response packet.
template <typename PktType>
void process(isc::dhcp::Option::Universe universe,
PktType query, PktType /*response*/) {
std::string value = isc::dhcp::evaluateString(*getExpr(), *query);
if (value.empty()) {
return;
}
}
private:
/// @brief The textual expression.
std::string text_;
/// @brief The match expression.
isc::dhcp::ExpressionPtr expr_;
};
/// @brief The type of shared pointers to DDNS Tuning implementations.
typedef boost::shared_ptr<DdnsTuningImpl> DdnsTuningImplPtr;
} // end of namespace ddns_tuning
} // end of namespace isc
#endif

View File

@@ -1,151 +0,0 @@
// Copyright (C) 2022 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 <ddns_tuning.h>
#include <ddns_tuning_log.h>
#include <cc/command_interpreter.h>
#include <hooks/hooks.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
namespace isc {
namespace ddns_tuning {
DdnsTuningImplPtr impl;
} // end of namespace ddns_tuning
} // end of namespace isc
using namespace isc;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::hooks;
using namespace isc::ddns_tuning;
// Functions accessed by the hooks framework use C linkage to avoid the name
// mangling that accompanies use of the C++ compiler as well as to avoid
// issues related to namespaces.
extern "C" {
/// @brief This callout is called at the "pkt4_send" hook.
///
/// It retrieves v4 query and response packets, and then adds, supersedes
/// or removes option values in the response according to expressions
/// evaluated on the query.
///
/// @param handle CalloutHandle.
///
/// @return 0 upon success, non-zero otherwise
int pkt4_send(CalloutHandle& handle) {
CalloutHandle::CalloutNextStep status = handle.getStatus();
if (status == CalloutHandle::NEXT_STEP_DROP) {
return (0);
}
// Sanity.
if (!impl) {
return (0);
}
// Get the parameters.
Pkt4Ptr query;
Pkt4Ptr response;
handle.getArgument("query4", query);
handle.getArgument("response4", response);
if (status == CalloutHandle::NEXT_STEP_SKIP) {
isc_throw(InvalidOperation, "packet pack already handled");
}
try {
impl->process<Pkt4Ptr>(Option::V4, query, response);
} catch (const std::exception& ex) {
LOG_ERROR(ddns_tuning_logger, DDNS_TUNING_PROCESS_ERROR)
.arg(query->getLabel())
.arg(ex.what());
}
return (0);
}
/// @brief This callout is called at the "pkt6_send" hook.
///
/// It retrieves v6 query and response packets, and then adds, supersedes
/// or removes option values in the response according to expressions
/// evaluated on the query.
///
/// @param handle CalloutHandle.
///
/// @return 0 upon success, non-zero otherwise
int pkt6_send(CalloutHandle& handle) {
CalloutHandle::CalloutNextStep status = handle.getStatus();
if (status == CalloutHandle::NEXT_STEP_DROP) {
return (0);
}
// Sanity.
if (!impl) {
return (0);
}
if (status == CalloutHandle::NEXT_STEP_SKIP) {
isc_throw(InvalidOperation, "packet pack already handled");
}
// Get the parameters.
Pkt6Ptr query;
Pkt6Ptr response;
handle.getArgument("query6", query);
handle.getArgument("response6", response);
try {
impl->process<Pkt6Ptr>(Option::V6, query, response);
} catch (const std::exception& ex) {
LOG_ERROR(ddns_tuning_logger, DDNS_TUNING_PROCESS_ERROR)
.arg(query->getLabel())
.arg(ex.what());
}
return (0);
}
/// @brief This function is called when the library is loaded.
///
/// @param handle library handle
/// @return 0 when initialization is successful, 1 otherwise
int load(LibraryHandle& handle) {
try {
impl.reset(new DdnsTuningImpl());
ConstElementPtr json = handle.getParameters();
impl->configure(json);
} catch (const std::exception& ex) {
LOG_ERROR(ddns_tuning_logger, DDNS_TUNING_LOAD_ERROR)
.arg(ex.what());
return (1);
}
return (0);
}
/// @brief This function is called when the library is unloaded.
///
/// @return always 0.
int unload() {
impl.reset();
LOG_INFO(ddns_tuning_logger, DDNS_TUNING_UNLOAD);
return (0);
}
/// @brief This function is called to retrieve the multi-threading compatibility.
///
/// @return 1 which means compatible with multi-threading.
int multi_threading_compatible() {
return (1);
}
} // end extern "C"

View File

@@ -1,17 +0,0 @@
// Copyright (C) 2022 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 <ddns_tuning_log.h>
namespace isc {
namespace ddns_tuning {
isc::log::Logger ddns_tuning_logger("ddns-tuning-hooks");
} // namespace ddns_tuning
} // namespace isc

View File

@@ -1,22 +0,0 @@
// Copyright (C) 2022 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/.
#ifndef DDNS_TUNING_LOG_H
#define DDNS_TUNING_LOG_H
#include <log/logger_support.h>
#include <log/macros.h>
#include <log/log_dbglevels.h>
#include <ddns_tuning_messages.h>
namespace isc {
namespace ddns_tuning {
extern isc::log::Logger ddns_tuning_logger;
} // end of namespace ddns_tuning
} // end of namespace isc
#endif

View File

@@ -1,16 +0,0 @@
# Copyright (C) 2022 Internet Systems Consortium, Inc. ("ISC")
% DDNS_TUNING_LOAD_ERROR loading Flex Option hooks library failed: %1
This error message indicates an error during loading the Flex Option
hooks library. The details of the error are provided as argument of
the log message.
% DDNS_TUNING_PROCESS_ERROR An error occurred processing query %1: %2
This error message indicates an error during processing of a query
by the Flex Option hooks library. The client identification information
from the query and the details of the error are provided as arguments
of the log message.
% DDNS_TUNING_UNLOAD Flex Option hooks library has been unloaded
This info message indicates that the Flex Option hooks library has been
unloaded.

View File

@@ -1,60 +0,0 @@
SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/ddns_tuning -I$(top_srcdir)/src/hooks/dhcp/ddns_tuning
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DDDNS_TUNING_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/ddns_tuning/.libs/libdhcp_ddns_tuning.so\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
# Unit test data files need to get installed.
EXTRA_DIST =
CLEANFILES = *.gcno *.gcda
# TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
LOG_COMPILER = $(LIBTOOL)
AM_LOG_FLAGS = --mode=execute
TESTS =
if HAVE_GTEST
TESTS += hook_unittests
hook_unittests_SOURCES = run_unittests.cc
hook_unittests_SOURCES += callout_unittests.cc
hook_unittests_SOURCES += load_unload_unittests.cc
ddns_tuning_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
ddns_tuning_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
ddns_tuning_unittests_CXXFLAGS = $(AM_CXXFLAGS)
ddns_tuning_unittests_LDADD = $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
ddns_tuning_unittests_LDADD += $(LOG4CPLUS_LIBS)
ddns_tuning_unittests_LDADD += $(CRYPTO_LIBS)
ddns_tuning_unittests_LDADD += $(BOOST_LIBS)
ddns_tuning_unittests_LDADD += $(GTEST_LDADD)
endif
noinst_PROGRAMS = $(TESTS)

View File

@@ -1,174 +0,0 @@
// Copyright (C) 2022 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/.
/// @file This file contains tests which exercise the pkt[46]_send callouis
/// called by the flexible option hook library. In order to test the callouts
/// one must be able to pass to the load function it hook library parameters
/// because the only way to populate these parameters is by actually loading
/// the library via HooksManager::loadLibraries().
#include <config.h>
#include <ddns_tuning.h>
#include <hooks/hooks.h>
#include <hooks/hooks_manager.h>
#include <hooks/callout_manager.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#include <dhcpsrv/cfgmgr.h>
#include <gtest/gtest.h>
#include <errno.h>
using namespace std;
using namespace isc;
using namespace isc::hooks;
using namespace isc::data;
using namespace isc::dhcp;
namespace {
/// @brief Structure that holds registered hook indexes.
struct TestHooks {
/// @brief Index of pkt4_send callout.
int hook_index_pkt4_send_;
/// @brief Index of pkt6_send callout.
int hook_index_pkt6_send_;
/// @brief Constructor
///
/// The constructor registers hook points for callout tests.
TestHooks() {
hook_index_pkt4_send_ = HooksManager::registerHook("pkt4_send");
hook_index_pkt6_send_ = HooksManager::registerHook("pkt6_send");
}
};
TestHooks testHooks;
/// @brief Test fixture for testing callouts called by the flex-option library
class CalloutTest : public ::testing::Test {
public:
/// @brief Constructor
CalloutTest() {
reset();
}
/// @brief Destructor
/// Removes files that may be left over from previous tests
virtual ~CalloutTest() {
reset();
}
/// @brief Removes files that may be left over from previous tests
virtual void reset() {
HooksManager::unloadLibraries();
}
void addLib(const std::string& lib, ConstElementPtr params) {
libraries_.push_back(make_pair(lib, params));
}
void loadLibs() {
EXPECT_TRUE(HooksManager::loadLibraries(libraries_));
}
void unloadLibs() {
EXPECT_NO_THROW(HooksManager::unloadLibraries());
}
HookLibsCollection libraries_;
};
// Simple test which exercises the pkt4_send callout.
TEST_F(CalloutTest, pkt4Send) {
// Prepare load() parameters.
ElementPtr params = Element::createMap();
ElementPtr options = Element::createList();
params->set("options", options);
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr code = Element::create(DHO_HOST_NAME);
option->set("code", code);
ElementPtr add = Element::create(string("'abc'"));
option->set("add", add);
// Load the library.
addLib(DDNS_TUNING_LIB_SO, params);
loadLibs();
// Prepare packets.
Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 12345));
Pkt4Ptr response(new Pkt4(DHCPOFFER, 12345));
EXPECT_FALSE(response->getOption(DHO_HOST_NAME));
// Get and setup the callout handle.
EXPECT_TRUE(HooksManager::calloutsPresent(testHooks.hook_index_pkt4_send_));
CalloutHandlePtr handle = HooksManager::createCalloutHandle();
handle->setArgument("query4", query);
handle->setArgument("response4", response);
// Execute the callout.
EXPECT_NO_THROW(HooksManager::callCallouts(testHooks.hook_index_pkt4_send_,
*handle));
EXPECT_EQ(0, handle->getStatus());
// Check the result.
OptionPtr opt = response->getOption(DHO_HOST_NAME);
ASSERT_TRUE(opt);
EXPECT_EQ(DHO_HOST_NAME, opt->getType());
const OptionBuffer& buffer = opt->getData();
ASSERT_EQ(3, buffer.size());
EXPECT_EQ(0, memcmp(&buffer[0], "abc", 3));
}
// Simple test which exercises the pkt6_send callout.
TEST_F(CalloutTest, pkt6Send) {
// Move to DHCPv6.
CfgMgr::instance().setFamily(AF_INET6);
// Prepare load() parameters.
ElementPtr params = Element::createMap();
ElementPtr options = Element::createList();
params->set("options", options);
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr code = Element::create(D6O_BOOTFILE_URL);
option->set("code", code);
ElementPtr supersede = Element::create(string("'abc'"));
option->set("supersede", supersede);
// Load the library.
addLib(DDNS_TUNING_LIB_SO, params);
loadLibs();
// Prepare packets.
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 12345));
Pkt6Ptr response(new Pkt6(DHCPV6_ADVERTISE, 12345));
EXPECT_FALSE(response->getOption(D6O_BOOTFILE_URL));
// Get and setup the callout handle.
EXPECT_TRUE(HooksManager::calloutsPresent(testHooks.hook_index_pkt6_send_));
CalloutHandlePtr handle = HooksManager::createCalloutHandle();
handle->setArgument("query6", query);
handle->setArgument("response6", response);
// Execute the callout.
EXPECT_NO_THROW(HooksManager::callCallouts(testHooks.hook_index_pkt6_send_,
*handle));
EXPECT_EQ(0, handle->getStatus());
// Check the result.
OptionPtr opt = response->getOption(D6O_BOOTFILE_URL);
ASSERT_TRUE(opt);
EXPECT_EQ(D6O_BOOTFILE_URL, opt->getType());
const OptionBuffer& buffer = opt->getData();
ASSERT_EQ(3, buffer.size());
EXPECT_EQ(0, memcmp(&buffer[0], "abc", 3));
}
} // end of anonymous namespace

View File

@@ -1,80 +0,0 @@
// Copyright (C) 2022 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/.
/// @file This file contains tests which exercise the load and unload
/// functions in the ddns tuning hook library. In order to test the load
/// function, one must be able to pass it hook library parameters. The
/// the only way to populate these parameters is by actually loading the
/// library via HooksManager::loadLibraries().
#include <config.h>
#include <ddns_tuning.h>
#include <hooks/hooks_manager.h>
#include <cc/data.h>
#include <gtest/gtest.h>
#include <errno.h>
using namespace std;
using namespace isc;
using namespace isc::hooks;
using namespace isc::data;
using namespace isc::dhcp;
namespace {
/// @brief Test fixture for testing loading and unloading the flex-option library
class LibLoadTest : public ::testing::Test {
public:
/// @brief Constructor
LibLoadTest() {
reset();
}
/// @brief Destructor
/// Removes files that may be left over from previous tests
virtual ~LibLoadTest() {
reset();
}
/// @brief Removes files that may be left over from previous tests
virtual void reset() {
HooksManager::unloadLibraries();
}
void addLib(const std::string& lib, ConstElementPtr params) {
libraries_.push_back(make_pair(lib, params));
}
void loadLibs() {
EXPECT_TRUE(HooksManager::loadLibraries(libraries_));
}
void unloadLibs() {
EXPECT_NO_THROW(HooksManager::unloadLibraries());
}
HookLibsCollection libraries_;
};
// Simple test that checks the library can be loaded and unloaded several times.
TEST_F(LibLoadTest, validLoad) {
// Prepare parameters for the callout parameters library.
ElementPtr params = Element::createList();
params->set("hostname-expr", Element::create("special-snowflake"));
addLib(DDNS_TUNING_LIB_SO, params);
loadLibs();
unloadLibs();
loadLibs();
unloadLibs();
}
} // end of anonymous namespace

View File

@@ -1,19 +0,0 @@
// Copyright (C) 2022 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 <log/logger_support.h>
#include <gtest/gtest.h>
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::log::initLogger();
int result = RUN_ALL_TESTS();
return (result);
}

View File

@@ -1 +0,0 @@
/ddns_tuning_unittests

View File

@@ -1,60 +0,0 @@
SUBDIRS = .
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/hooks/dhcp/ddns_tuning -I$(top_srcdir)/src/hooks/dhcp/ddns_tuning
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DDDNS_TUNING_LIB_SO=\"$(abs_top_builddir)/src/hooks/dhcp/ddns_tuning/.libs/libdhcp_ddns_tuning.so\"
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_STATIC_LINK
AM_LDFLAGS = -static
endif
# Unit test data files need to get installed.
EXTRA_DIST =
CLEANFILES = *.gcno *.gcda
# TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
LOG_COMPILER = $(LIBTOOL)
AM_LOG_FLAGS = --mode=execute
TESTS =
if HAVE_GTEST
TESTS += ddns_tuning_unittests
ddns_tuning_unittests_SOURCES = run_unittests.cc
ddns_tuning_unittests_SOURCES += ddns_tuning_unittests.cc
ddns_tuning_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
ddns_tuning_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
ddns_tuning_unittests_CXXFLAGS = $(AM_CXXFLAGS)
ddns_tuning_unittests_LDADD = $(top_builddir)/src/hooks/dhcp/ddns_tuning/libddns_tuning.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
ddns_tuning_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
ddns_tuning_unittests_LDADD += $(LOG4CPLUS_LIBS)
ddns_tuning_unittests_LDADD += $(CRYPTO_LIBS)
ddns_tuning_unittests_LDADD += $(BOOST_LIBS)
ddns_tuning_unittests_LDADD += $(GTEST_LDADD)
endif
noinst_PROGRAMS = $(TESTS)

View File

@@ -1,247 +0,0 @@
// Copyright (C) 2022 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/.
/// @file This file contains tests which verify flexible option.
#include <config.h>
#include <ddns_tuning.h>
#include <ddns_tuning_log.h>
#include <dhcp/libdhcp++.h>
#include <dhcp/option_string.h>
#include <dhcpsrv/cfgmgr.h>
#include <eval/eval_context.h>
#include <hooks/callout_manager.h>
#include <hooks/hooks.h>
#include <gtest/gtest.h>
#include <sstream>
using namespace std;
using namespace isc;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::eval;
using namespace isc::hooks;
using namespace isc::ddns_tuning;
namespace {
/// @brief Test class derived from DdnsTuningImpl
class TestDdnsTuningImpl : public DdnsTuningImpl {
public:
/// @brief Configure clone which records the error.
///
/// @param options The element with option config list.
void testConfigure(ConstElementPtr options) {
err_msg_.clear();
try {
configure(options);
} catch (const std::exception& ex) {
err_msg_ = string(ex.what());
throw;
}
}
/// @brief Get the last error message.
///
/// @return The last error message.
const string& getErrMsg() const {
return (err_msg_);
}
private:
/// @brief Last error message.
string err_msg_;
};
/// @brief The type of shared pointers to TestDdnsTuningImpl
typedef boost::shared_ptr<TestDdnsTuningImpl> TestDdnsTuningImplPtr;
/// @brief Test fixture for testing the DDNS Tuning library.
class DdnsTuningTest : public ::testing::Test {
public:
/// @brief Constructor.
DdnsTuningTest() {
impl_.reset(new TestDdnsTuningImpl());
CfgMgr::instance().setFamily(AF_INET);
}
/// @brief Destructor.
virtual ~DdnsTuningTest() {
CfgMgr::instance().setFamily(AF_INET);
impl_.reset();
}
/// @brief Flex Option implementation.
TestDdnsTuningImplPtr impl_;
};
// Verify that the configuration must exist.
TEST_F(DdnsTuningTest, noConfig) {
ElementPtr options;
EXPECT_THROW(impl_->testConfigure(options), BadValue);
EXPECT_EQ("'hostname' parameter is mandatory", impl_->getErrMsg());
}
// Verify that the configuration must be a list.
TEST_F(DdnsTuningTest, configNotList) {
ElementPtr options = Element::createMap();
EXPECT_THROW(impl_->testConfigure(options), BadValue);
EXPECT_EQ("'hostname' parameter must be a string", impl_->getErrMsg());
}
// Verify that the configuration can be the empty list.
TEST_F(DdnsTuningTest, configEmpty) {
ElementPtr options = Element::createList();
EXPECT_NO_THROW(impl_->testConfigure(options));
EXPECT_TRUE(impl_->getErrMsg().empty());
}
// Verify that the add value must parse.
TEST_F(DdnsTuningTest, optionConfigBadAdd) {
ElementPtr params = Element::createList();
params->set("hostname", Element::create(string("ifelse('a','b','c')")));
EXPECT_THROW(impl_->testConfigure(params), BadValue);
string expected = "can't parse add expression [ifelse('a','b','c')] ";
expected += "error: <string>:1.11: syntax error, ";
expected += "unexpected \",\", expecting == or +";
EXPECT_EQ(expected, impl_->getErrMsg());
}
// Verify that a valid v4 add value is accepted.
TEST_F(DdnsTuningTest, optionConfigAdd4) {
ElementPtr params = Element::createList();
params->set("hostname", Element::create(string("ifelse('a','b','c')")));
EXPECT_NO_THROW(impl_->testConfigure(params));
EXPECT_TRUE(impl_->getErrMsg().empty());
/* TODO: verify it was really configured
auto map = impl_->getOptionConfigMap();
DdnsTuningImpl::OptionConfigPtr opt_cfg;
ASSERT_NO_THROW(opt_cfg = map.at(DHO_HOST_NAME));
ASSERT_TRUE(opt_cfg);
EXPECT_EQ(DHO_HOST_NAME, opt_cfg->getCode());
EXPECT_EQ(DdnsTuningImpl::ADD, opt_cfg->getAction());
EXPECT_EQ("'abc'", opt_cfg->getText());
ExpressionPtr expr = opt_cfg->getExpr();
ASSERT_TRUE(expr);
ASSERT_EQ(1, expr->size());
Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, 12345));
ValueStack values;
EXPECT_NO_THROW(expr->at(0)->evaluate(*pkt4, values));
ASSERT_EQ(1, values.size());
EXPECT_EQ("abc", values.top()); */
}
// Verify that empty option config list does nothing.
TEST_F(DdnsTuningTest, processEmpty) {
Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 12345));
Pkt4Ptr response(new Pkt4(DHCPOFFER, 12345));
string response_txt = response->toText();
EXPECT_NO_THROW(impl_->process<Pkt4Ptr>(Option::V4, query, response));
EXPECT_EQ(response_txt, response->toText());
}
// Verify that NONE action really does nothing.
TEST_F(DdnsTuningTest, processNone) {
CfgMgr::instance().setFamily(AF_INET6);
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 12345));
Pkt6Ptr response(new Pkt6(DHCPV6_ADVERTISE, 12345));
string response_txt = response->toText();
EXPECT_NO_THROW(impl_->process<Pkt6Ptr>(Option::V6, query, response));
EXPECT_EQ(response_txt, response->toText());
}
// Verify that REMOVE action does nothing if the option is not present.
TEST_F(DdnsTuningTest, processRemoveNoOption) {
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr code = Element::create(DHO_HOST_NAME);
option->set("code", code);
ElementPtr remove = Element::create(string("'abc' == 'abc'"));
option->set("remove", remove);
EXPECT_NO_THROW(impl_->testConfigure(options));
EXPECT_TRUE(impl_->getErrMsg().empty());
Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 12345));
Pkt4Ptr response(new Pkt4(DHCPOFFER, 12345));
string response_txt = response->toText();
EXPECT_FALSE(response->getOption(DHO_HOST_NAME));
EXPECT_NO_THROW(impl_->process<Pkt4Ptr>(Option::V4, query, response));
EXPECT_EQ(response_txt, response->toText());
EXPECT_FALSE(response->getOption(DHO_HOST_NAME));
}
// Verify that REMOVE action does nothing when the expression evaluates to false.
TEST_F(DdnsTuningTest, processRemoveFalse) {
CfgMgr::instance().setFamily(AF_INET6);
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr code = Element::create(D6O_BOOTFILE_URL);
option->set("code", code);
ElementPtr remove = Element::create(string("'abc' == 'xyz'"));
option->set("remove", remove);
EXPECT_NO_THROW(impl_->testConfigure(options));
EXPECT_TRUE(impl_->getErrMsg().empty());
Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 12345));
Pkt6Ptr response(new Pkt6(DHCPV6_ADVERTISE, 12345));
OptionStringPtr str(new OptionString(Option::V6, D6O_BOOTFILE_URL, "http"));
response->addOption(str);
string response_txt = response->toText();
EXPECT_NO_THROW(impl_->process<Pkt6Ptr>(Option::V6, query, response));
EXPECT_EQ(response_txt, response->toText());
EXPECT_TRUE(response->getOption(D6O_BOOTFILE_URL));
}
// A more complex check...
TEST_F(DdnsTuningTest, processFullTest) {
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr code = Element::create(DHO_BOOT_FILE_NAME);
option->set("code", code);
string expr = "ifelse(option[host-name].exists,";
expr += "concat(option[host-name].text,'.boot'),'')";
ElementPtr add = Element::create(expr);
option->set("add", add);
EXPECT_NO_THROW(impl_->testConfigure(options));
EXPECT_TRUE(impl_->getErrMsg().empty());
Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 12345));
Pkt4Ptr response(new Pkt4(DHCPOFFER, 12345));
OptionStringPtr str(new OptionString(Option::V4, DHO_HOST_NAME, "foo"));
query->addOption(str);
EXPECT_FALSE(response->getOption(DHO_BOOT_FILE_NAME));
EXPECT_NO_THROW(impl_->process<Pkt4Ptr>(Option::V4, query, response));
OptionPtr opt = response->getOption(DHO_BOOT_FILE_NAME);
ASSERT_TRUE(opt);
EXPECT_EQ(DHO_BOOT_FILE_NAME, opt->getType());
const OptionBuffer& buffer = opt->getData();
ASSERT_EQ(8, buffer.size());
EXPECT_EQ(0, memcmp(&buffer[0], "foo.boot", 8));
}
} // end of anonymous namespace

View File

@@ -1,19 +0,0 @@
// Copyright (C) 2022 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 <log/logger_support.h>
#include <gtest/gtest.h>
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
isc::log::initLogger();
int result = RUN_ALL_TESTS();
return (result);
}

View File

@@ -1,17 +0,0 @@
// Copyright (C) 2022 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 <hooks/hooks.h>
extern "C" {
/// @brief returns Kea hooks version.
int version() {
return (KEA_HOOKS_VERSION);
}
}