Skip to content

network dns: fix AUTO settings to properly fallback to v4 lookup when v6 returns only cname entries#2641

Merged
alyssawilk merged 3 commits intoenvoyproxy:masterfrom
glicht:dns-fix
Mar 5, 2018
Merged

network dns: fix AUTO settings to properly fallback to v4 lookup when v6 returns only cname entries#2641
alyssawilk merged 3 commits intoenvoyproxy:masterfrom
glicht:dns-fix

Conversation

@glicht
Copy link
Copy Markdown
Contributor

@glicht glicht commented Feb 19, 2018

network dns: fix AUTO settings to properly fallback to v4 lookup when v6 returns only cname entries

Description:

Fixes #2634

Fixed dns_impl.cc to assume completed only when actual ips are returned from a v6 lookup.

Risk Level: Low

Testing:

Release Notes: N/A

…returns only cname entries

Fixes envoyproxy#2634

Added unit tests to test the CNAME scenario where a v6 lookup retuns only cnames. Fixed dns_impl.cc to assume completed only when actuall ips are returned from a v6 lookup.

Signed-off-by: Guy Lichtman <guy@lichtman.io>
@glicht glicht changed the title network: fix AUTO settings to properly fallback to v4 lookup when v6 returns only cname entries network dns: fix AUTO settings to properly fallback to v4 lookup when v6 returns only cname entries Feb 19, 2018
@alyssawilk
Copy link
Copy Markdown
Contributor

@junr03 you up for doing first pass?

Copy link
Copy Markdown
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the delay @glicht. Expect a much faster turn around going forward


~TestDnsServerQuery() { connection_->close(ConnectionCloseType::NoFlush); }

// Utility to encode a dns string in the rfc format. Example: \004some\004good\006domain
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link to RFC in the comment

write_buffer_.add(&response_size_n, sizeof(response_size_n));
write_buffer_.add(response_base, response_base_len);

// create a resource record for cname if we have
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we have a cname

hostLookup = cname.c_str();
encodedCname = TestDnsServerQuery::encodeDnsName(cname);
ip_question = reinterpret_cast<const unsigned char*>(encodedCname.c_str());
ip_name_len = encodedCname.size() + 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry if I am being dense, but why do we have +1 here and below in the response_cname_len calculation? It might be worthwhile to sprinkle some clarifying comments in order to ease a new reader into faster understanding

Copy link
Copy Markdown
Contributor Author

@glicht glicht Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, as the encoded cname format always ends with a null (0) char which also needs to be written out. Will add this in a comment.

}
size_t response_cname_len =
encodedCname.size() > 0 ? name_len + RRFIXEDSZ + encodedCname.size() + 1 : 0;
// Send response to client.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment makes this section a little confusing.

Previously, we computed all the elements of the response and then wrote them all to the client.

In this PR we have moved to computing and writing in lockstep on each piece of the request.

I think we should either refactor to how it was previously done (compute then write all), or change the comments (the one this review comment hangs off of, add a comment above line 171 size_t response_ip_rest_len, etc)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree the cname flow is a bit confusing. First there is need to see if a domain name resolves to a cname entry. Then there is need to lookup the cname record to see if it resolves to an ip or multiple ips. We still need to compute the total response size before starting to write each response element. This is computed with the variable: response_size_n. After writing out the header response, then we need to write out all response elements which include the cname entry and the ips. I'll add a comment to better explain this logic.

Signed-off-by: Guy Lichtman <guy@lichtman.io>
@glicht
Copy link
Copy Markdown
Contributor Author

glicht commented Mar 1, 2018

@junr03, I've added some more comments following your code review. Let me know if you see need for more changes.

@junr03
Copy link
Copy Markdown
Member

junr03 commented Mar 1, 2018

@alyssawilk looks fine to me. Want to give a pass?

Copy link
Copy Markdown
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix and the comprehensive testing! Only a few minor nits on my end.

auto name_split = StringUtil::splitToken(input, ".");
std::string res;
for (const auto& it : name_split) {
res += static_cast<char>(it.size());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you toss in an assert on the total size, just to make it super clear it won't work with illegally long DNS names?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

encodedCname.size() > 0 ? name_len + RRFIXEDSZ + encodedCname.size() + 1 : 0;
const uint16_t response_size_n =
htons(response_base_len + response_ip_rest_len + response_cname_len);
Buffer::OwnedImpl write_buffer_;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is local scope you don't need the trailing _ - that's only for member variables

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eyes of a falcon, totally missed it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trailing "_" was present before my changes, so I didn't really give this thought. Anyway, I'll add a commit to change the name of the variable.

DNS_HEADER_SET_ANCOUNT(response_base, answer_size);
DNS_HEADER_SET_NSCOUNT(response_base, 0);
DNS_HEADER_SET_ARCOUNT(response_base, 0);
// Total response size will be computed according to cname response size + ip response sizes
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional - this function is getting reaaally long. If there's anything else you can easily factor into a utility helper that'd be nice. Optional because it's test code and you've done a great job with comments and variable names.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll pass on this. I agree the function is getting long. But, I am not too sure that refactoring will make this easier to understand.

Signed-off-by: Guy Lichtman <guy@lichtman.io>
@glicht
Copy link
Copy Markdown
Contributor Author

glicht commented Mar 2, 2018

@alyssawilk, I've added a commit following your code review. Let me know if you see need for more changes.

Copy link
Copy Markdown
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay - I'm out Fridays. LGTM!

@alyssawilk
Copy link
Copy Markdown
Contributor

@junr03 LGTY? I can only force-merge while github has you flagged as having requested changes :-/

@alyssawilk alyssawilk merged commit f194fa2 into envoyproxy:master Mar 5, 2018
lita pushed a commit to lita/envoy that referenced this pull request Mar 5, 2018
…kup when v6 returns only cname entries (envoyproxy#2641)"

This reverts commit f194fa2.
jpsim pushed a commit that referenced this pull request Nov 28, 2022
Disable flaky TestConfig.StringAccessors util the cause of flakiness is addressed.

#2641
Risk Level: Low
Testing: N/A
Docs Changes: N/A
Release Notes: N/A

Signed-off-by: Ryan Hamilton rch@google.com
Signed-off-by: JP Simard <jp@jpsim.com>
jpsim pushed a commit that referenced this pull request Nov 29, 2022
Disable flaky TestConfig.StringAccessors util the cause of flakiness is addressed.

#2641
Risk Level: Low
Testing: N/A
Docs Changes: N/A
Release Notes: N/A

Signed-off-by: Ryan Hamilton rch@google.com
Signed-off-by: JP Simard <jp@jpsim.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DNS lookup AUTO settings doesn't fallback to V4 when a single CNAME entry is returned

3 participants