From: database64128 Date: Fri, 1 Aug 2025 16:42:27 +0000 (+0800) Subject: net: allow zero value destination address in WriteMsgUDPAddrPort X-Git-Tag: go1.26rc1~1014 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=49a2f3ed87;p=gostls13.git net: allow zero value destination address in WriteMsgUDPAddrPort The existing address validity checks already cover both connected and non-connected sockets. Pass a nil sockaddr just like WriteMsgUDP, when the address is zero value. TestWriteToUDP is extended to cover the netip APIs. Fixes #74841 Change-Id: I2708e7747e224958198fe7abb3fcd8d59bc5a88a Reviewed-on: https://go-review.googlesource.com/c/go/+/692437 LUCI-TryBot-Result: Go LUCI Reviewed-by: Cherry Mui Reviewed-by: Sean Liao Reviewed-by: Damien Neil --- diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go index 52712f932f..1ed37d7e6e 100644 --- a/src/net/ipsock_posix.go +++ b/src/net/ipsock_posix.go @@ -260,9 +260,6 @@ func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) { // to an IPv4-mapped IPv6 address. // The error message is kept consistent with ipToSockaddrInet6. addr := ap.Addr() - if !addr.IsValid() { - return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()} - } sa := syscall.SockaddrInet6{ Addr: addr.As16(), Port: int(ap.Port()), diff --git a/src/net/net_fake.go b/src/net/net_fake.go index f7eb28e01a..cc35d90a26 100644 --- a/src/net/net_fake.go +++ b/src/net/net_fake.go @@ -1082,11 +1082,19 @@ func (ffd *fakeNetFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int return n, 0, err } -func (ffd *fakeNetFD) writeMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (n int, oobn int, err error) { +func (ffd *fakeNetFD) writeMsgInet4(p []byte, oob []byte, sa4 *syscall.SockaddrInet4) (n int, oobn int, err error) { + var sa syscall.Sockaddr + if sa4 != nil { + sa = sa4 + } return ffd.writeMsg(p, oob, sa) } -func (ffd *fakeNetFD) writeMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (n int, oobn int, err error) { +func (ffd *fakeNetFD) writeMsgInet6(p []byte, oob []byte, sa6 *syscall.SockaddrInet6) (n int, oobn int, err error) { + var sa syscall.Sockaddr + if sa6 != nil { + sa = sa6 + } return ffd.writeMsg(p, oob, sa) } diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go index 3cd1d0a762..99e4359e71 100644 --- a/src/net/udpsock_posix.go +++ b/src/net/udpsock_posix.go @@ -186,17 +186,25 @@ func (c *UDPConn) writeMsgAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn switch c.fd.family { case syscall.AF_INET: - sa, err := addrPortToSockaddrInet4(addr) - if err != nil { - return 0, 0, err + var sap *syscall.SockaddrInet4 + if addr.IsValid() { + sa, err := addrPortToSockaddrInet4(addr) + if err != nil { + return 0, 0, err + } + sap = &sa } - return c.fd.writeMsgInet4(b, oob, &sa) + return c.fd.writeMsgInet4(b, oob, sap) case syscall.AF_INET6: - sa, err := addrPortToSockaddrInet6(addr) - if err != nil { - return 0, 0, err + var sap *syscall.SockaddrInet6 + if addr.IsValid() { + sa, err := addrPortToSockaddrInet6(addr) + if err != nil { + return 0, 0, err + } + sap = &sa } - return c.fd.writeMsgInet6(b, oob, &sa) + return c.fd.writeMsgInet6(b, oob, sap) default: return 0, 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()} } diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go index 3c8da43bdd..7b4bf328e2 100644 --- a/src/net/udpsock_test.go +++ b/src/net/udpsock_test.go @@ -141,36 +141,37 @@ func testWriteToConn(t *testing.T, raddr string) { if err != nil { t.Fatal(err) } + rap := ra.AddrPort() + + assertErrWriteToConnected := func(t *testing.T, err error) { + t.Helper() + if e, ok := err.(*OpError); !ok || e.Err != ErrWriteToConnected { + t.Errorf("got %v; want ErrWriteToConnected", err) + } + } b := []byte("CONNECTED-MODE SOCKET") + _, err = c.(*UDPConn).WriteToUDPAddrPort(b, rap) + assertErrWriteToConnected(t, err) _, err = c.(*UDPConn).WriteToUDP(b, ra) - if err == nil { - t.Fatal("should fail") - } - if err != nil && err.(*OpError).Err != ErrWriteToConnected { - t.Fatalf("should fail as ErrWriteToConnected: %v", err) - } + assertErrWriteToConnected(t, err) _, err = c.(*UDPConn).WriteTo(b, ra) - if err == nil { - t.Fatal("should fail") - } - if err != nil && err.(*OpError).Err != ErrWriteToConnected { - t.Fatalf("should fail as ErrWriteToConnected: %v", err) - } + assertErrWriteToConnected(t, err) _, err = c.Write(b) if err != nil { - t.Fatal(err) + t.Errorf("c.Write(b) = %v; want nil", err) } _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra) - if err == nil { - t.Fatal("should fail") - } - if err != nil && err.(*OpError).Err != ErrWriteToConnected { - t.Fatalf("should fail as ErrWriteToConnected: %v", err) - } + assertErrWriteToConnected(t, err) _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil) if err != nil { - t.Fatal(err) + t.Errorf("c.WriteMsgUDP(b, nil, nil) = %v; want nil", err) + } + _, _, err = c.(*UDPConn).WriteMsgUDPAddrPort(b, nil, rap) + assertErrWriteToConnected(t, err) + _, _, err = c.(*UDPConn).WriteMsgUDPAddrPort(b, nil, netip.AddrPort{}) + if err != nil { + t.Errorf("c.WriteMsgUDPAddrPort(b, nil, netip.AddrPort{}) = %v; want nil", err) } }