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
Raku needs better ways to deal with network addresses #111
Comments
|
These leads me to think that there should be an op for doing DNS lookups that would take a hostname or socket address and return a list of addresses. The socket connect and bind ops could take one address at a time instead of dealing with them all at once, so the behaviour for how errors would be handled when attempting to use them would be dealt with from Rakudo, allowing people to change how they're handled if desired. Inconsistencies with how addresses are resolved would be harder to make from then on. If this is how it should be handled though, then with a DNS op existing, why not provide a basic DNS API that people could do lookups and reverse lookups with? |
|
I think we also need to think through IPv4 + IPv6. I.E. there should be a lookup that only returns IPv4 addresses if and only if the host is IPv4-only, but returns both if the host is dual-stacked (I suppose it should also only do IPv6 if the host is IPv6-only). There is also some host preference stuff that as to which address families and what order they should be in. There should be a different way to get all addresses (maybe "A" or "AAAA" records). I'd like to see us support IPv6 as a first class citizen, just like we do for Unicode. |
|
With the improvements to hostname lookup, IPv4 addresses only get returned if the interface used supports it, and ditto for IPv6 addresses. But there currently isn't a way to get both A and AAAA records regardless of whether or not the interface used supports it, which is what it was doing before (though it'd only use the first address received). |
|
The way I had planned out the work I'm doing for the IP6NS grant, there would be the same degree of support for IPv6 as there is for IPv4. This is partially implemented for |
|
Perhaps some allomorph that would contain both IPv4 and IPv6 value? I guess then the question becomes: how do we decide which to use when? |
|
There must be a way to manually specify which address to use, no matter what type of address it is and wether it is source or destination. Consider a corporate network to which I connect over VPN. Good if my system is smart enough to bind the connection to the VPN interface, but what if it's not? Similarly, if a name resolves to more than one IP sometimes it is important to choose the preferred one manually. |
|
Perhaps a dynamic variable indicating preference? |
|
This would be a headache if a big system would require different binding for different connections. Why can't we have a unified address kind of type? Say, similar to perl5, Respectively:
|
|
I think it'd be a good idea to have one unified address type, but I don't think that type is where DNS queries should be handled from, since there are other types of DNS records besides How I think this could be solved sums up to this:
Combined, this could allow people to customize how my IO::Socket::INET:D $client .= connect: 'www.google.com', 443;And addresses could be used directly for this instead, if desired: # Connect to all addresses resolved for a hostname.
race for $*RESOLVER.resolve: 'www.google.com', 443 -> IO::Address:D $address {
my IO::Socket::INET:D $client .= connect: $address;
# ...
}But if the result of using addresses directly like this is one socket and the behaviour for handling addresses is consistent for both binding and connecting, this would be better written using # Replicate the current behaviour for hostname resolution.
sub CONNECT(@addresses, &callback) {
callback @addresses.head
}
my IO::Socket::INET:D $client .= connect: 'www.google.com', 443; |
|
I love your plan!
|
|
Update:
|
|
The v6.e changes are doable as well! I tried to use c-ares to implement them on MoarVM, but I found there were a couple of issues with it that made it less than ideal to use:
For these reasons, I chose UDNS to handle DNS on MoarVM instead. This library is also much simpler to get to work properly with the I/O event loop. While working on v6.e's changes, I found the new |
|
My design for how DNS resolution should be implemented has changed since my previous posts here. There is now an My strategy to implement At the same time, since There is another strategy we could use, which would ease the workload on backend authors in the future, and allow us to have a much more powerful DNS resolver than any other language I've used thus far, and that is to implement a stub resolver ourselves. In order to do this, we need full TCP and UDP support for Is this a good idea to be doing? If so, what sort of channels do we have for people to report security problems in the language? |
|
Just a quick thought: a full blown DNS resolver implementation in Raku is
probably best developed as a module first. That's a nicer development
environment anyway (avoiding the minute of compilation time). If you do so,
you'll want a way to plug this implementation in, so Rakudo will use it. But
then, will there even be a need to pull the implementation into the core?
|
|
Which resolver Edit: in order for this to actually fix this issue, v6.e still needs its own connection and binding logic. This can be borrowed from Happy Eyeballs v2, since that part of the algorithm stands on its own. |
There are a couple issues with how network addresses are handled at the moment:
connect,bindsock,asyncconnect,asynclisten, andasyncudpops try to use all addresses received from a DNS lookup rather than just the first. The issue with this, as @niner pointed out, is this is that all errors when connecting/binding except the one when attempting to use the final address received are silent, but people cannot change this behaviour to suit their needs.IO::Socket::INETandIO::Socket::Asyncdeal with resolving addresses is inconsistent;IO::Socket::INETsupports resolving socket addresses and hostnames, whileIO::Socket::Asynconly supports resolving hostnames.The text was updated successfully, but these errors were encountered: