mirror of
https://github.com/golang/go
synced 2024-11-17 10:14:46 -07:00
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 #52264.
This commit is contained in:
parent
e7c56fe994
commit
6776fdb0a7
@ -215,8 +215,12 @@ func addrPortToSockaddrInet4(ap netip.AddrPort) (syscall.SockaddrInet4, error) {
|
|||||||
func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) {
|
func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) {
|
||||||
// ipToSockaddrInet6 has special handling here for zero length slices.
|
// ipToSockaddrInet6 has special handling here for zero length slices.
|
||||||
// We do not, because netip has no concept of a generic zero IP address.
|
// 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.
|
||||||
|
// The error message is kept consistent with ipToSockaddrInet6.
|
||||||
addr := ap.Addr()
|
addr := ap.Addr()
|
||||||
if !addr.Is6() {
|
if !addr.IsValid() {
|
||||||
return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()}
|
return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()}
|
||||||
}
|
}
|
||||||
sa := syscall.SockaddrInet6{
|
sa := syscall.SockaddrInet6{
|
||||||
|
@ -9,6 +9,7 @@ package net
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"internal/testenv"
|
"internal/testenv"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -622,3 +623,45 @@ func TestUDPIPVersionReadMsg(t *testing.T) {
|
|||||||
t.Error("returned UDPAddr is not IPv4")
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "openbsd":
|
||||||
|
// OpenBSD's IPv6 sockets are always IPv6-only, according to the man page:
|
||||||
|
// https://man.openbsd.org/ip6#IPV6_V6ONLY
|
||||||
|
t.Skipf("skipping on %v", runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
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.WriteMsgUDPAddrPort(buf, nil, daddr4)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr4in6)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = conn.WriteMsgUDPAddrPort(buf, nil, daddr6)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user