-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dns_filter: add support for wildcard name in DNS filter inline table #34588
Changes from all commits
dc1a66d
b29ec4c
ce796cb
39d87a3
957d8bc
ae8b3b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,19 @@ absl::string_view getDomainSuffix(const absl::string_view name) { | |
return name.substr(pos + 1); | ||
} | ||
|
||
absl::string_view getVirtualDomainName(const absl::string_view domain_name) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we call this function getWildcardDomainName? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be incorrect. It returns not only wildcard domain names but any name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's okay to me then. |
||
// We can use names started with '.' as wildcard records in virtual domain name config | ||
// since these are not valid domain names and in this way we optimize for future search against | ||
// them. We expect only names like *.foo.com as a valid wildcard records because any other | ||
// wildcard usages are not considered as valid ones, i.e. **.foo.com, *foo.bar.com, foo*.bar.com | ||
// are all invalid. | ||
if (domain_name.starts_with("*.")) { | ||
return domain_name.substr(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the domain_name is invalid, like just "*.". This will return an empty string. Can we handle it correctly? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If domain is |
||
} | ||
|
||
return domain_name; | ||
} | ||
|
||
} // namespace Utils | ||
} // namespace DnsFilter | ||
} // namespace UdpFilters | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2433,6 +2433,133 @@ stat_prefix: "my_prefix" | |
EXPECT_EQ(1, config_->stats().known_domain_queries_.value()); | ||
} | ||
|
||
TEST_F(DnsFilterTest, WildcardName) { | ||
InSequence s; | ||
|
||
const std::string wildcard_virtual_domain = R"EOF( | ||
stat_prefix: "my_prefix" | ||
server_config: | ||
inline_dns_table: | ||
external_retry_count: 0 | ||
virtual_domains: | ||
- name: "*.foobaz.com" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add some tests for invalid virtual_domain test, like ".com", ".", "com", and see whether there is any issue? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I mentioned above, invalid domains will be accepted by envoy and (do not) work due to lack of validations.
|
||
endpoint: | ||
address_list: | ||
address: | ||
- "10.0.0.1" | ||
)EOF"; | ||
setup(wildcard_virtual_domain); | ||
|
||
const std::list<std::string> expected_address{"10.0.0.1"}; | ||
const std::string domain("www.foobaz.com"); | ||
|
||
const std::string query = | ||
Utils::buildQueryForDomain(domain, DNS_RECORD_TYPE_A, DNS_RECORD_CLASS_IN); | ||
ASSERT_FALSE(query.empty()); | ||
sendQueryFromClient("10.0.0.1:1000", query); | ||
|
||
response_ctx_ = ResponseValidator::createResponseContext(udp_response_, counters_); | ||
EXPECT_TRUE(response_ctx_->parse_status_); | ||
EXPECT_EQ(DNS_RESPONSE_CODE_NO_ERROR, response_ctx_->getQueryResponseCode()); | ||
|
||
for (const auto& answer : response_ctx_->answers_) { | ||
EXPECT_EQ(answer.first, domain); | ||
Utils::verifyAddress(expected_address, answer.second); | ||
} | ||
|
||
// Validate stats | ||
EXPECT_EQ(1, config_->stats().downstream_rx_queries_.value()); | ||
EXPECT_EQ(1, config_->stats().known_domain_queries_.value()); | ||
} | ||
|
||
TEST_F(DnsFilterTest, WildcardSubdomainPrevails) { | ||
InSequence s; | ||
|
||
const std::string wildcard_with_subdomain_virtual_domain = R"EOF( | ||
stat_prefix: "my_prefix" | ||
server_config: | ||
inline_dns_table: | ||
external_retry_count: 0 | ||
virtual_domains: | ||
- name: "*.foo1.com" | ||
endpoint: | ||
address_list: | ||
address: | ||
- "10.0.0.1" | ||
- name: "*.foo2.foo1.com" | ||
endpoint: | ||
address_list: | ||
address: | ||
- "10.0.0.2" | ||
)EOF"; | ||
setup(wildcard_with_subdomain_virtual_domain); | ||
|
||
const std::list<std::string> expected_address{"10.0.0.2"}; | ||
const std::string domain("www.foo2.foo1.com"); | ||
|
||
const std::string query = | ||
Utils::buildQueryForDomain(domain, DNS_RECORD_TYPE_A, DNS_RECORD_CLASS_IN); | ||
ASSERT_FALSE(query.empty()); | ||
sendQueryFromClient("10.0.0.1:1000", query); | ||
|
||
response_ctx_ = ResponseValidator::createResponseContext(udp_response_, counters_); | ||
EXPECT_TRUE(response_ctx_->parse_status_); | ||
EXPECT_EQ(DNS_RESPONSE_CODE_NO_ERROR, response_ctx_->getQueryResponseCode()); | ||
|
||
for (const auto& answer : response_ctx_->answers_) { | ||
EXPECT_EQ(answer.first, domain); | ||
Utils::verifyAddress(expected_address, answer.second); | ||
} | ||
|
||
// Validate stats | ||
EXPECT_EQ(1, config_->stats().downstream_rx_queries_.value()); | ||
EXPECT_EQ(1, config_->stats().known_domain_queries_.value()); | ||
} | ||
|
||
TEST_F(DnsFilterTest, WildcardExactNamePrevails) { | ||
InSequence s; | ||
|
||
const std::string wildcard_and_exact_name_virtual_domain = R"EOF( | ||
stat_prefix: "my_prefix" | ||
server_config: | ||
inline_dns_table: | ||
external_retry_count: 0 | ||
virtual_domains: | ||
- name: "*.foo1.com" | ||
endpoint: | ||
address_list: | ||
address: | ||
- "10.0.0.1" | ||
- name: "bar.foo1.com" | ||
endpoint: | ||
address_list: | ||
address: | ||
- "10.0.0.2" | ||
)EOF"; | ||
setup(wildcard_and_exact_name_virtual_domain); | ||
|
||
const std::list<std::string> expected_address{"10.0.0.2"}; | ||
const std::string domain("bar.foo1.com"); | ||
|
||
const std::string query = | ||
Utils::buildQueryForDomain(domain, DNS_RECORD_TYPE_A, DNS_RECORD_CLASS_IN); | ||
ASSERT_FALSE(query.empty()); | ||
sendQueryFromClient("10.0.0.1:1000", query); | ||
|
||
response_ctx_ = ResponseValidator::createResponseContext(udp_response_, counters_); | ||
EXPECT_TRUE(response_ctx_->parse_status_); | ||
EXPECT_EQ(DNS_RESPONSE_CODE_NO_ERROR, response_ctx_->getQueryResponseCode()); | ||
|
||
for (const auto& answer : response_ctx_->answers_) { | ||
EXPECT_EQ(answer.first, domain); | ||
Utils::verifyAddress(expected_address, answer.second); | ||
} | ||
|
||
// Validate stats | ||
EXPECT_EQ(1, config_->stats().downstream_rx_queries_.value()); | ||
EXPECT_EQ(1, config_->stats().known_domain_queries_.value()); | ||
} | ||
|
||
} // namespace | ||
} // namespace DnsFilter | ||
} // namespace UdpFilters | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we getDomainSuffix(virtual_domain.name()),
or getDomainSuffix( Utils::getVirtualDomainName(virtual_domain.name()))
Can these two return different result in some cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I thought about this (getting suffix of "initial" input domain name). But with current implementation result should always be the same and for me it makes more sense to extract suffix after manipulations