@marcel91200 / caddy Mirror · read-only / commits / 710824c3
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 00:30 UTC

core: Embed net.UDPConn to gain optimizations (#5606)

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

WeidiDeng committed Jul 1, 2023 at 06:31 UTC 710824c3ce9f8084517e8ab099d57f9060f62061
1 file changed +17 -23
listeners.go
+17 -23
@@ -196,7 +196,8 @@ func (na NetworkAddress) listen(ctx context.Context, portOffset uint, config net
196 if err != nil {
197 return nil, err
198 }
199 - ln = &fakeClosePacketConn{sharedPacketConn: sharedPc.(*sharedPacketConn)}
199 + spc := sharedPc.(*sharedPacketConn)
200 + ln = &fakeClosePacketConn{spc: spc, UDPConn: spc.PacketConn.(*net.UDPConn)}
201 }
202 if strings.HasPrefix(na.Network, "ip") {
203 ln, err = config.ListenPacket(ctx, na.Network, address)
@@ -668,37 +669,30 @@ func fakeClosedErr(l interface{ Addr() net.Addr }) error {
669 // socket is actually left open.
670 var errFakeClosed = fmt.Errorf("listener 'closed' 😉")
671
671 -// fakeClosePacketConn is like fakeCloseListener, but for PacketConns.
672 +// fakeClosePacketConn is like fakeCloseListener, but for PacketConns,
673 +// or more specifically, *net.UDPConn
674 type fakeClosePacketConn struct {
673 - closed int32 // accessed atomically; belongs to this struct only
674 - *sharedPacketConn // embedded, so we also become a net.PacketConn
675 + closed int32 // accessed atomically; belongs to this struct only
676 + spc *sharedPacketConn // its key is used in Close
677 + *net.UDPConn // embedded, so we also become a net.PacketConn and enable several other optimizations done by quic-go
678 }
679
680 +// interface guard for extra optimizations
681 +// needed by QUIC implementation: https://github.com/caddyserver/caddy/issues/3998, https://github.com/caddyserver/caddy/issues/5605
682 +var _ quic.OOBCapablePacketConn = (*fakeClosePacketConn)(nil)
683 +
684 +// https://pkg.go.dev/golang.org/x/net/ipv4#NewPacketConn is used by quic-go and requires a net.PacketConn type assertable to a net.Conn,
685 +// but doesn't actually use these methods, the only methods needed are `ReadMsgUDP` and `SyscallConn`.
686 +var _ net.Conn = (*fakeClosePacketConn)(nil)
687 +
688 +// Close won't close the underlying socket unless there is no more reference, then listenerPool will close it.
689 func (fcpc *fakeClosePacketConn) Close() error {
690 if atomic.CompareAndSwapInt32(&fcpc.closed, 0, 1) {
679 - _, _ = listenerPool.Delete(fcpc.sharedPacketConn.key)
691 + _, _ = listenerPool.Delete(fcpc.spc.key)
692 }
693 return nil
694 }
695
684 -// Supports QUIC implementation: https://github.com/caddyserver/caddy/issues/3998
685 -func (fcpc fakeClosePacketConn) SetReadBuffer(bytes int) error {
686 - if conn, ok := fcpc.PacketConn.(interface{ SetReadBuffer(int) error }); ok {
687 - return conn.SetReadBuffer(bytes)
688 - }
689 - return fmt.Errorf("SetReadBuffer() not implemented for %T", fcpc.PacketConn)
690 -}
691 -
692 -// Supports QUIC implementation: https://github.com/caddyserver/caddy/issues/3998
693 -func (fcpc fakeClosePacketConn) SyscallConn() (syscall.RawConn, error) {
694 - if conn, ok := fcpc.PacketConn.(interface {
695 - SyscallConn() (syscall.RawConn, error)
696 - }); ok {
697 - return conn.SyscallConn()
698 - }
699 - return nil, fmt.Errorf("SyscallConn() not implemented for %T", fcpc.PacketConn)
700 -}
701 -
696 type fakeCloseQuicListener struct {
697 closed int32 // accessed atomically; belongs to this struct only
698 *sharedQuicListener // embedded, so we also become a quic.EarlyListener