1
0
mirror of https://github.com/golang/go synced 2024-09-29 16:24:28 -06:00

net: do more faithful conversion from AddrPort to UDPAddr

A UDPAddr with a nil IP is a valid state, representing an AF-agnostic
unspecified address, so checking for addr.IsValid() isn't correct;
remove that, as it's only needed in the UDP rx path where it can be
added. Secondly, forcing everything to be IPv6 also is not correct, and
was likely done when the missing .AsSlice() made doing the right thing
less ergonomic. Fix this by using .AsSlice(), which properly preserves
IP version.

Change-Id: Idd1eaecd4076f32a843f859a0a9802ef98f956d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/361478
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Jason A. Donenfeld 2021-11-05 13:02:09 +01:00
parent 23f653df96
commit 4d0683965b
2 changed files with 39 additions and 9 deletions

View File

@ -99,16 +99,12 @@ func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
return addrs.forResolve(network, address).(*UDPAddr), nil
}
// UDPAddrFromAddrPort returns addr as a UDPAddr.
//
// If addr is not valid, it returns nil.
// UDPAddrFromAddrPort returns addr as a UDPAddr. If addr.IsValid() is false,
// then the returned UDPAddr will contain a nil IP field, indicating an
// address family-agnostic unspecified address.
func UDPAddrFromAddrPort(addr netip.AddrPort) *UDPAddr {
if !addr.IsValid() {
return nil
}
ip16 := addr.Addr().As16()
return &UDPAddr{
IP: IP(ip16[:]),
IP: addr.Addr().AsSlice(),
Zone: addr.Addr().Zone(),
Port: int(addr.Port()),
}
@ -189,7 +185,9 @@ func (c *UDPConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err
func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
var ap netip.AddrPort
n, oobn, flags, ap, err = c.ReadMsgUDPAddrPort(b, oob)
addr = UDPAddrFromAddrPort(ap)
if ap.IsValid() {
addr = UDPAddrFromAddrPort(ap)
}
return
}

View File

@ -603,3 +603,35 @@ func BenchmarkWriteToReadFromUDPAddrPort(b *testing.B) {
}
}
}
func TestUDPIPVersionReadMsg(t *testing.T) {
conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
if err != nil {
t.Fatal(err)
}
defer conn.Close()
daddr := conn.LocalAddr().(*UDPAddr).AddrPort()
buf := make([]byte, 8)
_, err = conn.WriteToUDPAddrPort(buf, daddr)
if err != nil {
t.Fatal(err)
}
_, _, _, saddr, err := conn.ReadMsgUDPAddrPort(buf, nil)
if err != nil {
t.Fatal(err)
}
if !saddr.Addr().Is4() {
t.Error("returned AddrPort is not IPv4")
}
_, err = conn.WriteToUDPAddrPort(buf, daddr)
if err != nil {
t.Fatal(err)
}
_, _, _, soldaddr, err := conn.ReadMsgUDP(buf, nil)
if err != nil {
t.Fatal(err)
}
if len(soldaddr.IP) != 4 {
t.Error("returned UDPAddr is not IPv4")
}
}