grpc-go icon indicating copy to clipboard operation
grpc-go copied to clipboard

dns: scoped literal IPv6 addresses should be supported

Open menghanl opened this issue 5 years ago • 22 comments

fe80::1ff:fe23:4567:890a%eth2 is a valid IPv6 address, and should be supported in the DNS resolver

net.Dial("dns:///fe80::1ff:fe23:4567:890a%eth2:8080")

It fails with ParseIP error now.

https://en.wikipedia.org/wiki/IPv6_address#Scoped_literal_IPv6_addresses

menghanl avatar Dec 18 '19 21:12 menghanl

Literal IPv6 addresses with zone identifer are supported by functions like net.Dial (https://github.com/golang/go/commit/aa0dda767a9a31c6b0b49a665f0d059ebfed8e1c), but not net.ParseIP. The default DNS resolver also supports this address.

A work-around now is to use passthrough as the resolver.

To solve this in the DNS resolver, we can remove the special code for IPs (so we don't call ParseIP), and let the default go DNS resolver handle everything.

menghanl avatar Dec 18 '19 21:12 menghanl

use [fdbd:dc02:ff:1:1:225:111:82]:9238 format will resolve

xujianhai666 avatar Jan 16 '20 08:01 xujianhai666

The issue is interesting, I'm willing to take this task up.

jackwener avatar Aug 18 '21 09:08 jackwener

@menghanl After I read code and your instruction, I think the solution is to remove net.ParseIP in formatIP but remain net.ParseIP in parseTarget. Is this right?

https://github.com/grpc/grpc-go/blob/a42567fe92f005c47e60146bdbb0d5f7fc232219/internal/resolver/dns/dns_resolver.go#L364

https://github.com/grpc/grpc-go/blob/a42567fe92f005c47e60146bdbb0d5f7fc232219/internal/resolver/dns/dns_resolver.go#L387

jackwener avatar Aug 18 '21 13:08 jackwener

It's not enough to remove net.ParseIP, because address will be not verified. We could still use ParseIP for verifying if it is in high version.

parseIPv6 support literal IPv6

jackwener avatar Aug 18 '21 14:08 jackwener

OMG,the solution above is wrong. The solution is removing the IP resolver , and let the default go DNS resolver handle everything. However, customAuthorityResolver call formatIP and parseTarget. There is still some wrong.

jackwener avatar Aug 18 '21 15:08 jackwener

I don't remember all the details about this issue. But I think if we want to keep our handling of IPs, we can update formatIP and parseTarget to handle scopes.

Seems it's as easy as finding the %: https://cs.opensource.google/go/go/+/refs/tags/go1.17:src/net/ip.go;l=592

If the DNS resolver can recognize this address, it can just return it as is, and net.Dial will handle it correctly.

Note that in ParseIP (and when used with gRPC), the address should be put in brackets dns:///[fe80::1ff:fe23:4567:890a%eth2]:8080

menghanl avatar Aug 18 '21 17:08 menghanl

Yes, I notice that dns:///[fe80::1ff:fe23:4567:890a%eth2]:8080 is supported instead of net.Dial("dns:///fe80::1ff:fe23:4567:890a%eth2:8080")

jackwener avatar Aug 19 '21 00:08 jackwener

Is there any solution for grpc.Dial to connect to ipv6 with scope? Maybe example? Now with passthrough returns error invalid URL escape

gknw avatar Sep 07 '22 14:09 gknw

Works for me:

tcp:[fe80::1ff:fe23:4567:890a%25eth2]:8080

url.Parse issue: https://github.com/golang/go/issues/30611

rfc6874:

In a URI, a literal IPv6 address is always embedded between "[" and
   "]".  This document specifies how a <zone_id> can be appended to the
   address.  According to URI syntax [[RFC3986](https://www.rfc-editor.org/rfc/rfc3986)], "%" is always treated as
   an escape character in a URI, so, according to the established URI
   syntax [[RFC3986](https://www.rfc-editor.org/rfc/rfc3986)] any occurrences of literal "%" symbols in a URI MUST
   be percent-encoded and represented in the form "%25".  Thus, the
   scoped address fe80::a%en1 would appear in a URI as
   http://[fe80::a%25en1].

gknw avatar Sep 07 '22 18:09 gknw

Given that the net package now supports parsing of IPv6 scoped literals, all we need to do is to ensure that this actually works for us, and to have a test for the same. Before that (or as part of that) though, we need to cleanup dns_resolver_test.go, which is currently a mess.

easwars avatar Sep 20 '23 00:09 easwars