Use a sync.Pool to reuse packet buffers in QueuePacketConn.

This is meant to reduce overall allocations. See past discussion at
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40260#note_2885524 ff.
This commit is contained in:
David Fifield 2023-04-04 18:45:26 -06:00
parent 97c930013b
commit c097d5f3bc
4 changed files with 116 additions and 14 deletions

View file

@ -69,10 +69,10 @@ type httpHandler struct {
// newHTTPHandler creates a new http.Handler that exchanges encapsulated packets
// over incoming WebSocket connections.
func newHTTPHandler(localAddr net.Addr, numInstances int) *httpHandler {
func newHTTPHandler(localAddr net.Addr, numInstances int, mtu int) *httpHandler {
pconns := make([]*turbotunnel.QueuePacketConn, 0, numInstances)
for i := 0; i < numInstances; i++ {
pconns = append(pconns, turbotunnel.NewQueuePacketConn(localAddr, clientMapTimeout))
pconns = append(pconns, turbotunnel.NewQueuePacketConn(localAddr, clientMapTimeout, mtu))
}
clientIDLookupKey := make([]byte, 16)
@ -200,6 +200,7 @@ func (handler *httpHandler) turbotunnelMode(conn net.Conn, addr net.Addr) error
return
}
_, err := encapsulation.WriteData(bw, p)
pconn.Restore(p)
if err == nil {
err = bw.Flush()
}

View file

@ -79,7 +79,11 @@ func (t *Transport) Listen(addr net.Addr, numKCPInstances int) (*SnowflakeListen
ln: make([]*kcp.Listener, 0, numKCPInstances),
}
handler := newHTTPHandler(addr, numKCPInstances)
// kcp-go doesn't provide an accessor for the current MTU setting (and
// anyway we could not create a kcp.Listener without creating a
// net.PacketConn for it first), so assume the default kcp.IKCP_MTU_DEF
// (1400 bytes) and don't increase it elsewhere.
handler := newHTTPHandler(addr, numKCPInstances, kcp.IKCP_MTU_DEF)
server := &http.Server{
Addr: addr.String(),
Handler: handler,