- Go 1.24+ is required; module root exports
server,client, andprotocolpackages. - Fast manual checks:
go build ./cmd/s5then run./s5 server -listen :1080 [...]and./s5 dial -socks 127.0.0.1:1080 -dest example.com:80 -stdio. - Use
go mod tidyto clean up dependencies after adding or removing imports. - Check the
go.modfile to confirm module name and dependencies.
server/- TCP server, method negotiation, CONNECT/BIND/ASSOCIATE handlers; options include upstream chaining, connection logging, and linkquality tracker injection.handler/– Request façade and middleware chains.protocol/– Public wire-level structs.internal/protocol– Server-only fast paths.auth/,rules/,resolver/– Pluggable interfaces wired throughserver.Options.client/– Protocol mirroring: negotiation, multi-hop dialing, helpers inclient/tcpandclient/udp.cmd/s5– Reference CLI:s5 serverands5 dial.linkquality/– Passive instrumentation for dials and streams.test/– Integration-heavy test suite.
- Find the CI plan in the
.github/workflowsfolder (CodeQL Advanced workflow). - Run
go test ./...to run the full test suite (takes ~1-2 minutes). - Targeted runs:
go test ./test -run <TestName>for specific protocol flows. - Many tests spin up live listeners and UDP sockets—avoid hard-coding ports/IPs; use helpers in
test/*.gofor ephemeral endpoints. - Fix any test or type errors until the whole suite is green.
- After moving files or changing imports, run
go vet ./...andgo fmt ./...to ensure code quality. - Add or update tests for the code you change, even if nobody asked.
- Title format:
[<package>] <Title>(e.g.,[server] Add new middleware hook) - Always run
go test ./...,go vet ./..., andgo fmt ./...before committing. - Ensure all tests pass and there are no linting errors.
- Follow existing code conventions and patterns.
- Prefer
server.With...options to customize behavior (auth, rules, resolver, bind IPs, timeouts, custom dialers, metadata hooks); seeserver/option.gofor available knobs. - Use middleware hooks (
server.WithConnectMiddlewareetc.) for cross-cutting concerns. - TLS-aware deployments rely on
AuthContext.Payloadenrichment; rules/auth modules expect keys liketls.subjectortls.fingerprint.sha256. - Upstream chaining is implemented with
server.WithDialAndRequest; ensure UDP requests fall back to directnet.Dialer. handler.AddressRewritershould treat passed*protocol.AddrSpecas immutable—copy and adjust to avoid data races.
- Respect context deadlines everywhere: server sets handshake deadlines and cancels per-connection goroutines when contexts fire.
- Duplex proxying uses pooled buffers (
internal/buffer/pool.go) plusio.WriterTo/io.ReaderFromfast paths—reuseServer.borrowBuf/Server.proxyDuplex. - UDP associate enforces peer caps, idle GC, and drops fragmented datagrams by design.
- BIND flows expect two replies and optional peer validation; coordinate with tests in
test/bind_*.go.
- Use
server.Logger/client/internal/loggingabstractions so library consumers can swap verbosity. - Avoid direct
log.Printfoutside CLI utilities.