16 Commits
Author SHA1 Message Date
ginuerzh 49c998ee45 fix(service): keep accepting after a conn limiter rejection
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
2026-10-11 10:26:15 +00:00
ginuerzh d12663dfe3 fix(conn-limiter): add regression test for double-close guard
Verifies the atomic.Bool CAS in serverConn.Close() releases the limiter
slot exactly once, regardless of how many times Close() is called.
2026-07-11 20:23:32 +08:00
Denis Galeev f9fb5f443d fix(conn-limiter): release limiter slot once on Close
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.
2026-07-11 13:38:37 +03:00
ginuerzh 49ceda6cc2 feat(wrapper): add UnwrapConn to remaining TCP conn wrappers
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.
2026-06-13 14:43:49 +08:00
ginuerzh 05fe690f67 test(limiter/conn): add unit tests for conn limiter and wrappers 2026-05-24 19:38:54 +08:00
ginuerzh fa708f4b5f docs(limiter/conn): add doc comments, fix nil guards and missing Close
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.
2026-05-24 19:38:07 +08:00
ginuerzh 4eb006f1b0 tungo: debug exec.Command output 2025-08-09 16:34:04 +08:00
ginuerzh b597467858 add context for conn 2025-08-04 19:29:38 +08:00
ginuerzh db21de831a fix xnet.Pipe 2025-08-01 23:00:50 +08:00
ginuerzh 208d18125c replace xnet.Transport by xnet.Pipe 2025-07-28 20:52:15 +08:00
ginuerzh 1c6bc9283e forward non-HTTP traffic based on host 2023-01-30 21:09:21 +08:00
ginuerzh ee2c05494c add more options for grpc 2022-12-21 18:17:46 +08:00
ginuerzh 84079e32d2 fix traffic limiter for CIDR 2022-11-05 16:10:26 +08:00
ginuerzh 5237f79740 add chain hop 2022-09-20 17:54:03 +08:00
ginuerzh 01d7dc77c6 update limiter 2022-09-14 20:00:35 +08:00
ginuerzh 91c12882f5 add conn limiter 2022-09-14 00:15:19 +08:00