Skip to content

Commit

Permalink
net: fix WriteMsgUDPAddrPort addr handling
Browse files Browse the repository at this point in the history
WriteMsgUDPAddrPort should accept IPv4 target addresses on IPv6 UDP sockets.
An IPv4 target address will be converted to an IPv4-mapped IPv6 address.

Fixes #52264.
  • Loading branch information
database64128 committed Apr 12, 2022
1 parent 2b31abc commit 56d9199
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/net/ipsock_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,11 @@ func addrPortToSockaddrInet4(ap netip.AddrPort) (syscall.SockaddrInet4, error) {
func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) {
// ipToSockaddrInet6 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 address, because As16 will convert it
// to an IPv4-mapped IPv6 address.
addr := ap.Addr()
if !addr.Is6() {
if !addr.Is6() && !addr.Is4() {
return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()}
}
sa := syscall.SockaddrInet6{
Expand Down
36 changes: 36 additions & 0 deletions src/net/udpsock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package net
import (
"errors"
"internal/testenv"
"net/netip"
"os"
"reflect"
"runtime"
Expand Down Expand Up @@ -622,3 +623,38 @@ func TestUDPIPVersionReadMsg(t *testing.T) {
t.Error("returned UDPAddr is not IPv4")
}
}

// TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion verifies that
// WriteMsgUDPAddrPort accepts IPv4, IPv4-mapped IPv6, and IPv6 target addresses
// on a UDPConn listening on "::".
func TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion(t *testing.T) {
if !supportsIPv6() {
t.Skip("IPv6 is not supported")
}

conn, err := ListenUDP("udp", nil)
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)

_, err = conn.WriteToUDPAddrPort(buf, daddr4)
if err != nil {
t.Fatal(err)
}

_, err = conn.WriteToUDPAddrPort(buf, daddr4in6)
if err != nil {
t.Fatal(err)
}

_, err = conn.WriteToUDPAddrPort(buf, daddr6)
if err != nil {
t.Fatal(err)
}
}

0 comments on commit 56d9199

Please sign in to comment.