Skip to content
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

Add more control over how the connection and resolution is established #2418

Open
MOZGIII opened this issue Feb 4, 2021 · 10 comments
Open

Comments

@MOZGIII
Copy link

MOZGIII commented Feb 4, 2021

I need to have more control over whether the IPv4/IPv6 is used.

There are two parts to this.

Part 1: DNS

I'd like to have control over what IP protocol version is requested during the DNS resolution. This means hinting whether the A/AAAA records are requested during the resolution. The GaiResolver relies on the getaddrinfo under the hood, which has rich functionality allowing all the necessary flexibility, however, the API currently doesn't expose any of that. I know this might be due to the cross-platform compatibility needs, but I wonder what does it take to land it.

Part 2: Explicit IPv4 / IPv6 / Dual-stack sockets use in HttpConnector

The HttpConnector has a lot of logic built-in to support both IPv4 and IPv6 sockets. However, as of right now, there's no way to explicitly make it use only IPv4, IPv6 or dual-stack. Given its internal complexity, I think the best route would be implementing a custom connector. I still wanted to mention it though, because it might be valuable feedback, and would welcome it if this functionality was available in the crate.

@seanmonstar
Copy link
Member

I think you're right, there isn't really a way to pick that generally. You can specify to bind to a certain local address, and its IP version will force that decision. Additionally, "dual stack" is assumed unless binding disables it, or you disable the "happy eyeballs" timeout.

@seanmonstar
Copy link
Member

Regarding DNS, could you propose more? It's possible to provide your own resolver, which I assume could do exactly what you want. If proposing to add something specifically to GaiResolver, what would it be?

@MOZGIII
Copy link
Author

MOZGIII commented Feb 5, 2021

If proposing to add something specifically to GaiResolver, what would it be?

Exposing more of its bit would certainly help with building custom resolvers. If not that - a simple setting to request an A or AAAA record (or no preference) would be just enough for my needs. This can be achieved via setting ai_family of the getaddrinfo call to the matching value. With portability in mind, on Windows this is done via the addrinfoexW struct of a GetAddrInfoExW call.

@seanmonstar
Copy link
Member

Exposing more of its bit would certainly help with building custom resolvers.

Exactly which bits is what I'm asking :)

Note that GaiResolver is just using std::net::ToSocketAddrs, essentially, so we can't add extra flags. It should be straight forward to create a new resolver that uses libc::getaddrinfo directly.

@MOZGIII
Copy link
Author

MOZGIII commented Feb 5, 2021

Exposing more of its bit would certainly help with building custom resolvers.

Exactly which bits is what I'm asking :)

Note that GaiResolver is just using std::net::ToSocketAddrs, essentially, so we can't add extra flags. It should be straight forward to create a new resolver that uses libc::getaddrinfo directly.

It contains a thread pool, right? Exposing that would be useful. If it was exposed in such a way that I can swap out the std::net::ToSocketAddrs with the custom implementation - I'd be satisfied.

@seanmonstar
Copy link
Member

It utilizes Tokio's "blocking" threads, via tokio::task::spawn_blocking. The implementation is small.

@MOZGIII
Copy link
Author

MOZGIII commented Feb 5, 2021

Indeed, just checked - I think it's trivial to implement. There's a lot of boilerplate with regard to futures though.
I'll take a stab at building a custom resolver.

@MOZGIII
Copy link
Author

MOZGIII commented Feb 5, 2021

One of the notable things is the lack of impl From<Name> for String - which makes it a bit less efficient to work with.

@MOZGIII
Copy link
Author

MOZGIII commented Feb 6, 2021

Implemented a custom resolver that fits my needs: https://github.com/MOZGIII/hyper-system-resolver
I've utilized a backround::Resolver and it seems to be a good fit for being upstreamed into hyper. The main value that it provides is that it helps to wrap any blocking/spawnable implementation of the resolver with some non-impl and non-Box<dyn ...> types - which is a pretty common operation.

I've also discovered that it's possible to perform name resolution using system resolvers in the async fashion on Linux and Windows. Would be interesting to dig deeper into those.

@andrewtj
Copy link

andrewtj commented Feb 6, 2021

I've also discovered that it's possible to perform name resolution using system resolvers in the async fashion on Linux and Windows.

I believe getaddrinfo_a is implemented using threads so it may not be a clear win (though possibly this is dated information). On Apple platforms DNSServiceGetAddrInfo or DNSServiceQueryRecord can be used to do async resolution.

Does hyper intend to support the HTTPS RR? If so that might be an opportunity to make the interface less tied to single-shot name to A and AAAA resolution.

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

No branches or pull requests

3 participants