-
Notifications
You must be signed in to change notification settings - Fork 5.4k
network/config: Add IPv6 DNS support #1002
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
Changes from all commits
b292f3f
41f290f
c6ca161
536a204
c17cd01
9ba1839
3ff5df7
5c45591
5588ebe
759c5e4
2b24ec3
554fb2e
405fd79
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 |
|---|---|---|
|
|
@@ -52,26 +52,51 @@ void DnsResolverImpl::PendingResolution::onAresHostCallback(int status, hostent* | |
| delete this; | ||
| return; | ||
| } | ||
| if (status == ARES_SUCCESS || !fallback_if_failed_) { | ||
| completed_ = true; | ||
| } | ||
|
|
||
| std::list<Address::InstanceConstSharedPtr> address_list; | ||
| completed_ = true; | ||
| if (status == ARES_SUCCESS) { | ||
| ASSERT(hostent->h_addrtype == AF_INET); | ||
| for (int i = 0; hostent->h_addr_list[i] != nullptr; ++i) { | ||
| ASSERT(hostent->h_length == sizeof(in_addr)); | ||
| sockaddr_in address; | ||
| memset(&address, 0, sizeof(address)); | ||
| // TODO(mattklein123): IPv6 support. | ||
| address.sin_family = AF_INET; | ||
| address.sin_port = 0; | ||
| address.sin_addr = *reinterpret_cast<in_addr*>(hostent->h_addr_list[i]); | ||
| address_list.emplace_back(new Address::Ipv4Instance(&address)); | ||
| if (hostent->h_addrtype == AF_INET) { | ||
| for (int i = 0; hostent->h_addr_list[i] != nullptr; ++i) { | ||
| ASSERT(hostent->h_length == sizeof(in_addr)); | ||
| sockaddr_in address; | ||
| memset(&address, 0, sizeof(address)); | ||
| address.sin_family = AF_INET; | ||
| address.sin_port = 0; | ||
| address.sin_addr = *reinterpret_cast<in_addr*>(hostent->h_addr_list[i]); | ||
| address_list.emplace_back(new Address::Ipv4Instance(&address)); | ||
| } | ||
| } else if (hostent->h_addrtype == AF_INET6) { | ||
| for (int i = 0; hostent->h_addr_list[i] != nullptr; ++i) { | ||
| ASSERT(hostent->h_length == sizeof(in6_addr)); | ||
| sockaddr_in6 address; | ||
| memset(&address, 0, sizeof(address)); | ||
| address.sin6_family = AF_INET6; | ||
| address.sin6_port = 0; | ||
| address.sin6_addr = *reinterpret_cast<in6_addr*>(hostent->h_addr_list[i]); | ||
| address_list.emplace_back(new Address::Ipv6Instance(address)); | ||
|
Member
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. Unrelated to your review, but it seems weird that the |
||
| } | ||
| } | ||
| } | ||
| if (!cancelled_) { | ||
| callback_(std::move(address_list)); | ||
|
|
||
| if (completed_) { | ||
| if (!cancelled_) { | ||
| callback_(std::move(address_list)); | ||
| } | ||
| if (owned_) { | ||
| delete this; | ||
| return; | ||
| } | ||
| } | ||
| if (owned_) { | ||
| delete this; | ||
|
|
||
| if (status != ARES_SUCCESS && fallback_if_failed_) { | ||
| fallback_if_failed_ = false; | ||
| getHostByName(AF_INET); | ||
| // Note: Nothing can follow this call to getHostByName due to deletion of this | ||
| // object upon synchronous resolution. | ||
| return; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -115,17 +140,26 @@ void DnsResolverImpl::onAresSocketStateChange(int fd, int read, int write) { | |
| (write ? Event::FileReadyType::Write : 0)); | ||
| } | ||
|
|
||
| ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, ResolveCb callback) { | ||
| std::unique_ptr<PendingResolution> pending_resolution(new PendingResolution()); | ||
| pending_resolution->callback_ = callback; | ||
| ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, | ||
| DnsLookupFamily dns_lookup_family, ResolveCb callback) { | ||
| // TODO(hennna): Add DNS caching which will allow testing the edge case of a | ||
| // failed intial call to getHostbyName followed by a synchronous IPv4 | ||
| // resolution. | ||
| std::unique_ptr<PendingResolution> pending_resolution( | ||
| new PendingResolution(callback, channel_, dns_name)); | ||
| if (dns_lookup_family == DnsLookupFamily::Auto) { | ||
| pending_resolution->fallback_if_failed_ = true; | ||
| } | ||
|
|
||
| ares_gethostbyname(channel_, dns_name.c_str(), | ||
| AF_INET, [](void* arg, int status, int timeouts, hostent* hostent) { | ||
| static_cast<PendingResolution*>(arg)->onAresHostCallback(status, hostent); | ||
| UNREFERENCED_PARAMETER(timeouts); | ||
| }, pending_resolution.get()); | ||
| if (dns_lookup_family == DnsLookupFamily::V4Only) { | ||
| pending_resolution->getHostByName(AF_INET); | ||
| } else { | ||
| pending_resolution->getHostByName(AF_INET6); | ||
| } | ||
|
|
||
| if (pending_resolution->completed_) { | ||
| // Resolution does not need asynchronous behavior or network events. For | ||
| // example, localhost lookup. | ||
| return nullptr; | ||
| } else { | ||
| // The PendingResolution will self-delete when the request completes | ||
|
|
@@ -135,5 +169,12 @@ ActiveDnsQuery* DnsResolverImpl::resolve(const std::string& dns_name, ResolveCb | |
| } | ||
| } | ||
|
|
||
| void DnsResolverImpl::PendingResolution::getHostByName(int family) { | ||
| ares_gethostbyname(channel_, dns_name_.c_str(), | ||
|
Member
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 discussed IRL last week,
Contributor
Author
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 also seems that AF_UNSPEC has unexpected behavior (not a straightforward IPv6 lookup followed by a IPv4 lookup). Once that and returning multiple address types is added to the c-ares library, we can switch over to using AF_UNSPEC. |
||
| family, [](void* arg, int status, int, hostent* hostent) { | ||
| static_cast<PendingResolution*>(arg)->onAresHostCallback(status, hostent); | ||
| }, this); | ||
| } | ||
|
|
||
| } // Network | ||
| } // Envoy | ||
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.
Docs say
fallback, but it'sautohere.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.
I actually, like 'auto' for consistency with other settings (just fix the doc)
Uh oh!
There was an error while loading. Please reload this page.
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.
The problem with auto is that it's a keyword and can't be used when making the string to enum conversion.
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.
bummer :(
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.
Actually AUTO might be okay