From e5be011922ec7c808ae1102feb98600debdcd6a5 Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Fri, 30 Oct 2015 00:20:48 -0700 Subject: [PATCH 1/5] [trac4090] Add support for TokenSubstring Add support and testing for TokenSubstring. This token takes three paramaters (string, start and length) and produces a new string based on the original string. It allows negative values for start and length causing it to count from the end of the string for start and to get characters before the start point for length. --- src/lib/eval/eval_messages.mes | 4 + src/lib/eval/tests/token_unittest.cc | 207 +++++++++++++++++++++++++++ src/lib/eval/token.cc | 75 ++++++++++ src/lib/eval/token.h | 48 ++++++- 4 files changed, 333 insertions(+), 1 deletion(-) diff --git a/src/lib/eval/eval_messages.mes b/src/lib/eval/eval_messages.mes index cca2b0e19e..1ce1ca3d12 100644 --- a/src/lib/eval/eval_messages.mes +++ b/src/lib/eval/eval_messages.mes @@ -18,3 +18,7 @@ $NAMESPACE isc::dhcp This debug message indicates that the expression has been evaluated to said value. This message is mostly useful during debugging of the client classification expressions. + +% EVAL_SUBSTRING_BAD_PARAM_CONVERSION starting %1, length %2 +This debug message indicates that the parameter for the starting postion +or length of the substring couldn't be converted to an integer. diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index 6b29763c62..d3bb997bf3 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -60,6 +60,40 @@ public: OptionPtr option_str4_; ///< A string option for DHCPv4 OptionPtr option_str6_; ///< A string option for DHCPv6 + + /// @brief Verify that the substring eval works properly + /// + /// This function takes the parameters and sets up the value + /// stack then executes the eval and checks the results. + /// + /// @param test_string The string to operate on + /// @param test_start The postion to start when getting a substring + /// @param test_length The length of the substring to get + /// @param result_string The expected result of the eval + void verifySubstringEval(const std::string& test_string, + const std::string& test_start, + const std::string& test_length, + const std::string& result_string) { + + // create the token + ASSERT_NO_THROW(t_.reset(new TokenSubstring())); + + // push values on stack + values_.push(test_string); + values_.push(test_start); + values_.push(test_length); + + // evaluate the token + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + + // verify results + ASSERT_EQ(1, values_.size()); + EXPECT_EQ(result_string, values_.top()); + + // remove result + values_.pop(); + } + /// @todo: Add more option types here }; @@ -197,3 +231,176 @@ TEST_F(TokenTest, optionEqualTrue) { } }; + +// This test checks if an a token representing a substring request +// throws an excpetion if there aren't enough values on the stack. +// The stack from the top is: length, start, string. +// The actual packet is not used. +TEST_F(TokenTest, substringNotEnoughValues) { + ASSERT_NO_THROW(t_.reset(new TokenSubstring())); + + // Subsring requires three values on the stack, try + // with 0, 1 and 2 all should thorw an exception + EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack); + + values_.push(""); + EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack); + + values_.push("0"); + EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack); + + // Three should work + values_.push("0"); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + + // As we had an empty string to start with we should have an empty + // one after the evaluate + ASSERT_EQ(1, values_.size()); + EXPECT_EQ("", values_.top()); +} + +// Test getting the whole string in different ways +TEST_F(TokenTest, substringWholeString) { + // Get the whole string + verifySubstringEval("foobar", "0", "6", "foobar"); + + // Get the whole string with "all" + verifySubstringEval("foobar", "0", "all", "foobar"); + + // Get the whole string with an extra long number + verifySubstringEval("foobar", "0", "123456", "foobar"); + + // Get the whole string counting from the back + verifySubstringEval("foobar", "-6", "all", "foobar"); +} + +// Test getting a suffix, in this case the last 3 characters +TEST_F(TokenTest, substringTrailer) { + verifySubstringEval("foobar", "3", "3", "bar"); + verifySubstringEval("foobar", "3", "all", "bar"); + verifySubstringEval("foobar", "-3", "all", "bar"); + verifySubstringEval("foobar", "-3", "123", "bar"); +} + +// Test getting the middle of the string in different ways +TEST_F(TokenTest, substringMiddle) { + verifySubstringEval("foobar", "1", "4", "ooba"); + verifySubstringEval("foobar", "-5", "4", "ooba"); + verifySubstringEval("foobar", "-1", "-4", "ooba"); + verifySubstringEval("foobar", "5", "-4", "ooba"); +} + +// Test getting the last letter in different ways +TEST_F(TokenTest, substringLastLetter) { + verifySubstringEval("foobar", "5", "all", "r"); + verifySubstringEval("foobar", "5", "1", "r"); + verifySubstringEval("foobar", "5", "5", "r"); + verifySubstringEval("foobar", "-1", "all", "r"); + verifySubstringEval("foobar", "-1", "1", "r"); + verifySubstringEval("foobar", "-1", "5", "r"); +} + +// Test we get only what is available if we ask for a longer string +TEST_F(TokenTest, substringLength) { + // Test off the front + verifySubstringEval("foobar", "0", "-4", ""); + verifySubstringEval("foobar", "1", "-4", "f"); + verifySubstringEval("foobar", "2", "-4", "fo"); + verifySubstringEval("foobar", "3", "-4", "foo"); + + // and the back + verifySubstringEval("foobar", "3", "4", "bar"); + verifySubstringEval("foobar", "4", "4", "ar"); + verifySubstringEval("foobar", "5", "4", "r"); + verifySubstringEval("foobar", "6", "4", ""); +} + +// Test that we get nothing if the starting postion is out of the string +TEST_F(TokenTest, substringStartingPosition) { + // Off the front + verifySubstringEval("foobar", "-7", "1", ""); + verifySubstringEval("foobar", "-7", "-11", ""); + verifySubstringEval("foobar", "-7", "all", ""); + + // and the back + verifySubstringEval("foobar", "6", "1", ""); + verifySubstringEval("foobar", "6", "-11", ""); + verifySubstringEval("foobar", "6", "all", ""); +} + +// Check what happens if we use strings that aren't numbers for start or length +// We should return the empty string +TEST_F(TokenTest, substringBadParams) { + verifySubstringEval("foobar", "0ick", "all", ""); + verifySubstringEval("foobar", "ick0", "all", ""); + verifySubstringEval("foobar", "ick", "all", ""); + verifySubstringEval("foobar", "0", "ick", ""); + verifySubstringEval("foobar", "0", "0ick", ""); + verifySubstringEval("foobar", "0", "ick0", ""); + verifySubstringEval("foobar", "0", "allaboard", ""); +} + +// lastly check that we don't get anything if the string is empty +TEST_F(TokenTest, substringStartingEmpty) { + verifySubstringEval("", "0", "all", ""); + verifySubstringEval("foobar", "0", "0", ""); +} + +// Check if we can use the substring and equal tokens together +// We put the result on the stack first then the substring values +// then evaluate the substring which should leave the original +// result on the bottom with the substring result on next. +// Evaulating the equals should produce true for the first +// and false for the second. +// throws an excpetion if there aren't enough values on the stack. +// The stack from the top is: length, start, string. +// The actual packet is not used. +TEST_F(TokenTest, substringEquals) { + TokenPtr tequal; + + ASSERT_NO_THROW(t_.reset(new TokenSubstring())); + ASSERT_NO_THROW(tequal.reset(new TokenEqual())); + + // The final expected value + values_.push("ooba"); + + // The substring values + // Subsring requires three values on the stack, try + // with 0, 1 and 2 all should thorw an exception + values_.push("foobar"); + values_.push("1"); + values_.push("4"); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + + // we should have two values on the stack + ASSERT_EQ(2, values_.size()); + + // next the equals eval + EXPECT_NO_THROW(tequal->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + EXPECT_EQ("true", values_.top()); + + // get rid of the result + values_.pop(); + + // and try it again but with a bad final value + // The final expected value + values_.push("foob"); + + // The substring values + // Subsring requires three values on the stack, try + // with 0, 1 and 2 all should thorw an exception + values_.push("foobar"); + values_.push("1"); + values_.push("4"); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + + // we should have two values on the stack + ASSERT_EQ(2, values_.size()); + + // next the equals eval + EXPECT_NO_THROW(tequal->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + EXPECT_EQ("false", values_.top()); + +} diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index 66ebf1c5b1..3d3266a7dd 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include using namespace isc::dhcp; @@ -53,3 +54,77 @@ TokenEqual::evaluate(const Pkt& /*pkt*/, ValueStack& values) { else values.push("false"); } + +void +TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) { + + if (values.size() < 3) { + isc_throw(EvalBadStack, "Incorrect stack order. Expected at least " + "3 values for substring operator, got " << values.size()); + } + + string len_str = values.top(); + values.pop(); + string start_str = values.top(); + values.pop(); + string string_str = values.top(); + values.pop(); + + // If we have no string to start with we push an empty string and leave + if (string_str.empty()) { + values.push(""); + return; + } + + // Convert the starting position and legnth from strings to numbers + // the length may also be "all" in which case simply make it the + // legnth of the string. + // If we have a problem push an empty string and leave + int start_pos, length; + try { + start_pos = boost::lexical_cast(start_str); + if ("all" == len_str) { + length = string_str.length(); + } else { + length = boost::lexical_cast(len_str); + } + } catch (const boost::bad_lexical_cast&) { +#if 0 + // Logging not yet built + LOG_DEBUG(eval_logger, EVAL_DBG_TRACE, + EVAL_SUBSTRING_BAD_PARAM_CONVERSION) + .arg(start_str) + .arg(len_str); +#endif + values.push(""); + return; + } + + // If the starting postion is outside of the string push an + // empty string and leave + if (((start_pos >= 0) && (start_pos >= string_str.length())) | + ((start_pos < 0) && (-start_pos > string_str.length()))) { + values.push(""); + return; + } + + // Adjust the values to be something for substr. We first figure out + // the staring postion, then update it and the length to get the + // characters before or after it depnding on the sign of length + if (start_pos < 0) { + start_pos = string_str.length() + start_pos; + } + + if (length < 0) { + length = -length; + if (length <= start_pos){ + start_pos -= length; + } else { + length = start_pos; + start_pos = 0; + } + } + + // and finally get the substring + values.push(string_str.substr(start_pos, length)); +} diff --git a/src/lib/eval/token.h b/src/lib/eval/token.h index 930c707fc5..dee4c46212 100644 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@ -56,7 +56,7 @@ public: /// - option[123] (a token that extracts value of option 123) /// - == (an operator that compares two other tokens) /// - substring(a,b,c) (an operator that takes three arguments: a string, -/// first and last character) +/// first character and length) class Token { public: @@ -158,6 +158,52 @@ public: void evaluate(const Pkt& pkt, ValueStack& values); }; +/// @brief Token that represents the substring operator (returns a portion +/// of the supplied string) +/// +/// This token represents substring(str, start, len) An operator that takes three +/// arguments: a string, the first character and the length. +class TokenSubstring : public Token { +public: + /// @brief Constructor (does nothing) + TokenSubstring() {} + + /// @brief Extract a substring from a string + /// + /// Evaluation does not use packet information, but rather consumes the last + /// three parameters and requires at least three parameters to be present on + /// stack. From the top it expects the values on the stack as: + /// len + /// start + /// str + /// + /// str is the string to extract a substring from. If it is empty an empty + /// string is pushed onto the value stack. + /// + /// start is the postion from which the code starts extracting the substring. + /// 0 is before the first character and a negative number starts from the end, + /// with -1 being before the last character. If the starting point is + /// outside of the original string an empty string is pushed onto the value + /// stack. + /// + /// length is the number of characters from the string to extract. + /// "all" means all remaining characters from start to the end of string. + /// A negative number means to go from start towards the beginning of + /// string, but doesn't include start. + /// If length is longer than the remaining portion of string + /// then the entire remaining portion is placed on the value stack. + /// Note: a negative value of length only indicates which characters to + /// extract, it does NOT indicate any attempt to reverse the string. + /// For example substring("foobar", 4, -2) will result in "ob". + /// + /// @throw EvalBadStack if there's less than 3 values on stack + /// + /// @brief pkt (unused) + /// @brief values - stack of values (3 arguments will be poped, 1 result + /// will be pushed) + void evaluate(const Pkt& pkt, ValueStack& values); +}; + }; // end of isc::dhcp namespace }; // end of isc namespace From b36a613740284c5197e99b8fdd3a78bcad3202b3 Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Mon, 2 Nov 2015 11:22:23 -0800 Subject: [PATCH 2/5] [trac4090] Update per review comments. Update per the review comments except for the logging stuff which will be done next. --- ChangeLog | 4 +++ src/lib/eval/eval_messages.mes | 3 +- src/lib/eval/tests/token_unittest.cc | 9 ++--- src/lib/eval/token.cc | 19 ++++++----- src/lib/eval/token.h | 51 ++++++++++++++++------------ 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index cd2ad8527b..8058ef04bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +XXXX. [func] sar + Added client classification substring token. + (Trac #4090, git + 1041. [func] tomek A new library, libkea-eval has been edded. It is not functional yet, but its purpose is to provide a generic expression diff --git a/src/lib/eval/eval_messages.mes b/src/lib/eval/eval_messages.mes index 1ce1ca3d12..3d86f758b4 100644 --- a/src/lib/eval/eval_messages.mes +++ b/src/lib/eval/eval_messages.mes @@ -21,4 +21,5 @@ client classification expressions. % EVAL_SUBSTRING_BAD_PARAM_CONVERSION starting %1, length %2 This debug message indicates that the parameter for the starting postion -or length of the substring couldn't be converted to an integer. +or length of the substring couldn't be converted to an integer. In this +case the substring routine returns an empty string. diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index d3bb997bf3..273bb37fef 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -233,7 +233,7 @@ TEST_F(TokenTest, optionEqualTrue) { }; // This test checks if an a token representing a substring request -// throws an excpetion if there aren't enough values on the stack. +// throws an exception if there aren't enough values on the stack. // The stack from the top is: length, start, string. // The actual packet is not used. TEST_F(TokenTest, substringNotEnoughValues) { @@ -340,8 +340,9 @@ TEST_F(TokenTest, substringBadParams) { verifySubstringEval("foobar", "0", "allaboard", ""); } -// lastly check that we don't get anything if the string is empty -TEST_F(TokenTest, substringStartingEmpty) { +// lastly check that we don't get anything if the string is empty or +// we don't ask for any characters from it. +TEST_F(TokenTest, substringReturnEmpty) { verifySubstringEval("", "0", "all", ""); verifySubstringEval("foobar", "0", "0", ""); } @@ -352,7 +353,7 @@ TEST_F(TokenTest, substringStartingEmpty) { // result on the bottom with the substring result on next. // Evaulating the equals should produce true for the first // and false for the second. -// throws an excpetion if there aren't enough values on the stack. +// throws an exception if there aren't enough values on the stack. // The stack from the top is: length, start, string. // The actual packet is not used. TEST_F(TokenTest, substringEquals) { diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index 3d3266a7dd..4701976865 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -76,14 +76,15 @@ TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) { return; } - // Convert the starting position and legnth from strings to numbers + // Convert the starting position and length from strings to numbers // the length may also be "all" in which case simply make it the - // legnth of the string. + // length of the string. // If we have a problem push an empty string and leave - int start_pos, length; + int start_pos; + int length; try { start_pos = boost::lexical_cast(start_str); - if ("all" == len_str) { + if (len_str == "all") { length = string_str.length(); } else { length = boost::lexical_cast(len_str); @@ -100,19 +101,19 @@ TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) { return; } + const int string_length = string_str.length(); // If the starting postion is outside of the string push an // empty string and leave - if (((start_pos >= 0) && (start_pos >= string_str.length())) | - ((start_pos < 0) && (-start_pos > string_str.length()))) { + if ((start_pos < -string_length) || (start_pos >= string_length)) { values.push(""); return; } // Adjust the values to be something for substr. We first figure out - // the staring postion, then update it and the length to get the - // characters before or after it depnding on the sign of length + // the starting postion, then update it and the length to get the + // characters before or after it depending on the sign of length if (start_pos < 0) { - start_pos = string_str.length() + start_pos; + start_pos = string_length + start_pos; } if (length < 0) { diff --git a/src/lib/eval/token.h b/src/lib/eval/token.h index dee4c46212..1e34051225 100644 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@ -150,10 +150,10 @@ public: /// either "true" or "false". It requires at least two parameters to be /// present on stack. /// - /// @throw EvalBadStack if there's less than 2 values on stack + /// @throw EvalBadStack if there are less than 2 values on stack /// - /// @brief pkt (unused) - /// @brief values - stack of values (2 arguments will be poped, 1 result + /// @param pkt (unused) + /// @param values - stack of values (2 arguments will be popped, 1 result /// will be pushed) void evaluate(const Pkt& pkt, ValueStack& values); }; @@ -170,36 +170,45 @@ public: /// @brief Extract a substring from a string /// - /// Evaluation does not use packet information, but rather consumes the last - /// three parameters and requires at least three parameters to be present on - /// stack. From the top it expects the values on the stack as: - /// len - /// start - /// str + /// Evaluation does not use packet information. It requires at least + /// three values to be present on the stack. It will consume the top + /// three values on the stack as parameters and push the resulting substring + /// onto the stack. From the top it expects the values on the stack as: + /// - len + /// - start + /// - str /// - /// str is the string to extract a substring from. If it is empty an empty + /// str is the string to extract a substring from. If it is empty, an empty /// string is pushed onto the value stack. /// /// start is the postion from which the code starts extracting the substring. - /// 0 is before the first character and a negative number starts from the end, - /// with -1 being before the last character. If the starting point is - /// outside of the original string an empty string is pushed onto the value - /// stack. + /// 0 is the first character and a negative number starts from the end, with + /// -1 being the last character. If the starting point is outside of the + /// original string an empty string is pushed onto the value stack. /// /// length is the number of characters from the string to extract. /// "all" means all remaining characters from start to the end of string. /// A negative number means to go from start towards the beginning of - /// string, but doesn't include start. + /// the string, but doesn't include start. /// If length is longer than the remaining portion of string /// then the entire remaining portion is placed on the value stack. - /// Note: a negative value of length only indicates which characters to - /// extract, it does NOT indicate any attempt to reverse the string. - /// For example substring("foobar", 4, -2) will result in "ob". /// - /// @throw EvalBadStack if there's less than 3 values on stack + /// The following examples all use the base string "foobar", the first number + /// is the starting position and the second is the length. Note that + /// a negative length only selects which characters to extract it does not + /// indicate an attempt to reverse the string. + /// - 0, all => "foobar" + /// - 0, 6 => "foobar" + /// - 0, 4 => "foob" + /// - 2, all => "obar" + /// - 2, 6 => "obar" + /// - -1, all => "r" + /// - -1, -4 => "ooba" /// - /// @brief pkt (unused) - /// @brief values - stack of values (3 arguments will be poped, 1 result + /// @throw EvalBadStack if there are less than 3 values on stack + /// + /// @param pkt (unused) + /// @param values - stack of values (3 arguments will be popped, 1 result /// will be pushed) void evaluate(const Pkt& pkt, ValueStack& values); }; From a32f2a2aaaa8a2fb71f049514f1b92205f0f4b12 Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Mon, 2 Nov 2015 13:10:06 -0800 Subject: [PATCH 3/5] [trac4090] Setup logger for eval --- doc/guide/logging.xml | 10 ++++++++++ src/lib/eval/Makefile.am | 11 +++++++++-- src/lib/eval/tests/Makefile.am | 2 ++ src/lib/eval/token.cc | 5 ++--- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/doc/guide/logging.xml b/doc/guide/logging.xml index 63c9cf3a38..0924c152ac 100644 --- a/doc/guide/logging.xml +++ b/doc/guide/logging.xml @@ -219,6 +219,11 @@ kea-dhcp4.dhcpsrv - this is a base logger for the libdhcpsrv library. + + kea-dhcp4.eval - this logger is used + to log messages relating to the evaluation code, primarily used + by the client classification routines. + kea-dhcp4.hooks - this logger is used to log messages related to management of hooks libraries, e.g. @@ -302,6 +307,11 @@ kea-dhcp6.dhcpsrv - this is a base logger for the libdhcpsrv library. + + kea-dhcp6.eval - this logger is used + to log messages relating to the evaluation code, primarily used + by the client classification routines. + kea-dhcp6.hooks - this logger is used to log messages related to management of hooks libraries, e.g. diff --git a/src/lib/eval/Makefile.am b/src/lib/eval/Makefile.am index 1fd66b96f8..b8a833c9af 100644 --- a/src/lib/eval/Makefile.am +++ b/src/lib/eval/Makefile.am @@ -12,14 +12,20 @@ AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG) lib_LTLIBRARIES = libkea-eval.la libkea_eval_la_SOURCES = +libkea_eval_la_SOURCES += eval_log.cc eval_log.h libkea_eval_la_SOURCES += token.cc token.h +nodist_libkea_eval_la_SOURCES = eval_messages.h eval_messages.cc + libkea_eval_la_CXXFLAGS = $(AM_CXXFLAGS) libkea_eval_la_CPPFLAGS = $(AM_CPPFLAGS) libkea_eval_la_LIBADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la libkea_eval_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la +libkea_eval_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la +libkea_eval_la_LIBADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) + libkea_eval_la_LDFLAGS = -no-undefined -version-info 3:0:0 -libkea_eval_la_LDFLAGS += $(LOG4CPLUS_LIBS) $(CRYPTO_LDFLAGS) +libkea_eval_la_LDFLAGS += $(CRYPTO_LDFLAGS) EXTRA_DIST = eval.dox EXTRA_DIST += eval_messages.mes @@ -29,6 +35,7 @@ eval_messages.h eval_messages.cc: s-messages s-messages: eval_messages.mes $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/eval/eval_messages.mes + touch $@ # Tell Automake that the eval_messages.{cc,h} source files are created in the # build process, so it must create these before doing anything else. Although @@ -39,4 +46,4 @@ s-messages: eval_messages.mes # first. BUILT_SOURCES = eval_messages.h eval_messages.cc -CLEANFILES = eval_messages.h eval_messages.cc +CLEANFILES = eval_messages.h eval_messages.cc s-messages diff --git a/src/lib/eval/tests/Makefile.am b/src/lib/eval/tests/Makefile.am index d220b2be46..c127429b61 100644 --- a/src/lib/eval/tests/Makefile.am +++ b/src/lib/eval/tests/Makefile.am @@ -2,6 +2,8 @@ SUBDIRS = . AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib AM_CPPFLAGS += $(BOOST_INCLUDES) +AM_CPPFLAGS += -DLOGGING_SPEC_FILE=\"$(abs_top_srcdir)/src/lib/dhcpsrv/logging.spec\" + AM_CXXFLAGS = $(KEA_CXXFLAGS) # Some versions of GCC warn about some versions of Boost regarding diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index 4701976865..5720158ca3 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include #include @@ -90,13 +91,11 @@ TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) { length = boost::lexical_cast(len_str); } } catch (const boost::bad_lexical_cast&) { -#if 0 - // Logging not yet built LOG_DEBUG(eval_logger, EVAL_DBG_TRACE, EVAL_SUBSTRING_BAD_PARAM_CONVERSION) .arg(start_str) .arg(len_str); -#endif + values.push(""); return; } From 358927b0a2616be496002777dad09250202339b4 Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Mon, 2 Nov 2015 13:25:34 -0800 Subject: [PATCH 4/5] [trac4090] Add the forgotten eval_log.c and eval_log.h files --- src/lib/eval/eval_log.cc | 26 +++++++++++++++++++++ src/lib/eval/eval_log.h | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/lib/eval/eval_log.cc create mode 100644 src/lib/eval/eval_log.h diff --git a/src/lib/eval/eval_log.cc b/src/lib/eval/eval_log.cc new file mode 100644 index 0000000000..35128f6ae5 --- /dev/null +++ b/src/lib/eval/eval_log.cc @@ -0,0 +1,26 @@ +// Copyright (C) 2015 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 Eval (classification) code + +#include + +namespace isc { +namespace dhcp { + +isc::log::Logger eval_logger("eval"); + +} // namespace dhcp +} // namespace isc + diff --git a/src/lib/eval/eval_log.h b/src/lib/eval/eval_log.h new file mode 100644 index 0000000000..fb39198d25 --- /dev/null +++ b/src/lib/eval/eval_log.h @@ -0,0 +1,49 @@ +// Copyright (C) 2015 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 EVAL_LOG_H +#define EVAL_LOG_H + +#include +#include + +namespace isc { +namespace dhcp { + +/// @brief Eval debug Logging levels +/// +/// Defines the levels used to output debug messages in the eval (classification) code. +/// Note that higher numbers equate to more verbose (and detailed) output. + +// The first level traces normal operations, +const int EVAL_DBG_TRACE = DBGLVL_TRACE_BASIC; + +// The next level traces each call to hook code. +const int EVAL_DBG_CALLS = DBGLVL_TRACE_BASIC_DATA; + +// Additional information on the calls. Report each call to a callout (even +// if there are multiple callouts on a hook) and each status return. +const int EVAL_DBG_EXTENDED_CALLS = DBGLVL_TRACE_DETAIL_DATA; + +/// @brief Eval Logger +/// +/// Define the logger used to log messages. We could define it in multiple +/// modules, but defining in a single module and linking to it saves time and +/// space. +extern isc::log::Logger eval_logger; + +} // namespace dhcp +} // namespace isc + +#endif // EVAL_LOG_H From d87d517b8edf0307d0d3a70c2be2ea19b398308f Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Mon, 2 Nov 2015 16:38:50 -0800 Subject: [PATCH 5/5] [trac4090] Update per second set of review comments Remove change log entry as it isn't needed Update eval log description in user guide. --- ChangeLog | 4 ---- doc/guide/logging.xml | 8 ++++---- src/lib/eval/Makefile.am | 1 + 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8058ef04bf..cd2ad8527b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,3 @@ -XXXX. [func] sar - Added client classification substring token. - (Trac #4090, git - 1041. [func] tomek A new library, libkea-eval has been edded. It is not functional yet, but its purpose is to provide a generic expression diff --git a/doc/guide/logging.xml b/doc/guide/logging.xml index 0924c152ac..25dd24749e 100644 --- a/doc/guide/logging.xml +++ b/doc/guide/logging.xml @@ -221,8 +221,8 @@ kea-dhcp4.eval - this logger is used - to log messages relating to the evaluation code, primarily used - by the client classification routines. + to log messages relating to the client classification expression + evaluation code. kea-dhcp4.hooks - this logger is used @@ -309,8 +309,8 @@ kea-dhcp6.eval - this logger is used - to log messages relating to the evaluation code, primarily used - by the client classification routines. + to log messages relating to the client classification expression + evaluation code. kea-dhcp6.hooks - this logger is used diff --git a/src/lib/eval/Makefile.am b/src/lib/eval/Makefile.am index b8a833c9af..05c4902e08 100644 --- a/src/lib/eval/Makefile.am +++ b/src/lib/eval/Makefile.am @@ -22,6 +22,7 @@ libkea_eval_la_CPPFLAGS = $(AM_CPPFLAGS) libkea_eval_la_LIBADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la libkea_eval_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la libkea_eval_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la +libkea_eval_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la libkea_eval_la_LIBADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) libkea_eval_la_LDFLAGS = -no-undefined -version-info 3:0:0