mirror of
https://github.com/go-gost/x.git
synced 2026-10-19 16:16:32 +00:00
49c998ee454c614c5df72cd59adee099dc1ee6cd
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
x
The implementation layer for the GOST proxy framework. Every interface defined in core/ is implemented here — handlers, listeners, dialers, connectors, plus config parsing, registries, and all cross-cutting concerns.
Package layout
| Directory | Purpose |
|---|---|
handler/ |
Protocol handlers (http, socks4/5, ss, ssh, tunnel, tun, dns, redirect, etc.) |
listener/ |
Protocol listeners (tcp, tls, ws, http2/3, quic, kcp, icmp, tun, udp, etc.) |
dialer/ |
Outbound dialers (tcp, tls, ws, http2/3, quic, grpc, ssh, wg, kcp, icmp, etc.) |
connector/ |
Destination connectors (http, socks4/5, ss, ssh, relay, tunnel, direct, etc.) |
config/ |
Config struct, YAML/JSON parsing, and service construction |
registry/ |
Typed global registries for all component types |
service/ |
Accept loop wiring listener + handler |
chain/ |
Multi-hop forwarding chain and route implementation |
router/ |
Route table router (destination-based routing) |
hop/ |
Node group with load-balanced selection |
selector/ |
Load-balancing strategies (round-robin, random, weighted, hash) |
auth/, bypass/, admission/ |
Authentication, bypass rules, admission control |
resolver/, hosts/ |
DNS resolution and host mapping |
limiter/ |
Traffic, connection, and rate limiters |
recorder/, observer/ |
Traffic recording and observability |
ingress/, sd/, routing/ |
Ingress control, service discovery, routing rules |
logger/, metrics/, api/ |
Logging, Prometheus metrics, Web API |
metadata/, ctx/ |
Metadata key-value system and context propagation |
internal/ |
Shared internals — not importable externally |
Component pattern
Every handler, listener, dialer, and connector follows the same pattern: init() registers a constructor into a global registry, the constructor takes functional options, and Init(metadata.Metadata) extracts typed configuration from the metadata key-value map.
See CLAUDE.md for detailed architecture and conventions.
Languages
Go
100%