From c4f161d8c59c5d6d400028200c6a5cf9ecf0836b Mon Sep 17 00:00:00 2001 From: Audrius Butkevicius Date: Fri, 18 Oct 2019 09:55:37 +0200 Subject: [PATCH] lib/connections: Rate limit quic accept loop (fixes #6081) (#6082) --- lib/connections/quic_listen.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/connections/quic_listen.go b/lib/connections/quic_listen.go index 3c1dbf6c0..5c402d747 100644 --- a/lib/connections/quic_listen.go +++ b/lib/connections/quic_listen.go @@ -16,6 +16,7 @@ import ( "strings" "sync" "sync/atomic" + "time" "github.com/lucas-clemente/quic-go" @@ -110,6 +111,9 @@ func (t *quicListener) serve(stop chan struct{}) error { l.Infof("QUIC listener (%v) starting", packetConn.LocalAddr()) defer l.Infof("QUIC listener (%v) shutting down", packetConn.LocalAddr()) + acceptFailures := 0 + const maxAcceptFailures = 10 + for { select { case <-ctx.Done(): @@ -121,9 +125,23 @@ func (t *quicListener) serve(stop chan struct{}) error { if err == context.Canceled { return nil } else if err != nil { - l.Warnln("Listen (BEP/quic): Accepting connection:", err) + l.Infoln("Listen (BEP/quic): Accepting connection:", err) + + acceptFailures++ + if acceptFailures > maxAcceptFailures { + // Return to restart the listener, because something + // seems permanently damaged. + return err + } + + // Slightly increased delay for each failure. + time.Sleep(time.Duration(acceptFailures) * time.Second) + continue } + + acceptFailures = 0 + l.Debugln("connect from", session.RemoteAddr()) streamCtx, cancel := context.WithTimeout(ctx, quicOperationTimeout)