Proposal Details
The To16() is not as desired when compared to To4():
To4(): works as expected, if address is IPv4 or IPv4 mapped IPv6 it convert to IPv4, otherwise return nil To16): I expect it to do the same. If address is IPv6 it return address, otherwise return nil. the current behavior is not expected, it can return IPv4 address (4 byte value), and can easily causing bugs in using golang in network programming.
Here I propose either modify To16(), if not IPv6 address return nil or Create a new To6() which can be symmetric to To4()
Jia Chen from Paloaltonetworks.
Comment From: jiapaloalto
// To4 converts the IPv4 address ip to a 4-byte representation.
// If ip is not an IPv4 address, To4 returns nil.
func (ip IP) To4() IP {
if len(ip) == IPv4len {
return ip
}
if len(ip) == IPv6len &&
isZeros(ip[0:10]) &&
ip[10] == 0xff &&
ip[11] == 0xff {
return ip[12:16]
}
return nil
}
// To16 converts the IP address ip to a 16-byte representation.
// If ip is not an IP address (it is the wrong length), To16 returns nil.
func (ip IP) To16() IP {
if len(ip) == IPv4len {
return IPv4(ip[0], ip[1], ip[2], ip[3])
}
if len(ip) == IPv6len {
return ip
}
return nil
}
Comment From: thediveo
My understanding of IPv6 is (addressing RFC) that as long as there are for instance IPv4 embedded and also compatible IPv6 addresses, To16()
is fine. As you unfortunately didn't use the provided proposal form, you should have otherwise come across a checkbox IIRC about compatibility; your proposal would break compatibility. So, a new, separate function would be needed, with a hopefully self-explanatory name.
You seem to want a stdlib function that excludes certain (or all?) IPv4-related mappings and tunneling addresses? I somehow have the gut feeling that this is very, very specific and everyone has a different expectation, but let's see.
Comment From: gabyhelp
Similar Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: seankhliao
the current behavior is not expected, it can return IPv4 address (4 byte value),
That sounds like a bug, do you have a reproducer for this?
Comment From: thediveo
I don't think that there is a bug; but let's start from what seems to be the central issue expectation:
the current behavior is not expected, it can return IPv4 address (4 byte value), and can easily causing bugs in using golang in network programming.
The issue report is ambiguous in what 4 byte value actually mean when looking at what the source code actually does:
1. returning a four byte slice value: the source code doesn't support this for 1.22.4.
2. returning an IPv4-embedded/compatible IPv6 address when caller might expect nil
: this is what the code does and what the godoc comment says. In this case, issue reporter would request breaking the existing contract.
https://cs.opensource.google/go/go/+/refs/tags/go1.22.4:src/net/ip.go;drc=1d45a7ef560a76318ed59dfdb178cecd58caf948;l=227
// To16 converts the IP address ip to a 16-byte representation.
// If ip is not an IP address (it is the wrong length), To16 returns nil.
func (ip IP) To16() IP {
if len(ip) == IPv4len {
return IPv4(ip[0], ip[1], ip[2], ip[3])
}
if len(ip) == IPv6len {
return ip
}
return nil
}
https://cs.opensource.google/go/go/+/master:src/net/ip.go;drc=1667dbd7be0da5e75a25f14c339c859ed2190b43;l=53
// IPv4 returns the IP address (in 16-byte form) of the
// IPv4 address a.b.c.d.
func IPv4(a, b, c, d byte) IP {
p := make(IP, IPv6len)
copy(p, v4InV6Prefix)
p[12] = a
p[13] = b
p[14] = c
p[15] = d
return p
}
Comment From: jiapaloalto
To4() has no problem, it returns an IPv4 address or nil (IPv4 mapped IPv6 is returned as IPv4, which is ok). However, To16() corresponds to To4() meaning to return an IPv6 address if it is an IPv6 address or if the address can be a valid IPv6 address after conversion, it should not convert any IPv4 address to IPv6 address. It does not work for the network world. I understand it is too late to change, backward compatibility etc. But that doesn't mean it is right.
I suggest providing ToIPv6() that only returns a valid IPv6 address or nil.
On Wed, Jun 19, 2024 at 10:25 AM TheDiveO @.***> wrote:
I don't think that there is a bug; but let's start from what seems to be the central issue expectation:
the current behavior is not expected, it can return IPv4 address (4 byte value), and can easily causing bugs in using golang in network programming.
The issue report is ambiguous in what 4 byte value actually mean when looking at what the source code actually does:
- returning a four byte slice value: the source code doesn't support this for 1.22.4.
- returning an IPv4-embedded/compatible IPv6 address when caller might expect nil: this is what the code does and what the godoc comment says. In this case, issue reporter would request breaking the existing contract.
https://cs.opensource.google/go/go/+/refs/tags/go1.22.4:src/net/ip.go;drc=1d45a7ef560a76318ed59dfdb178cecd58caf948;l=227 https://urldefense.proofpoint.com/v2/url?u=https-3A__cs.opensource.google_go_go_-2B_refs_tags_go1.22.4-3Asrc_net_ip.go-3Bdrc-3D1d45a7ef560a76318ed59dfdb178cecd58caf948-3Bl-3D227&d=DwMCaQ&c=V9IgWpI5PvzTw83UyHGVSoW3Uc1MFWe5J8PTfkrzVSo&r=yetdj-aXQpuqTCJGs-93hOpK3740MIRXowfUNLByeos&m=aTIrdflz1Pi0YjhqMY8iahfZHqh1C_IKQIdn0zwBT5GKmkvRMR6rRWotwxNMYTHf&s=Bky8d020eJ9KStBn_PZ3dYuosO2oEN5z7ZtjLo96PV0&e=
// To16 converts the IP address ip to a 16-byte representation.// If ip is not an IP address (it is the wrong length), To16 returns nil.func (ip IP) To16() IP { if len(ip) == IPv4len { return IPv4(ip[0], ip[1], ip[2], ip[3]) } if len(ip) == IPv6len { return ip } return nil }
https://cs.opensource.google/go/go/+/master:src/net/ip.go;drc=1667dbd7be0da5e75a25f14c339c859ed2190b43;l=53 https://urldefense.proofpoint.com/v2/url?u=https-3A__cs.opensource.google_go_go_-2B_master-3Asrc_net_ip.go-3Bdrc-3D1667dbd7be0da5e75a25f14c339c859ed2190b43-3Bl-3D53&d=DwMCaQ&c=V9IgWpI5PvzTw83UyHGVSoW3Uc1MFWe5J8PTfkrzVSo&r=yetdj-aXQpuqTCJGs-93hOpK3740MIRXowfUNLByeos&m=aTIrdflz1Pi0YjhqMY8iahfZHqh1C_IKQIdn0zwBT5GKmkvRMR6rRWotwxNMYTHf&s=hExgKr4mT-qGq2c_-eebJddoZ6FqLb7OPnVYN3k0Ok8&e=
// IPv4 returns the IP address (in 16-byte form) of the// IPv4 address a.b.c.d.func IPv4(a, b, c, d byte) IP { p := make(IP, IPv6len) copy(p, v4InV6Prefix) p[12] = a p[13] = b p[14] = c p[15] = d return p }
— Reply to this email directly, view it on GitHub https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_golang_go_issues_68066-23issuecomment-2D2179209672&d=DwMCaQ&c=V9IgWpI5PvzTw83UyHGVSoW3Uc1MFWe5J8PTfkrzVSo&r=yetdj-aXQpuqTCJGs-93hOpK3740MIRXowfUNLByeos&m=aTIrdflz1Pi0YjhqMY8iahfZHqh1C_IKQIdn0zwBT5GKmkvRMR6rRWotwxNMYTHf&s=s9UvT1eYIITTRVJA5YysVqtafnY4pQzoKohKotY2_bU&e=, or unsubscribe https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_notifications_unsubscribe-2Dauth_BJJVDKRRXFLE3WV5EDMIOXDZIG5IXAVCNFSM6AAAAABJRK5BPCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNZZGIYDSNRXGI&d=DwMCaQ&c=V9IgWpI5PvzTw83UyHGVSoW3Uc1MFWe5J8PTfkrzVSo&r=yetdj-aXQpuqTCJGs-93hOpK3740MIRXowfUNLByeos&m=aTIrdflz1Pi0YjhqMY8iahfZHqh1C_IKQIdn0zwBT5GKmkvRMR6rRWotwxNMYTHf&s=JeiYduSIhrcOvNHs3nbE_3PgHQCBvkBirg8HvQpuobI&e= . You are receiving this because you authored the thread.Message ID: @.***>
Comment From: seankhliao
an mapped ipv4 in ipv6 addresses are still valid ipv6 addresses. even a name like ToIPv6() would be misleading for what you want. I think this is our of scope for the standard library (too specialized to your definition), though you may want to look at net/netip's 4in6