BIND 10 master, updated. e45768f4b916faff9ace1f1da25e423eba2ab430 Merge branch 'work/acl'
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Jun 14 19:14:51 UTC 2011
The branch, master has been updated
via e45768f4b916faff9ace1f1da25e423eba2ab430 (commit)
via 9652c9fd3f69836a928626ca9fc940e80e725279 (commit)
via a5572545c3b6106052898e016757398efd475dd8 (commit)
via b37a785ae2a03a7c84b316b67e50f77a827a81e8 (commit)
via 0b99dc120fc89081901be0b884f77e02530b8588 (commit)
via fde3b8cb6fc790249bfb918971a33a0cce7a4cf8 (commit)
via 3f6fb6a54d85ed33bb23aa3988934166b17261c9 (commit)
via fe244439fca78ce558073b856dac69290baf67c5 (commit)
via a6c21ad6d670896283a941b5bfb233ff5987c50b (commit)
via 30a20a04aae6b14749980d575cc69180998ca0c9 (commit)
via 46f82ccf0e1984c8b195a5492618f5d065682c3e (commit)
via d324bf65587ab92ffc8a5a6f94cefc2fc78a52f5 (commit)
via 49816e5010448c5c966ba3964934adf68a972400 (commit)
via 463a593e465643f157fe806b3fe826b6ed593750 (commit)
from 356ffa38fc98b8587499aa004eff6af103cfaa78 (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 e45768f4b916faff9ace1f1da25e423eba2ab430
Merge: 356ffa38fc98b8587499aa004eff6af103cfaa78 9652c9fd3f69836a928626ca9fc940e80e725279
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Jun 14 21:00:30 2011 +0200
Merge branch 'work/acl'
commit 9652c9fd3f69836a928626ca9fc940e80e725279
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Jun 14 20:58:15 2011 +0200
[trac997] Add a const
commit a5572545c3b6106052898e016757398efd475dd8
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Tue Jun 14 11:41:15 2011 -0700
[trac997] use camel style for methods.
commit b37a785ae2a03a7c84b316b67e50f77a827a81e8
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Tue Jun 14 11:40:57 2011 -0700
[trac997] added blank lines for readability
commit 0b99dc120fc89081901be0b884f77e02530b8588
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Jun 14 20:30:33 2011 +0200
[trac997] Return few camels
commit fde3b8cb6fc790249bfb918971a33a0cce7a4cf8
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Jun 14 20:23:43 2011 +0200
[trac997] More review comments
commit 3f6fb6a54d85ed33bb23aa3988934166b17261c9
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Tue Jun 14 10:02:20 2011 -0700
[trac997] minor editorial fix: indentation alignment.
commit fe244439fca78ce558073b856dac69290baf67c5
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Jun 14 12:01:36 2011 +0200
[trac997] Address review comments
commit a6c21ad6d670896283a941b5bfb233ff5987c50b
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Jun 13 17:51:13 2011 -0700
[trac997] another editorial cleanup: remove a space for style consistency
commit 30a20a04aae6b14749980d575cc69180998ca0c9
Author: JINMEI Tatuya <jinmei at isc.org>
Date: Mon Jun 13 17:26:41 2011 -0700
[trac997] minor editorial fixes:
- add blank lines for readability
- remove white space for style consistency
- use "lower+underscore" style for variables (per the guideline)
-----------------------------------------------------------------------
Summary of changes:
src/lib/acl/Makefile.am | 2 +-
src/lib/acl/acl.h | 140 ++++++++++++++++++++++++++++++++++++++
src/lib/acl/tests/Makefile.am | 2 +-
src/lib/acl/tests/acl_test.cc | 148 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 290 insertions(+), 2 deletions(-)
create mode 100644 src/lib/acl/acl.h
create mode 100644 src/lib/acl/tests/acl_test.cc
-----------------------------------------------------------------------
diff --git a/src/lib/acl/Makefile.am b/src/lib/acl/Makefile.am
index dc4900d..b063289 100644
--- a/src/lib/acl/Makefile.am
+++ b/src/lib/acl/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = tests
-EXTRA_DIST = check.h
+EXTRA_DIST = check.h acl.h
# TODO: Once we have some cc file we are able to compile, create the library.
# For now, we have only header files, not creating empty library.
diff --git a/src/lib/acl/acl.h b/src/lib/acl/acl.h
new file mode 100644
index 0000000..998b2b0
--- /dev/null
+++ b/src/lib/acl/acl.h
@@ -0,0 +1,140 @@
+// Copyright (C) 2011 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 ACL_ACL_H
+#define ACL_ACL_H
+
+#include "check.h"
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace isc {
+namespace acl {
+
+/**
+ * \brief Default actions an ACL could perform.
+ *
+ * This is the default for the ACL class. It is possible to specify any other
+ * data type, as the ACL class does nothing about them, but these look
+ * reasonable, so they are provided for convenience. It is not specified what
+ * exactly these mean and it's up to whoever uses them.
+ */
+enum BasicAction {
+ ACCEPT,
+ REJECT,
+ DROP
+};
+
+/**
+ * \brief The ACL itself.
+ *
+ * It holds bunch of ordered entries, each one consisting of a check (
+ * of any kind, it might be even compound) and an action that is returned
+ * whenever the action matches. They are tested in the order and first
+ * match counts.
+ *
+ * This is non-copyable. It seems that there's no need to copy them (even
+ * when it would be technically possible), so we forbid it just to prevent
+ * copying it by accident. If there really is legitimate use, this restriction
+ * can be removed.
+ *
+ * The class is template. It is possible to specify on which context the checks
+ * match and which actions it returns. The actions must be copyable
+ * for this to work and it is expected to be something small, usually an enum
+ * (but other objects are also possible).
+ *
+ * \note There are protected functions. In fact, you should consider them
+ * private, they are protected so tests can get inside. This class
+ * is not expected to be subclassed in real applications.
+ */
+template<typename Context, typename Action = BasicAction> class ACL :
+ public boost::noncopyable {
+public:
+ /**
+ * \brief Constructor.
+ *
+ * \param default_action It is the action that is returned when the checked
+ * things "falls off" the end of the list (when no rule matched).
+ */
+ ACL(const Action& default_action) : default_action_(default_action)
+ {}
+
+ /**
+ * \brief Pointer to the check.
+ *
+ * We use the shared pointer, because we are not able to copy the checks.
+ * However, we might need to copy the entries (when we concatenate ACLs
+ * together in future).
+ */
+ typedef boost::shared_ptr<const Check<Context> > ConstCheckPtr;
+
+ /**
+ * \brief The actual main function that decides.
+ *
+ * This is the function that takes the entries one by one, checks
+ * the context against conditions and if it matches, returns the
+ * action that belongs to the first matched entry or default action
+ * if nothing matches.
+ * \param context The thing that should be checked. It is directly
+ * passed to the checks.
+ */
+ const Action& execute(const Context& context) const {
+ const typename Entries::const_iterator end(entries_.end());
+ for (typename Entries::const_iterator i(entries_.begin()); i != end;
+ ++i) {
+ if (i->first->matches(context)) {
+ return (i->second);
+ }
+ }
+ return (default_action_);
+ }
+
+ /**
+ * \brief Add new entry at the end of the list.
+ *
+ * \note We currently allow only adding at the end. This is enough for now,
+ * but we may need more when we start implementing some kind optimisations,
+ * including replacements, reorderings and removals.
+ *
+ * \param check The check to test if the thing matches.
+ * \param action The action to return when the thing matches this check.
+ */
+ void append(ConstCheckPtr check, const Action& action) {
+ entries_.push_back(Entry(check, action));
+ }
+private:
+ // Just type abbreviations.
+ typedef std::pair<ConstCheckPtr, Action> Entry;
+ typedef std::vector<Entry> Entries;
+ /// \brief The default action, when nothing mathes.
+ const Action default_action_;
+ /// \brief The entries we have.
+ Entries entries_;
+protected:
+ /**
+ * \brief Get the default action.
+ *
+ * This is for testing purposes only.
+ */
+ const Action& getDefaultAction() const {
+ return (default_action_);
+ }
+};
+
+}
+}
+
+#endif
diff --git a/src/lib/acl/tests/Makefile.am b/src/lib/acl/tests/Makefile.am
index 1ca17f3..5c0cdfc 100644
--- a/src/lib/acl/tests/Makefile.am
+++ b/src/lib/acl/tests/Makefile.am
@@ -4,7 +4,7 @@ TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = run_unittests.cc
-run_unittests_SOURCES += check_test.cc
+run_unittests_SOURCES += check_test.cc acl_test.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
diff --git a/src/lib/acl/tests/acl_test.cc b/src/lib/acl/tests/acl_test.cc
new file mode 100644
index 0000000..1e70b86
--- /dev/null
+++ b/src/lib/acl/tests/acl_test.cc
@@ -0,0 +1,148 @@
+// Copyright (C) 2011 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 <gtest/gtest.h>
+#include <acl/acl.h>
+#include <cassert>
+
+using namespace isc::acl;
+using boost::shared_ptr;
+
+namespace {
+
+// This is arbitrary guess of size for the log. If it's too small for your
+// test, just make it bigger.
+const size_t LOG_SIZE = 10;
+
+// This will remember which checks did run already.
+struct Log {
+ // The actual log cells, if i-th check did run
+ mutable bool run[LOG_SIZE];
+ Log() {
+ // Nothing run yet
+ for (size_t i(0); i < LOG_SIZE; ++i) {
+ run[i] = false;
+ }
+ }
+ // Checks that the first amount of checks did run and the rest didn't.
+ void checkFirst(size_t amount) const {
+ ASSERT_LE(amount, LOG_SIZE) << "Wrong test: amount bigger than size "
+ "of log";
+ {
+ SCOPED_TRACE("Checking that the first amount of checks did run");
+ for (size_t i(0); i < amount; ++i) {
+ EXPECT_TRUE(run[i]) << "Check #" << i << " did not run.";
+ }
+ }
+
+ {
+ SCOPED_TRACE("Checking that the rest did not run");
+ for (size_t i(amount); i < LOG_SIZE; ++i) {
+ EXPECT_FALSE(run[i]) << "Check #" << i << "did run.";
+ }
+ }
+ }
+};
+
+// This returns true or false every time, no matter what is passed to it.
+// But it logs that it did run.
+class ConstCheck : public Check<Log> {
+public:
+ ConstCheck(bool accepts, size_t log_num) :
+ log_num_(log_num),
+ accepts_(accepts)
+ {
+ assert(log_num < LOG_SIZE); // If this fails, the LOG_SIZE is too small
+ }
+ /*
+ * This use of mutable log context is abuse for testing purposes.
+ * It is expected that the context will not be modified in the real
+ * applications of ACLs, but we want to know which checks were called
+ * and this is an easy way.
+ */
+ virtual bool matches(const Log& log) const {
+ log.run[log_num_] = true;
+ return (accepts_);
+ }
+private:
+ size_t log_num_;
+ bool accepts_;
+};
+
+// Test version of the ACL class. It adds few methods to examine the protected
+// data, but does not change the implementation.
+class TestACL : public ACL<Log> {
+public:
+ TestACL() :
+ ACL(DROP)
+ {}
+ // Check the stored default action there
+ void checkDefaultAction(BasicAction ac) {
+ EXPECT_EQ(getDefaultAction(), ac);
+ }
+};
+
+// The test fixture. Contains some members so they don't need to be manually
+// created each time and some convenience functions.
+class ACLTest : public ::testing::Test {
+public:
+ ACLTest() :
+ next_check_(0)
+ {}
+ TestACL acl_;
+ Log log_;
+ size_t next_check_;
+ shared_ptr<Check<Log> > getCheck(bool accepts) {
+ return (shared_ptr<Check<Log> >(new ConstCheck(accepts,
+ next_check_++)));
+ }
+};
+
+/*
+ * This tests the default action and that nothing is run if nothing is
+ * inserted (it's hard to imagine otherwise though).
+ *
+ * We use the default ACL unchanged from the test class.
+ */
+TEST_F(ACLTest, emptyRule) {
+ acl_.checkDefaultAction(DROP);
+ EXPECT_EQ(DROP, acl_.execute(log_));
+ // No test was run
+ log_.checkFirst(0);
+}
+
+/*
+ * This tests the default action in case no check matches.
+ */
+TEST_F(ACLTest, noMatch) {
+ acl_.append(getCheck(false), ACCEPT);
+ acl_.append(getCheck(false), REJECT);
+ EXPECT_EQ(DROP, acl_.execute(log_));
+ // The first two checks were actually run (and didn't match)
+ log_.checkFirst(2);
+}
+
+/*
+ * Checks that it takes the first matching check and returns the
+ * value. Also checks that the others aren't run at all.
+ */
+TEST_F(ACLTest, firstMatch) {
+ acl_.append(getCheck(false), ACCEPT);
+ acl_.append(getCheck(true), REJECT);
+ acl_.append(getCheck(true), ACCEPT);
+ EXPECT_EQ(REJECT, acl_.execute(log_));
+ log_.checkFirst(2);
+}
+
+}
More information about the bind10-changes
mailing list