diff --git a/source/common/network/BUILD b/source/common/network/BUILD index 71640de28a2dc..e1c39dc90801a 100644 --- a/source/common/network/BUILD +++ b/source/common/network/BUILD @@ -103,7 +103,6 @@ envoy_cc_library( ":cidr_range_lib", ":utility_lib", "//source/common/common:assert_lib", - "//source/common/common:empty_string", ], ) diff --git a/source/common/network/lc_trie.cc b/source/common/network/lc_trie.cc index b60e51f261d58..cc91f9e3228f6 100644 --- a/source/common/network/lc_trie.cc +++ b/source/common/network/lc_trie.cc @@ -32,13 +32,14 @@ LcTrie::LcTrie(const std::vector(ipv6_prefixes, fill_factor, root_branching_factor)); } -std::string LcTrie::getTag(const Network::Address::InstanceConstSharedPtr& ip_address) const { +std::vector +LcTrie::getTags(const Network::Address::InstanceConstSharedPtr& ip_address) const { if (ip_address->ip()->version() == Address::IpVersion::v4) { Ipv4 ip = ntohl(ip_address->ip()->ipv4()->address()); - return ipv4_trie_->getTag(ip); + return ipv4_trie_->getTags(ip); } else { Ipv6 ip = Utility::Ip6ntohl(ip_address->ip()->ipv6()->address()); - return ipv6_trie_->getTag(ip); + return ipv6_trie_->getTags(ip); } } diff --git a/source/common/network/lc_trie.h b/source/common/network/lc_trie.h index c081e69f02102..1306a476c471c 100644 --- a/source/common/network/lc_trie.h +++ b/source/common/network/lc_trie.h @@ -10,7 +10,6 @@ #include "envoy/network/address.h" #include "common/common/assert.h" -#include "common/common/empty_string.h" #include "common/network/address_impl.h" #include "common/network/cidr_range.h" #include "common/network/utility.h" @@ -48,14 +47,13 @@ class LcTrie { /** * Retrieve the tag associated with the CIDR range that contains `ip_address`. Both IPv4 and IPv6 * addresses are supported. - * TODO(ccaraman): Change to getTags and std::vector when nested prefixes are - * supported. * @param ip_address supplies the IP address. - * @return tag from the CIDR range that contains 'ip_address'. An empty string is returned - * if no prefix contains 'ip_address' or there is no data for the IP version of the - * ip_address. + * @return a vector of tags from the CIDR ranges and IP addresses that contains 'ip_address'. An + * empty vector is returned if no prefix contains 'ip_address' or there is no data for the IP + * version of the ip_address. */ - std::string getTag(const Network::Address::InstanceConstSharedPtr& ip_address) const; + std::vector + getTags(const Network::Address::InstanceConstSharedPtr& ip_address) const; private: /** @@ -198,10 +196,10 @@ class LcTrie { /** * Retrieve the tag associated with the CIDR range that contains `ip_address`. * @param ip_address supplies the IP address in host byte order. - * @return the tag from the prefix that encompasses the input. An empty string is returned - * if no prefix in the LC Trie exists. + * @return a vector of tags from the CIDR ranges and IP addresses that encompasses the input. An + * empty vector is returned if the LC Trie is empty. */ - std::string getTag(const IpType& ip_address) const; + std::vector getTags(const IpType& ip_address) const; private: /** @@ -510,9 +508,11 @@ LcTrie::LcTrieInternal::LcTrieInternal( } template -std::string LcTrie::LcTrieInternal::getTag(const IpType& ip_address) const { +std::vector +LcTrie::LcTrieInternal::getTags(const IpType& ip_address) const { + std::vector return_vector; if (trie_.empty()) { - return EMPTY_STRING; + return return_vector; } LcNode node = trie_[0]; @@ -533,16 +533,19 @@ std::string LcTrie::LcTrieInternal::getTag(const IpType& i // /0 will match all IP addresses. if (ip_prefixes_[address].length_ == 0) { - return ip_prefixes_[address].tag_; + return_vector.push_back(ip_prefixes_[address].tag_); + // TODO(ccaraman): When nested prefixes are supported, should the /0 case be handled better? + return return_vector; } // Check the input IP address is within the CIDR range stored in ip_prefixes_[adr] by XOR'ing the // two values and checking that up until the length of the CIDR range the value is 0. IpType bitmask = ip_prefixes_[address].ip_ ^ ip_address; if (extractBits(0, ip_prefixes_[address].length_, bitmask) == 0) { - return ip_prefixes_[address].tag_; + return_vector.push_back(ip_prefixes_[address].tag_); } - return EMPTY_STRING; + // TODO(ccaraman): Search through the nested prefix structure. + return return_vector; } } // namespace LcTrie diff --git a/test/common/network/lc_trie_test.cc b/test/common/network/lc_trie_test.cc index e91dc102c6002..9a77df4e9ddda 100644 --- a/test/common/network/lc_trie_test.cc +++ b/test/common/network/lc_trie_test.cc @@ -32,9 +32,10 @@ class LcTrieTest : public testing::Test { } } - void expectIPAndTag(const std::vector>& test_output) { + void expectIPAndTags( + const std::vector>>& test_output) { for (const auto& kv : test_output) { - EXPECT_EQ(kv.second, trie_->getTag(Utility::parseInternetAddress(kv.first))); + EXPECT_EQ(kv.second, trie_->getTags(Utility::parseInternetAddress(kv.first))); } } @@ -64,17 +65,17 @@ TEST_F(LcTrieTest, IPv4Defaults) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"0.0.0.0", "tag_0"}, {"16.0.0.1", "tag_1"}, - {"40.0.0.255", "tag_2"}, {"64.0.130.0", "tag_3"}, - {"96.0.0.10", "tag_4"}, {"112.0.0.0", "tag_5"}, - {"128.0.0.1", "tag_6"}, {"160.0.0.1", "tag_7"}, - {"164.255.0.0", "tag_8"}, {"168.0.0.0", "tag_9"}, - {"176.0.0.1", "tag_10"}, {"184.0.0.1", "tag_11"}, - {"192.0.0.0", "tag_12"}, {"232.0.80.0", "tag_13"}, - {"233.0.0.1", "tag_14"}, {"::1", ""}, + std::vector>> test_case = { + {"0.0.0.0", {"tag_0"}}, {"16.0.0.1", {"tag_1"}}, + {"40.0.0.255", {"tag_2"}}, {"64.0.130.0", {"tag_3"}}, + {"96.0.0.10", {"tag_4"}}, {"112.0.0.0", {"tag_5"}}, + {"128.0.0.1", {"tag_6"}}, {"160.0.0.1", {"tag_7"}}, + {"164.255.0.0", {"tag_8"}}, {"168.0.0.0", {"tag_9"}}, + {"176.0.0.1", {"tag_10"}}, {"184.0.0.1", {"tag_11"}}, + {"192.0.0.0", {"tag_12"}}, {"232.0.80.0", {"tag_13"}}, + {"233.0.0.1", {"tag_14"}}, {"::1", {}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } // There was a bug in the C++ port that didn't update the index for the next address in the trie. @@ -101,17 +102,17 @@ TEST_F(LcTrieTest, RootBranchingFactor) { }; setup(cidr_range_strings, fill_factor, root_branching_factor); - std::vector> test_case = { - {"0.0.0.0", "tag_0"}, {"16.0.0.1", "tag_1"}, - {"40.0.0.255", "tag_2"}, {"64.0.130.0", "tag_3"}, - {"96.0.0.10", "tag_4"}, {"112.0.0.0", "tag_5"}, - {"128.0.0.1", "tag_6"}, {"160.0.0.1", "tag_7"}, - {"164.255.0.0", "tag_8"}, {"168.0.0.0", "tag_9"}, - {"176.0.0.1", "tag_10"}, {"184.0.0.1", "tag_11"}, - {"192.0.0.0", "tag_12"}, {"232.0.80.0", "tag_13"}, - {"233.0.0.1", "tag_14"}, {"::1", ""}, + std::vector>> test_case = { + {"0.0.0.0", {"tag_0"}}, {"16.0.0.1", {"tag_1"}}, + {"40.0.0.255", {"tag_2"}}, {"64.0.130.0", {"tag_3"}}, + {"96.0.0.10", {"tag_4"}}, {"112.0.0.0", {"tag_5"}}, + {"128.0.0.1", {"tag_6"}}, {"160.0.0.1", {"tag_7"}}, + {"164.255.0.0", {"tag_8"}}, {"168.0.0.0", {"tag_9"}}, + {"176.0.0.1", {"tag_10"}}, {"184.0.0.1", {"tag_11"}}, + {"192.0.0.0", {"tag_12"}}, {"232.0.80.0", {"tag_13"}}, + {"233.0.0.1", {"tag_14"}}, {"::1", {}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, IPv4AddressSizeBoundaries) { @@ -122,11 +123,13 @@ TEST_F(LcTrieTest, IPv4AddressSizeBoundaries) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"205.251.192.100", "tag_1"}, {"18.232.0.255", ""}, {"10.255.255.255", "tag_0"}, - {"52.220.191.10", "tag_1"}, {"10.255.255.254", "tag_2"}, - }; - expectIPAndTag(test_case); + std::vector>> test_case = { + {"205.251.192.100", {"tag_1"}}, + {"10.255.255.255", {"tag_0"}}, + {"52.220.191.10", {"tag_1"}}, + {"10.255.255.254", {"tag_2"}}, + {"18.232.0.255", {}}}; + expectIPAndTags(test_case); } TEST_F(LcTrieTest, IPv4Boundaries) { @@ -137,11 +140,11 @@ TEST_F(LcTrieTest, IPv4Boundaries) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"10.255.255.255", "tag_0"}, - {"205.251.192.100", "tag_2"}, + std::vector>> test_case = { + {"10.255.255.255", {"tag_0"}}, + {"205.251.192.100", {"tag_2"}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, IPv6) { @@ -151,14 +154,14 @@ TEST_F(LcTrieTest, IPv6) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"2400:ffff:ff00::", ""}, - {"2406:da00:2000::1", "tag_0"}, - {"2001:abcd:ef01:2345::1", "tag_1"}, - {"::1", "tag_0"}, - {"1.2.3.4", ""}, + std::vector>> test_case = { + {"2406:da00:2000::1", {"tag_0"}}, + {"2001:abcd:ef01:2345::1", {"tag_1"}}, + {"::1", {"tag_0"}}, + {"1.2.3.4", {}}, + {"2400:ffff:ff00::", {}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, IPv6AddressSizeBoundaries) { @@ -169,14 +172,14 @@ TEST_F(LcTrieTest, IPv6AddressSizeBoundaries) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"::1", "tag_0"}, - {"2406:da00:2000::1", "tag_0"}, - {"2001:abcd:ef01:2345::1", "tag_1"}, - {"::", "tag_2"}, - {"::2", ""}, + std::vector>> test_case = { + {"::1", {"tag_0"}}, + {"2406:da00:2000::1", {"tag_0"}}, + {"2001:abcd:ef01:2345::1", {"tag_1"}}, + {"::", {"tag_2"}}, + {"::2", {}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, IPv6Boundaries) { @@ -187,12 +190,12 @@ TEST_F(LcTrieTest, IPv6Boundaries) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"::1", "tag_2"}, - {"::2", "tag_2"}, - {"8000::1", "tag_0"}, + std::vector>> test_case = { + {"::1", {"tag_2"}}, + {"::2", {"tag_2"}}, + {"8000::1", {"tag_0"}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, CatchAllIPv4Prefix) { @@ -202,13 +205,13 @@ TEST_F(LcTrieTest, CatchAllIPv4Prefix) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"2001:abcd:ef01:2345::1", "tag_1"}, - {"1.2.3.4", "tag_0"}, - {"255.255.255.255", "tag_0"}, - {"2400:ffff:ff00::", ""}, + std::vector>> test_case = { + {"2001:abcd:ef01:2345::1", {"tag_1"}}, + {"1.2.3.4", {"tag_0"}}, + {"255.255.255.255", {"tag_0"}}, + {"2400:ffff:ff00::", {}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, CatchAllIPv6Prefix) { @@ -218,13 +221,12 @@ TEST_F(LcTrieTest, CatchAllIPv6Prefix) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"2001:abcd:ef01:2345::1", "tag_0"}, - {"1.2.3.4", "tag_1"}, - {"255.255.255.255", ""}, - {"abcd::343", "tag_0"}, - }; - expectIPAndTag(test_case); + std::vector>> test_case = { + {"2001:abcd:ef01:2345::1", {"tag_0"}}, + {"1.2.3.4", {"tag_1"}}, + {"abcd::343", {"tag_0"}}, + {"255.255.255.255", {}}}; + expectIPAndTags(test_case); } TEST_F(LcTrieTest, BothIpvVersions) { @@ -236,12 +238,17 @@ TEST_F(LcTrieTest, BothIpvVersions) { }; setup(cidr_range_strings); - std::vector> test_case = { - {"205.251.192.100", "tag_3"}, {"18.232.0.255", ""}, {"10.255.255.255", "tag_2"}, - {"52.220.191.10", "tag_3"}, {"2400:ffff:ff00::", ""}, {"2406:da00:2000::1", "tag_0"}, - {"2001:abcd:ef01:2345::1", "tag_1"}, {"::1", "tag_0"}, + std::vector>> test_case = { + {"205.251.192.100", {"tag_3"}}, + {"10.255.255.255", {"tag_2"}}, + {"52.220.191.10", {"tag_3"}}, + {"2406:da00:2000::1", {"tag_0"}}, + {"2001:abcd:ef01:2345::1", {"tag_1"}}, + {"::1", {"tag_0"}}, + {"18.232.0.255", {}}, + {"2400:ffff:ff00::", {}}, }; - expectIPAndTag(test_case); + expectIPAndTags(test_case); } TEST_F(LcTrieTest, NestedPrefixes) {