From 604963052072d7895138c78751c477cf25625e7d Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 3 Nov 2021 13:54:08 -0700 Subject: [PATCH] internal/poll: remove alloc sending IPv6 UDP on Windows This was an oversight in CL 331511. Change-Id: Ibc20bf6ea80a8675d43d9691ed551dffab1d9215 Reviewed-on: https://go-review.googlesource.com/c/go/+/361254 Trust: Josh Bleecher Snyder Trust: Brad Fitzpatrick Run-TryBot: Josh Bleecher Snyder Reviewed-by: Brad Fitzpatrick TryBot-Result: Go Bot --- src/internal/poll/fd_windows.go | 42 +++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go index 0f5ae8e0d40..139f78a7c15 100644 --- a/src/internal/poll/fd_windows.go +++ b/src/internal/poll/fd_windows.go @@ -857,7 +857,7 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { return ntotal, nil } -// WriteTo wraps the sendto network call for IPv4. +// WriteToInet4 is WriteTo, specialized for syscall.SockaddrInet4. func (fd *FD) WriteToInet4(buf []byte, sa4 syscall.SockaddrInet4) (int, error) { if err := fd.writeLock(); err != nil { return 0, err @@ -896,9 +896,43 @@ func (fd *FD) WriteToInet4(buf []byte, sa4 syscall.SockaddrInet4) (int, error) { return ntotal, nil } -// WriteTo wraps the sendto network call for IPv6. -func (fd *FD) WriteToInet6(buf []byte, sa syscall.SockaddrInet6) (int, error) { - return fd.WriteTo(buf, &sa) +// WriteToInet6 is WriteTo, specialized for syscall.SockaddrInet6. +func (fd *FD) WriteToInet6(buf []byte, sa6 syscall.SockaddrInet6) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + + if len(buf) == 0 { + // handle zero-byte payload + o := &fd.wop + o.InitBuf(buf) + o.sa6 = sa6 + n, err := execIO(o, func(o *operation) error { + return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa6, &o.o, nil) + }) + return n, err + } + + ntotal := 0 + for len(buf) > 0 { + b := buf + if len(b) > maxRW { + b = b[:maxRW] + } + o := &fd.wop + o.InitBuf(b) + o.sa6 = sa6 + n, err := execIO(o, func(o *operation) error { + return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa6, &o.o, nil) + }) + ntotal += int(n) + if err != nil { + return ntotal, err + } + buf = buf[n:] + } + return ntotal, nil } // Call ConnectEx. This doesn't need any locking, since it is only