1
#include "source/extensions/matching/input_matchers/ip/matcher.h"
2

            
3
#include "envoy/matcher/matcher.h"
4

            
5
#include "source/common/network/utility.h"
6

            
7
namespace Envoy {
8
namespace Extensions {
9
namespace Matching {
10
namespace InputMatchers {
11
namespace IP {
12

            
13
namespace {
14
using ::Envoy::Matcher::MatchResult;
15

            
16
6
MatcherStats generateStats(absl::string_view prefix, Stats::Scope& scope) {
17
6
  return MatcherStats{IP_MATCHER_STATS(POOL_COUNTER_PREFIX(scope, prefix))};
18
6
}
19

            
20
} // namespace
21

            
22
Matcher::Matcher(std::vector<Network::Address::CidrRange> const& ranges,
23
                 absl::string_view stat_prefix,
24
                 Stats::Scope& stat_scope)
25
    : // We could put "false" instead of "true". What matters is that the IP
26
      // belongs to the trie. We could further optimize the storage of LcTrie in
27
      // this case by implementing an LcTrie<void> specialization that doesn't
28
      // store any associated data.
29
6
      trie_({{true, ranges}}), stats_(generateStats(stat_prefix, stat_scope)) {}
30

            
31
21
MatchResult Matcher::match(const Envoy::Matcher::DataInputGetResult& input) {
32
21
  auto data = input.stringData();
33
21
  if (!data) {
34
1
    return MatchResult::NoMatch;
35
1
  }
36
20
  if (data->empty()) {
37
1
    return MatchResult::NoMatch;
38
1
  }
39
19
  const auto ip = Network::Utility::parseInternetAddressNoThrow(std::string(*data));
40
19
  if (!ip) {
41
1
    stats_.ip_parsing_failed_.inc();
42
1
    ENVOY_LOG(debug, "IP matcher: unable to parse address '{}'", *data);
43
1
    return MatchResult::NoMatch;
44
1
  }
45
18
  if (!trie_.getData(ip).empty()) {
46
10
    return MatchResult::Matched;
47
10
  }
48
8
  return MatchResult::NoMatch;
49
18
}
50

            
51
} // namespace IP
52
} // namespace InputMatchers
53
} // namespace Matching
54
} // namespace Extensions
55
} // namespace Envoy