Browse Source

wgengine/netstack: use buffer pools for UDP packet forwarding

Use buffer pools for UDP packet forwarding to prepare for increasing the
forwarded UDP packet size for peer path MTU discovery.

Updates #311

Co-authored-by: Brad Fitzpatrick <[email protected]>
Signed-off-by: Val <[email protected]>
Val 2 years ago
parent
commit
fb2f3e4741
1 changed files with 17 additions and 5 deletions
  1. 17 5
      wgengine/netstack/netstack.go

+ 17 - 5
wgengine/netstack/netstack.go

@@ -1059,10 +1059,15 @@ func (ns *Impl) acceptUDP(r *udp.ForwarderRequest) {
 	go ns.forwardUDP(c, srcAddr, dstAddr)
 }
 
+// Buffer pool for forwarding UDP packets.
+var udpBufPool = &sync.Pool{
+	New: func() any {
+		b := make([]byte, maxUDPPacketSize)
+		return &b
+	},
+}
+
 func (ns *Impl) handleMagicDNSUDP(srcAddr netip.AddrPort, c *gonet.UDPConn) {
-	// In practice, implementations are advised not to exceed 512 bytes
-	// due to fragmenting. Just to be sure, we bump all the way to the MTU.
-	var maxUDPReqSize = tstun.DefaultMTU()
 	// Packets are being generated by the local host, so there should be
 	// very, very little latency. 150ms was chosen as something of an upper
 	// bound on resource usage, while hopefully still being long enough for
@@ -1070,7 +1075,10 @@ func (ns *Impl) handleMagicDNSUDP(srcAddr netip.AddrPort, c *gonet.UDPConn) {
 	const readDeadline = 150 * time.Millisecond
 
 	defer c.Close()
-	q := make([]byte, maxUDPReqSize)
+
+	bufp := udpBufPool.Get().(*[]byte)
+	defer udpBufPool.Put(bufp)
+	q := *bufp
 
 	// libresolv from glibc is quite adamant that transmitting multiple DNS
 	// requests down the same UDP socket is valid. To support this, we read
@@ -1183,7 +1191,11 @@ func startPacketCopy(ctx context.Context, cancel context.CancelFunc, dst net.Pac
 	}
 	go func() {
 		defer cancel() // tear down the other direction's copy
-		pkt := make([]byte, maxUDPPacketSize)
+
+		bufp := udpBufPool.Get().(*[]byte)
+		defer udpBufPool.Put(bufp)
+		pkt := *bufp
+
 		for {
 			select {
 			case <-ctx.Done():