Skip to content

Commit efe5967

Browse files
committed
net: add UDPConn.WriterTo (experimental)
Allows alloc-free writes. Previously 1 alloc of 32 bytes per packet. Change-Id: I2e9b9626799ccb7d28136059b8ad52024c97f05e
1 parent 249da7e commit efe5967

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/net/udpsock.go

+32
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package net
66

77
import (
88
"context"
9+
"io"
910
"syscall"
1011
)
1112

@@ -171,6 +172,37 @@ func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
171172
return n, err
172173
}
173174

175+
// WriterTo returns an io.Writer that writes UDP packets to addr.
176+
// This is more efficient than WriteTo when many packets will be sent to the same addr.
177+
func (c *UDPConn) WriterTo(addr Addr) (io.Writer, error) {
178+
a, ok := addr.(*UDPAddr)
179+
if !ok {
180+
return nil, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
181+
}
182+
sa, err := a.sockaddr(c.fd.family)
183+
if err != nil {
184+
return nil, err
185+
}
186+
return &udpWriterTo{c, a, sa}, nil
187+
}
188+
189+
type udpWriterTo struct {
190+
conn *UDPConn
191+
addr *UDPAddr
192+
sa syscall.Sockaddr
193+
}
194+
195+
func (c *udpWriterTo) Write(b []byte) (int, error) {
196+
if !c.conn.ok() {
197+
return 0, syscall.EINVAL
198+
}
199+
n, err := c.writeTo(b, c.sa)
200+
if err != nil {
201+
err = &OpError{Op: "write", Net: c.conn.fd.net, Source: c.conn.fd.laddr, Addr: c.addr.opAddr(), Err: err}
202+
}
203+
return n, err
204+
}
205+
174206
// WriteMsgUDP writes a message to addr via c if c isn't connected, or
175207
// to c's remote address if c is connected (in which case addr must be
176208
// nil). The payload is copied from b and the associated out-of-band

src/net/udpsock_posix.go

+7
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
8080
return c.fd.writeTo(b, sa)
8181
}
8282

83+
func (c *udpWriterTo) writeTo(b []byte, sa syscall.Sockaddr) (int, error) {
84+
if c.conn.fd.isConnected {
85+
return 0, ErrWriteToConnected
86+
}
87+
return c.conn.fd.writeTo(b, c.sa)
88+
}
89+
8390
func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
8491
if c.fd.isConnected && addr != nil {
8592
return 0, 0, ErrWriteToConnected

0 commit comments

Comments
 (0)