Skip to content

Commit fd7381b

Browse files
committed
net: fix WriteMsgUDPAddrPort addr handling
WriteMsgUDPAddrPort should accept IPv4 target addresses on IPv6 UDP sockets. An IPv4 target address will be converted to an IPv4-mapped IPv6 address. Fixes golang#52264.
1 parent 5bf6c97 commit fd7381b

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/net/ipsock_posix.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,11 @@ func addrPortToSockaddrInet4(ap netip.AddrPort) (syscall.SockaddrInet4, error) {
215215
func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) {
216216
// ipToSockaddrInet6 has special handling here for zero length slices.
217217
// We do not, because netip has no concept of a generic zero IP address.
218+
//
219+
// addr is allowed to be an IPv4 address, because As16 will convert it
220+
// to an IPv4-mapped IPv6 address.
218221
addr := ap.Addr()
219-
if !addr.Is6() {
222+
if !addr.Is6() && !addr.Is4() {
220223
return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()}
221224
}
222225
sa := syscall.SockaddrInet6{

src/net/udpsock_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package net
99
import (
1010
"errors"
1111
"internal/testenv"
12+
"net/netip"
1213
"os"
1314
"reflect"
1415
"runtime"
@@ -622,3 +623,38 @@ func TestUDPIPVersionReadMsg(t *testing.T) {
622623
t.Error("returned UDPAddr is not IPv4")
623624
}
624625
}
626+
627+
// TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion verifies that
628+
// WriteMsgUDPAddrPort accepts IPv4, IPv4-mapped IPv6, and IPv6 target addresses
629+
// on a UDPConn listening on "::".
630+
func TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion(t *testing.T) {
631+
if !supportsIPv6() {
632+
t.Skip("IPv6 is not supported")
633+
}
634+
635+
conn, err := ListenUDP("udp", nil)
636+
if err != nil {
637+
t.Fatal(err)
638+
}
639+
defer conn.Close()
640+
641+
daddr4 := netip.AddrPortFrom(netip.MustParseAddr("127.0.0.1"), 12345)
642+
daddr4in6 := netip.AddrPortFrom(netip.MustParseAddr("::ffff:127.0.0.1"), 12345)
643+
daddr6 := netip.AddrPortFrom(netip.MustParseAddr("::1"), 12345)
644+
buf := make([]byte, 8)
645+
646+
_, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr4)
647+
if err != nil {
648+
t.Fatal(err)
649+
}
650+
651+
_, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr4in6)
652+
if err != nil {
653+
t.Fatal(err)
654+
}
655+
656+
_, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr6)
657+
if err != nil {
658+
t.Fatal(err)
659+
}
660+
}

0 commit comments

Comments
 (0)