diff --git a/sys_conn_buffers.go b/sys_conn_buffers.go new file mode 100644 index 00000000..2d60ab10 --- /dev/null +++ b/sys_conn_buffers.go @@ -0,0 +1,48 @@ +package quic + +import ( + "errors" + "fmt" + "net" + "sync" + + "github.com/quic-go/quic-go/internal/protocol" + "github.com/quic-go/quic-go/internal/utils" +) + +func setReceiveBuffer(c net.PacketConn, logger utils.Logger) error { + conn, ok := c.(interface{ SetReadBuffer(int) error }) + if !ok { + return errors.New("connection doesn't allow setting of receive buffer size. Not a *net.UDPConn?") + } + size, err := inspectReadBuffer(c) + if err != nil { + return fmt.Errorf("failed to determine receive buffer size: %w", err) + } + if size >= protocol.DesiredReceiveBufferSize { + logger.Debugf("Conn has receive buffer of %d kiB (wanted: at least %d kiB)", size/1024, protocol.DesiredReceiveBufferSize/1024) + return nil + } + // Ignore the error. We check if we succeeded by querying the buffer size afterward. + _ = conn.SetReadBuffer(protocol.DesiredReceiveBufferSize) + newSize, err := inspectReadBuffer(c) + if newSize < protocol.DesiredReceiveBufferSize { + // Try again with RCVBUFFORCE on Linux + _ = forceSetReceiveBuffer(c, protocol.DesiredReceiveBufferSize) + newSize, err = inspectReadBuffer(c) + if err != nil { + return fmt.Errorf("failed to determine receive buffer size: %w", err) + } + } + if err != nil { + return fmt.Errorf("failed to determine receive buffer size: %w", err) + } + if newSize == size { + return fmt.Errorf("failed to increase receive buffer size (wanted: %d kiB, got %d kiB)", protocol.DesiredReceiveBufferSize/1024, newSize/1024) + } + if newSize < protocol.DesiredReceiveBufferSize { + return fmt.Errorf("failed to sufficiently increase receive buffer size (was: %d kiB, wanted: %d kiB, got: %d kiB)", size/1024, protocol.DesiredReceiveBufferSize/1024, newSize/1024) + } + logger.Debugf("Increased receive buffer size to %d kiB", newSize/1024) + return nil +} diff --git a/transport.go b/transport.go index d7d37eb4..52f1a36a 100644 --- a/transport.go +++ b/transport.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "crypto/tls" "errors" - "fmt" "log" "net" "os" @@ -167,46 +166,6 @@ func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.C return dial(ctx, newSendConn(t.conn, addr, nil), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, true) } -func setReceiveBuffer(c net.PacketConn, logger utils.Logger) error { - conn, ok := c.(interface{ SetReadBuffer(int) error }) - if !ok { - return errors.New("connection doesn't allow setting of receive buffer size. Not a *net.UDPConn?") - } - size, err := inspectReadBuffer(c) - if err != nil { - return fmt.Errorf("failed to determine receive buffer size: %w", err) - } - if size >= protocol.DesiredReceiveBufferSize { - logger.Debugf("Conn has receive buffer of %d kiB (wanted: at least %d kiB)", size/1024, protocol.DesiredReceiveBufferSize/1024) - return nil - } - // Ignore the error. We check if we succeeded by querying the buffer size afterward. - _ = conn.SetReadBuffer(protocol.DesiredReceiveBufferSize) - newSize, err := inspectReadBuffer(c) - if newSize < protocol.DesiredReceiveBufferSize { - // Try again with RCVBUFFORCE on Linux - _ = forceSetReceiveBuffer(c, protocol.DesiredReceiveBufferSize) - newSize, err = inspectReadBuffer(c) - if err != nil { - return fmt.Errorf("failed to determine receive buffer size: %w", err) - } - } - if err != nil { - return fmt.Errorf("failed to determine receive buffer size: %w", err) - } - if newSize == size { - return fmt.Errorf("failed to increase receive buffer size (wanted: %d kiB, got %d kiB)", protocol.DesiredReceiveBufferSize/1024, newSize/1024) - } - if newSize < protocol.DesiredReceiveBufferSize { - return fmt.Errorf("failed to sufficiently increase receive buffer size (was: %d kiB, wanted: %d kiB, got: %d kiB)", size/1024, protocol.DesiredReceiveBufferSize/1024, newSize/1024) - } - logger.Debugf("Increased receive buffer size to %d kiB", newSize/1024) - return nil -} - -// only print warnings about the UDP receive buffer size once -var receiveBufferWarningOnce sync.Once - func (t *Transport) init(isServer bool) error { t.initOnce.Do(func() { getMultiplexer().AddConn(t.Conn) @@ -310,6 +269,9 @@ func (t *Transport) close(e error) { t.closed = true } +// only print warnings about the UDP receive buffer size once +var receiveBufferWarningOnce sync.Once + func (t *Transport) listen(conn rawConn) { defer close(t.listening) defer getMultiplexer().RemoveConn(t.Conn)