aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordatabase64128 <free122448@hotmail.com>2025-07-25 15:14:16 +0800
committerCherry Mui <cherryyz@google.com>2025-08-25 19:49:49 -0700
commit86c5e2d025b6923424540d653a0c59cafc7571ca (patch)
treef61994fc77c5eb810fe16f436aba4983cd70c728
parent94ca1d97b4520cafc377110712b77e4cecc64c12 (diff)
downloadgo-86c5e2d025b6923424540d653a0c59cafc7571ca.tar.xz
[release-branch.go1.24] net: fix WriteMsgUDPAddrPort addr handling on IPv4 sockets
Accept IPv4-mapped IPv6 destination addresses on IPv4 UDP sockets. Fixes #74818. Change-Id: I4624b9b8f861aedcae29e51d5298d23ce1c0f2c7 Reviewed-on: https://go-review.googlesource.com/c/go/+/689976 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Mark Freeman <markfreeman@google.com> Reviewed-by: Damien Neil <dneil@google.com> (cherry picked from commit bdb2d50fdf40706e7d7411f33ade80edac726707) Reviewed-on: https://go-review.googlesource.com/c/go/+/695656 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
-rw-r--r--src/net/ipsock_posix.go6
-rw-r--r--src/net/udpsock_test.go32
2 files changed, 37 insertions, 1 deletions
diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go
index 2aeabd4487..52712f932f 100644
--- a/src/net/ipsock_posix.go
+++ b/src/net/ipsock_posix.go
@@ -237,8 +237,12 @@ func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, e
func addrPortToSockaddrInet4(ap netip.AddrPort) (syscall.SockaddrInet4, error) {
// ipToSockaddrInet4 has special handling here for zero length slices.
// We do not, because netip has no concept of a generic zero IP address.
+ //
+ // addr is allowed to be an IPv4-mapped IPv6 address.
+ // As4 will unmap it to an IPv4 address.
+ // The error message is kept consistent with ipToSockaddrInet4.
addr := ap.Addr()
- if !addr.Is4() {
+ if !addr.Is4() && !addr.Is4In6() {
return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: addr.String()}
}
sa := syscall.SockaddrInet4{
diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go
index 6dacc81df6..7ad8a585b0 100644
--- a/src/net/udpsock_test.go
+++ b/src/net/udpsock_test.go
@@ -705,3 +705,35 @@ func TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion(t *testing.T) {
t.Fatal(err)
}
}
+
+// TestIPv4WriteMsgUDPAddrPortTargetAddrIPVersion verifies that
+// WriteMsgUDPAddrPort accepts IPv4 and IPv4-mapped IPv6 destination addresses,
+// and rejects IPv6 destination addresses on a "udp4" connection.
+func TestIPv4WriteMsgUDPAddrPortTargetAddrIPVersion(t *testing.T) {
+ if !testableNetwork("udp4") {
+ t.Skipf("skipping: udp4 not available")
+ }
+
+ conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+
+ daddr4 := netip.AddrPortFrom(netip.MustParseAddr("127.0.0.1"), 12345)
+ daddr4in6 := netip.AddrPortFrom(netip.MustParseAddr("::ffff:127.0.0.1"), 12345)
+ daddr6 := netip.AddrPortFrom(netip.MustParseAddr("::1"), 12345)
+ buf := make([]byte, 8)
+
+ if _, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr4); err != nil {
+ t.Errorf("conn.WriteMsgUDPAddrPort(buf, nil, daddr4) failed: %v", err)
+ }
+
+ if _, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr4in6); err != nil {
+ t.Errorf("conn.WriteMsgUDPAddrPort(buf, nil, daddr4in6) failed: %v", err)
+ }
+
+ if _, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr6); err == nil {
+ t.Errorf("conn.WriteMsgUDPAddrPort(buf, nil, daddr6) should have failed, but got no error")
+ }
+}