| /** @file | |
| A brief file description | |
| @section license License | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #pragma once | |
| #include "swoc/swoc_ip.h" | |
| #include "tscore/ink_inet.h" | |
| #include "tscore/Ptr.h" | |
| #include "proxy/logging/LogAccess.h" | |
| #include "proxy/logging/LogField.h" | |
| /*------------------------------------------------------------------------- | |
| LogFilter | |
| This is an abstract base class from which particular filters can be | |
| derived. Each filter must implement the "toss_this_entry" member | |
| function which, given a LogAccess object, returns true if | |
| the log entry is to be tossed out. | |
| -------------------------------------------------------------------------*/ | |
| class LogFilter : public RefCountObjInHeap | |
| { | |
| public: | |
| enum Type { | |
| INT_FILTER = 0, | |
| STRING_FILTER, | |
| IP_FILTER, | |
| N_TYPES, | |
| }; | |
| enum Action { | |
| REJECT = 0, | |
| ACCEPT, | |
| WIPE_FIELD_VALUE, | |
| N_ACTIONS, | |
| }; | |
| static const char *ACTION_NAME[]; | |
| // all operators "positive" (i.e., there is no NOMATCH operator anymore) | |
| // because one can specify through the "action" field if the record should | |
| // be kept or tossed away | |
| // | |
| enum Operator { | |
| MATCH = 0, | |
| CASE_INSENSITIVE_MATCH, | |
| CONTAIN, | |
| CASE_INSENSITIVE_CONTAIN, | |
| LT, | |
| LTE, | |
| GT, | |
| GTE, | |
| N_OPERATORS, | |
| }; | |
| static const char *OPERATOR_NAME[]; | |
| LogFilter(const char *name, LogField *field, Action action, Operator oper); | |
| ~LogFilter() override; | |
| char * | |
| name() const | |
| { | |
| return m_name; | |
| } | |
| Type | |
| type() const | |
| { | |
| return m_type; | |
| } | |
| size_t | |
| get_num_values() const | |
| { | |
| return m_num_values; | |
| } | |
| bool | |
| is_wipe() const | |
| { | |
| return m_action == WIPE_FIELD_VALUE; | |
| } | |
| virtual bool toss_this_entry(LogAccess *lad) = 0; | |
| virtual void display(FILE *fd = stdout) = 0; | |
| static LogFilter *parse(const char *name, Action action, const char *condition); | |
| protected: | |
| char *m_name; | |
| LogField *m_field; | |
| Action m_action; // the action this filter takes | |
| Operator m_operator; | |
| Type m_type; | |
| size_t m_num_values; // the number of comparison values | |
| public: | |
| LINK(LogFilter, link); // so we can create a LogFilterList | |
| // noncopyable | |
| LogFilter(const LogFilter &rhs) = delete; | |
| LogFilter &operator=(LogFilter &rhs) = delete; | |
| private: | |
| // -- member functions that are not allowed -- | |
| LogFilter(); | |
| }; | |
| /*------------------------------------------------------------------------- | |
| LogFilterString | |
| Filter for string fields. | |
| -------------------------------------------------------------------------*/ | |
| class LogFilterString : public LogFilter | |
| { | |
| public: | |
| LogFilterString(const char *name, LogField *field, Action a, Operator o, char *value); | |
| LogFilterString(const char *name, LogField *field, Action a, Operator o, size_t num_values, char **value); | |
| LogFilterString(const LogFilterString &rhs); | |
| ~LogFilterString() override; | |
| bool operator==(LogFilterString &rhs); | |
| bool toss_this_entry(LogAccess *lad) override; | |
| void display(FILE *fd = stdout) override; | |
| // noncopyable | |
| LogFilterString &operator=(LogFilterString &rhs) = delete; | |
| // This assumes that s1 is all uppercase, hence we hide this in here specifically | |
| static const char * | |
| strstrcase(const char *s0, const char *s1) | |
| { | |
| size_t len_s0 = std::strlen(s0); | |
| size_t len_s1 = std::strlen(s1); | |
| if (len_s1 > len_s0) { | |
| return nullptr; // If s1 is longer than s0, there's no match | |
| } | |
| const char *end = s0 + len_s0 - len_s1; | |
| while (s0 < end) { | |
| const char *h = s0; | |
| const char *n = s1; | |
| while (*n && (std::toupper(static_cast<unsigned char>(*h)) == *n)) { | |
| ++h; | |
| ++n; | |
| } | |
| if (!*n) { | |
| return s0; | |
| } | |
| ++s0; | |
| } | |
| return nullptr; | |
| } | |
| private: | |
| char **m_value = nullptr; // the array of values | |
| // these are used to speed up case insensitive operations | |
| // | |
| char **m_value_uppercase = nullptr; // m_value in all uppercase | |
| size_t *m_length = nullptr; // length of m_value string | |
| void _setValues(size_t n, char **value); | |
| // note: OperatorFunction's must return 0 (zero) if condition is satisfied | |
| // (as strcmp does) | |
| using OperatorFunction = int (*)(const char *, const char *); | |
| // return 0 if s1 is substring of s0 and 1 otherwise, to conform to strcmp etc. | |
| static int | |
| _isSubstring(const char *s0, const char *s1) | |
| { | |
| return (strstr(s0, s1) == nullptr ? 1 : 0); | |
| } | |
| // | |
| static int | |
| _isSubstringUpper(const char *s0, const char *s1) | |
| { | |
| return (strstrcase(s0, s1) == nullptr) ? 1 : 0; | |
| } | |
| bool _checkConditionAndWipe(OperatorFunction f, char *field_value, size_t field_value_length, char **val, bool uppercase = false); | |
| // -- member functions that are not allowed -- | |
| LogFilterString(); | |
| }; | |
| /*------------------------------------------------------------------------- | |
| LogFilterInt | |
| Filter for int fields. | |
| -------------------------------------------------------------------------*/ | |
| class LogFilterInt : public LogFilter | |
| { | |
| public: | |
| LogFilterInt(const char *name, LogField *field, Action a, Operator o, int64_t value); | |
| LogFilterInt(const char *name, LogField *field, Action a, Operator o, size_t num_values, int64_t *value); | |
| LogFilterInt(const char *name, LogField *field, Action a, Operator o, char *values); | |
| LogFilterInt(const LogFilterInt &rhs); | |
| ~LogFilterInt() override; | |
| bool operator==(LogFilterInt &rhs); | |
| bool toss_this_entry(LogAccess *lad) override; | |
| void display(FILE *fd = stdout) override; | |
| // noncopyable | |
| LogFilterInt &operator=(LogFilterInt &rhs) = delete; | |
| private: | |
| int64_t *m_value = nullptr; // the array of values | |
| void _setValues(size_t n, int64_t *value); | |
| int _convertStringToInt(char *val, int64_t *ival, LogFieldAliasMap *map); | |
| // -- member functions that are not allowed -- | |
| LogFilterInt(); | |
| }; | |
| /*------------------------------------------------------------------------- | |
| LogFilterIP | |
| Filter for IP fields using IpAddr. | |
| -------------------------------------------------------------------------*/ | |
| class LogFilterIP : public LogFilter | |
| { | |
| public: | |
| LogFilterIP(const char *name, LogField *field, Action a, Operator o, swoc::IPAddr value); | |
| LogFilterIP(const char *name, LogField *field, Action a, Operator o, size_t num_values, IpAddr *value); | |
| LogFilterIP(const char *name, LogField *field, Action a, Operator o, char *values); | |
| LogFilterIP(const LogFilterIP &rhs); | |
| ~LogFilterIP() override; | |
| bool operator==(LogFilterIP &rhs); | |
| bool toss_this_entry(LogAccess *lad) override; | |
| void display(FILE *fd = stdout) override; | |
| // noncopyable | |
| LogFilterIP &operator=(LogFilterIP &rhs) = delete; | |
| private: | |
| swoc::IPRangeSet m_addrs; | |
| /// Initialization common to all constructors. | |
| void init(); | |
| // Checks for a match on this filter. | |
| bool is_match(LogAccess *lad); | |
| // -- member functions that are not allowed -- | |
| LogFilterIP(); | |
| }; | |
| bool filters_are_equal(LogFilter *filt1, LogFilter *filt2); | |
| /*------------------------------------------------------------------------- | |
| LogFilterList | |
| -------------------------------------------------------------------------*/ | |
| class LogFilterList | |
| { | |
| public: | |
| LogFilterList(); | |
| ~LogFilterList(); | |
| bool operator==(LogFilterList &); | |
| void add(LogFilter *filter, bool copy = true); | |
| bool toss_this_entry(LogAccess *lad); | |
| LogFilter *find_by_name(const char *name); | |
| void clear(); | |
| LogFilter * | |
| first() const | |
| { | |
| return m_filter_list.head; | |
| } | |
| LogFilter * | |
| next(LogFilter *here) const | |
| { | |
| return (here->link).next; | |
| } | |
| unsigned count() const; | |
| void display(FILE *fd = stdout); | |
| // noncopyable | |
| // -- member functions that are not allowed -- | |
| LogFilterList(const LogFilterList &rhs) = delete; | |
| LogFilterList &operator=(const LogFilterList &rhs) = delete; | |
| private: | |
| Queue<LogFilter> m_filter_list; | |
| bool m_has_wipe = false; | |
| }; |