-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: net: UDPAddr/TCPAddr AddrPort should map 4in6 addresses to IPv4 netip.Addrs #53607
Comments
I think udp4 instead of udp should be specified if you expect to use IPv4. - c, err := net.ListenUDP("udp", &net.UDPAddr{
+ c, err := net.ListenUDP("udp4", &net.UDPAddr{ The behavior is documented here: Lines 73 to 112 in 17083a2
|
I've known about the At the very least, there should be public documentation about that. Having the correct type of address would be better, but I don't know if that's feasible. |
Can you elaborate this part? I don't understand why |
if ip4 := ip.To4(); ip4 != nil {
// Use ip4 for IPv4 code.
} else {
// Use ip for IPv6 code.
} Which wasn't entirely correct, since there could be situations where one needs to make a distinction between the real IPv4 addresses and the mapped ones, but those seem to be fairly rare.
|
This is a duplicate of #53554, which has a proposed fix as well. |
@dr2chase, I agree with ZekeLu in that this is a separate issue. And I also feel like there may possibly be other places where a naïve conversion could result in code breakage. Perhaps a blog post outlining the dos and don'ts of converting code from |
Another example: https://go.dev/play/p/wVDZEuLFdRd
results in:
In retrospect, making https://pkg.go.dev/net/netip#AddrFromSlice not do the automatic unmapping was probably a mistake. I just converted a bunch of code from the original https://pkg.go.dev/inet.af/netaddr#FromStdIP which does do the unmapping and it was pretty tedious, having to sprinkle Some options:
|
With caveat golang/go#53607 (comment) that then requires a new wrapper. But a simpler one at least. Updates #5162 Change-Id: I0a5265065bfcd7f21e8dd65b2bd74cae90d76090 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
With caveat golang/go#53607 (comment) that then requires a new wrapper. But a simpler one at least. Updates #5162 Change-Id: I0a5265065bfcd7f21e8dd65b2bd74cae90d76090 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
@bradfitz, just to clarify, in your example the main culprit is probably ta := &net.TCPAddr{
IP: net.ParseIP("1.2.3.4").To4(),
Port: 80,
}
fmt.Println(ta.AddrPort())
ta = &net.TCPAddr{
IP: net.IP{1, 2, 3, 4},
Port: 80,
}
fmt.Println(ta.AddrPort())
Which is not to say that the problem doesn't exist, of course. I personally would prefer that all functions that are used to convert between |
Re-posting #54234 (comment) since it seems to be more relevant here. I don't think The IMO this behavior should be preserved, because this is how the underlying socket works. Those who wish to unmap IPv4-mapped IPv6 addresses can always do the unmapping themselves in their own code. |
And if there's no address family specified, as in |
Except it has always been like this. On most systems Unless being able to run on OpenBSD and DragonFly BSD is a requirement, one can usually safely assume that |
I guess the question is whether that's the API we want in Go. Seems like a legacy compatibility wart and we could do better than needlessly exposing mapped addresses to users when we have a type that can distinguish what was really meant. |
It's not a goal of Go to expose the underlying operating system behavior. Instead we are trying to present an API that works roughly the same on all operating systems. It seems like if we are listening on 127.0.0.1 we should get the IPv4 form of that for net/netip when we call TCPAddr.AddrPort (or UDPAddr.AddrPort). That's more often what people want. Note that package net has always returned 16-byte forms for everything as the standard form. But net/netip distinguishes them. Given that net has discarded the "IPv4 vs IPv4-in-6" information, we'll get the right answer far more often if we assume that case is "IPv4" rather than "IPv4-in-6". Do I have that right? |
It might not have been an explicit goal, but it has been the actual behavior since the beginning. Making this change could break existing code that converts the returned
Only the parse, lookup functions, and other things that does not speak to sockets. Methods on sockets have always preserved information on the socket's address family. |
This proposal has been added to the active column of the proposals project |
There are three conversions using netip.AddrFromSlice in package net. They are: UDPAddr.AddrPort The decision we have is whether to call netip.AddrFromSlice(...).Unmap() instead of just AddrFromSlice in each of these. I think we need to understand the impact of this change. We know times when it would help but I don't think we know the full impact well enough. Does anyone want to try to summarize the behavior across different systems and the different API calls? |
IPv4-mapped IPv6 addresses don't really make sense in the scope of DNS. It also simplifies things a bit if the returned addresses are guaranteed to be either IPv4 or IPv6. So for |
I think to move forward on this issue we'd need to see this summary. If no one is interested, maybe we should put this issue on hold. |
Placed on hold. |
I also met this problem. I send a cl I'm sorry about I don't fully understand the impact of this change. But in my case, when i got a ipv4 address, I just want to still get this ipv4 address after calling the netip package. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
It does with
go version devel go1.19-d3ffff2790 Tue Jun 28 13:01:41 2022 +0000 linux/amd64
, haven't tried a more recent one.What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
https://go.dev/play/p/9qs4KxGRPjq
Note: the requests are sent using
-4
and an IPv4 address.What did you expect to see?
What did you see instead?
I haven't tried the TCP ones, but looking at the code, they probably have the same issue.
The text was updated successfully, but these errors were encountered: