One connection over the climiter quota killed the whole service. The conn
limiter wrapper signals an over-limit connection by returning a plain
error from Accept, which the accept loop does not recognise as either a
listener.AcceptError or a temporary net.Error, so it fell through to the
fatal branch and returned. program.go discards Serve's return value, so
the process stayed up with no further logging while nothing accepted
connections any more. Every later connection sat in the listen backlog,
where the kernel completes the handshake but no service ever reads it, so
clients saw a connection that opens and then never negotiates. Only a
restart recovered the service.
The counter itself was never the problem: llimiter.Allow rolls the count
back when it refuses, and a test now pins that. A test also pins that
the accept loop survives a rejection and still serves the connection
that follows it.
Export ErrConnLimit so the refusal can be told apart from a listener
that has genuinely failed, and continue the accept loop on it. The
plain-http-tunnel listener refused over-limit connections with an
identical error and is fixed the same way.
Closes#914
serverConn.Close() called limiter.Allow(-1) on every invocation. Close
is routinely called more than once (deferred + explicit teardown paths),
so each extra call leaked a limiter slot, progressively under-counting
the current connection count until the climiter cap admitted more
connections than configured.
Guard the release behind an atomic.Bool CAS so the slot is returned
exactly once, regardless of how many times Close is called.
Add UnwrapConn() to the admission, proxyproto, conn limiter, metrics,
and observer/stats TCP connection wrappers, complementing the traffic
limiter's limitConn added in the previous commit.
This makes the unwrapConn() helper in handler/sshd able to peel through
any combination of these wrappers uniformly, keeping the pattern
complete and future-proof for handlers that assert on concrete
connection types.
Add package and exported symbol doc comments across conn, generator,
limiter, and wrapper packages. Fix nil receiver guard in
connLimitSingleGenerator.Limiter, add missing httpLoader.Close call,
return context.Background instead of nil in serverConn.Context, return
explicit error on connection limit exceeded, and simplify Allow logic.