Extract newRecorderObject, selectTarget, sniffingDial, buildSniffer,
handleSniffedProtocol, and handleRawForwarding from Handle (200→87 lines).
Move nil Router guard before sniffing for early failure. Log previously
silent sniff and pipe errors at Debug level. Apply readTimeout to Pipe.
Append :0 when target addr lacks a port. Reorder metadata fields and
add doc comments on all exported symbols.
- Return clear error when Router is nil instead of panicking
- Capture and log sniffing.Sniff and xnet.Pipe errors at Debug level
- Move dial closure and Sniffer construction into HTTP/TLS switch branch
to avoid unnecessary allocation on non-HTTP/TLS traffic
- Merge ProtoHTTP and ProtoTLS cases, branch internally on proto
- Add doc comments on NewHandler and Handle
- Add comment explaining nil hop is valid (no forwarder config)
- Pass readTimeout to xnet.Pipe via WithReadTimeout
Fix bugs in the file handler: unbuffered send channel deadlock on Close,
conn leak when send drops on done, and Addr() returning nil. Add done-
priority select in send(), explicit ln.Close() in Close(), Unwrap() on
responseWriter for http.ResponseController, and nil guards.
Also add package doc, NewHandler doc, and 39 unit tests covering the
listener, responseWriter, handler lifecycle, auth, and file serving.
On Windows, icmp.ListenPacket("ip4:icmp", "0.0.0.0") does not reliably
deliver ICMP packets (golang/go#38427). Add a platform-specific
ListenPacket helper that binds to a discovered interface address and
enables SIO_RCVALL via WSAIoctl for promiscuous receive.
Fixesgo-gost/x#36
tokenTransport now delegates CloseIdleConnections to the underlying
*http.Transport so http.Client.CloseIdleConnections() works through
the wrapper. Three plugin Close() methods updated to unwrap via
HTTPClientTransport before calling CloseIdleConnections.
RoundTrip now short-circuits when caller already set Authorization,
avoiding an unnecessary req.Clone allocation on the pass-through path.
Pull node-resolution logic out of dial/dialTLS into pure resolveHTTPNode
and resolveTLSNode helpers. This separates node selection (bypass, hop,
fallback) from connection establishment, making both independently
testable. Add 21 new tests covering bypass, hop selection, nil-hop,
addr fallback, upgrade response type mismatch, websocket frames,
response body rewriting, and h2 preface validation.
- Use local readTimeout copy in HandleOptions instead of mutating shared
Sniffer.ReadTimeout, eliminating a data race under concurrent calls
- Close both connections in sniffingWebsocketFrame when one direction
errors, preventing indefinite goroutine blockage
- Add bounds check on PeerCertificates before indexing in terminateTLS
- Discard non-fatal ParseServerHello error instead of returning it after
successful xnet.Pipe
- Log res.Write errors in bypass/bad-gateway/connect-failure paths
- Add doc comments to all 15 exported symbols
Replace cidranger third-party dependency with a custom binary trie for
zero-allocation CIDR containment lookups. Migrate ipMatcher from
string-keyed map to netip.Addr for correct IPv4/IPv6 normalization.
Extract shared splitHostPort helper to eliminate repeated host:port
parsing boilerplate across all matchers. Add comprehensive benchmarks.
Fix bufpool leak when PackBuffer fails by extracting packResponse helper.
Add write deadline before conn.Write to prevent goroutine hangs on slow
clients. Log async exchange errors instead of silently discarding them.
Raise defaultBufferSize from 1024 to 4096 to match EDNS0 standard.
Deduplicate lookupHosts TypeA/TypeAAAA branches.
Replace boolean bypass logic with bypassDecision enum (decisionBypass/decisionProxy),
consolidate four matcher fields into a single patternSet struct for atomic swaps,
extract classifyPatterns as a pure function, and remove unused matched() method
and slices import. Add 204 lines of tests covering decisions, pattern sets,
and group evaluation logic.
- Default nil logger to Nop() in NewService to prevent panics
- Fix Events() returning 20-element slice padded with zero values
- Collect and join all errors in Close() instead of discarding
- Remove unnecessary variable shadow in execCmds
- Add doc comments to all 22 exported symbols
- Add 34 tests covering status, serve loop, close, and edge cases
Replace bare type assertion in ParallelStrategy with comma-ok check to
prevent panic on non-Node inputs. Downgrade noisy Infof hash-selection
log to Tracef and remove Chinese-language debug output. Add doc comments
to all exported symbols in weighted.go.
- Add nil service guards to Register/Deregister/Renew in gRPC and HTTP
plugins to prevent nil pointer dereferences
- Remove unused log field from grpcPlugin and httpPlugin
- Prefix HTTP error messages with operation context (sd register/deregister/renew/get)
- Return gRPC Register error directly instead of logging + returning
- Add 33 unit tests covering all operations, nil guards, and error paths
- Fix Host(".example.com") incorrectly matching bare "example.com" by
using HasSuffix(reqHost, host) instead of HasSuffix(reqHost, host[1:])
- Fix PathRegexp matcher error message saying "PathPrefix" instead of
"PathRegexp"
- Add doc comments to NewMatcher and Tree types
- Add 28 unit tests covering all matcher types, boolean operators,
edge cases, and parameter validation
- Add missing httpLoader.Close() in localRouter.Close() to prevent
resource leak
- Log parse errors from file/redis/http loaders instead of silently
discarding them
- Add nil reader guards before calling parseRoutes in load()
- Default nil logger to xlogger.Nop() to prevent nil panics
- Use context.Background() instead of context.TODO() for root context
- Use strings.ReplaceAll instead of deprecated strings.Replace with -1
- Add doc comments to all exported symbols
- Add 27 unit tests + 1 benchmark
Replace 10 raw "ipv4"/"ipv6" string literals with preferIPv4/preferIPv6
constants, extract the duplicated fallback-condition check (repeated 4x
across resolve and lookupCache) into shouldReturn, and fix a misleading
doc comment on resolvePreference's default return.
Normalize Only/Prefer values (ip4→ipv4, ip6→ipv6) so downstream
comparisons match correctly. Fix asymmetric fallback where caller
network=ip6 fell through to IPv4 but ip4 didn't fall through to IPv6
— both branches now check hard constraints (server.Only || callerPref)
only, allowing soft Prefer to fall back. Fix data race on cache item.ts
by reading it inside RLock. Fix Store mutating caller's dns.Msg by
copying before TTL override. Add singleflight dedup, semaphore-bounded
async refresh, DNS rcode error checking, and bump EDNS0 UDPSize to
4096. Add 25 tests.
Fix async resolve goroutine using caller's cancelable context by
switching to context.WithoutCancel. Fix NewGRPCPlugin silently
returning broken resolver on connection failure. Fix "resolover"
typo in log field. Add doc comments to all exported symbols.
Log close errors in Unregister instead of silently discarding them.
Add doc comments to all exported symbols across 20 registry files.
Add comprehensive tests covering base registry, all wrapper types,
hot-reload delegation, nil-fallback semantics, and global accessors.
- httpRecorder: use http.NewRequestWithContext instead of http.NewRequest
- tcpRecorder: loop Write to avoid short-write data loss
- fileRecorder: guard against nil out in Record and Close
- plugin/grpc, plugin/http: handle json.Marshal errors instead of ignoring
- fileRecorder, redis*Recorder: idempotent Close via sync.Once
- All exported symbols: add doc comments
The WrapUDPConn constructor returns nil when either arg is nil, so
c.stats is always non-nil in all udpConn methods. Remove 8 redundant
nil guards that were inconsistent with packetConn (which already
skipped them).
Add 65 unit tests across plugin, stats, and wrapper packages covering
nil safety, race conditions, double-close, event marshaling, and
reset-traffic semantics. Replace magic numbers in tests with named
Kind constants.
- WrapUDPConn, WrapPacketConn, WrapListener: add nil guards for pc/ln params
- NewGRPCPlugin: return no-op observer instead of nil on connection error
- gRPC plugin: fix resource leak by wiring Close() through observerWrapper
and service.Close() lifecycle
- Both plugins: log unknown event types instead of silently dropping them
- httpPlugin: remove dead nil check for always-non-nil client field
- Stats.Reset: update core interface doc to match implementation behavior
- Add doc comments to all exported symbols across the observer package
- Add NewLimiterWithBurst(rate, burst) for independent burst control
- Extend parseLimit to accept optional 4th field as burst size
- Add DroppedPacketCounter interface with DroppedPackets() for packet/udp conns
- Export ErrRateLimited sentinel for rate-limit error checks
- Fix IP-level cache expiration (NoExpiration → defaultExpiration) to prevent
unbounded growth; reset TTL on access in In/Out
- Short-circuit single-limiter path to avoid limiterGroup allocation
- Add nil guard in cachedTrafficLimiter when both old and new values are nil
- Remove unused ctx field from wrapper structs
NewMetadata(nil) previously returned a nil Metadata interface, causing
panics on direct .Get()/.IsExists() calls. Now returns an empty map.
GetFloat added float32→float64 promotion, matching GetString behavior.
Doc comments for all 13 exported symbols across both packages.
41 unit tests (11 metadata + 30 util) at 100% coverage.
- limiterGroup.Allow(): return false immediately on first denial instead of
continuing through all limiters (wasting tokens on subsequent limiters).
Sort limiters by Limit() so most restrictive fires first.
- rateLimiter.Close(): add missing httpLoader.Close() to prevent resource leak.
- Add doc comments for all exported symbols (package, constants, Options,
NewRateLimiter, NewLimiter, ErrRateLimit, generators).
- Add rate_test.go with 59 unit tests covering generators, limiter groups,
parsing (limit/line/patterns), reload, loader merge, Close behavior,
and priority ordering (exact IP > CIDR > $$ > $).
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.
matcher: fix IPv6 normalization via netip.ParseAddr, port-range overwrite
by switching to []*PortRange map, case-insensitive domain/host matching,
glob.MustCompile→Compile to avoid panic on invalid patterns.
plugin: guard nil *Options in NewGRPCConn and NewHTTPClient; add
HTTPClientTransport helper for idle-connection cleanup.
net/*: add doc comments for all exported symbols (no code changes).
Add 30 tests (matcher_test.go 22, plugin_test.go 8) covering all
matcher types, nil safety, case insensitivity, IPv6 normalization,
port ranges, and plugin option composition.
- entrypoint.go: guard ictx.RecorderObjectFromContext with nil checks on
ClientID and Redirect assignments
- io.go: fix CloseRead checking Writer instead of Reader, add Reader
fallback to CloseWrite, unwrap *readWriter/*readWriteCloser in
SetReadDeadline to reach underlying net.Conn
- docs: add package doc and exported symbol comments to internal/ctx
and internal/io
- hosts/hosts.go: add package and symbol doc comments, fix missing
httpLoader.Close() in Close()
- hosts/plugin: add doc comments for HTTP and gRPC plugin types
- hop/hop.go: add doc comments, accumulate reload/parse errors via errors.Join
instead of silently discarding them
- hop/plugin/http.go: add doc comments and missing Close() method
- Add unit tests for hosts (580 lines) and hop (991 lines)
Remove unused WithContext interface (zero references in codebase), add
doc comments for all 14 exported symbols, and simplify HashFromContext
to match the one-liner pattern used by the other four getters.
Add 22 unit tests covering round-trip, empty context, wrong type, nil
values, multiple values, independent keys, and the Context interface.
Add nil checks for connect-options dialer and logger to prevent
nil-pointer panics when Connect is called without a DialerConnectOption
or LoggerOption. Add package and NewConnector godoc comments.
Add 10 unit tests covering construction, Init metadata parsing,
Connect success/reject/dial-error paths, nil dialer, nil logger,
and the reject conn stub.
Add godoc comments for all 62 exported symbols across 20 files in
config/parsing/: 23 MDKey constants, 35 Parse*/List/Default* functions,
3 TLS helpers, 1 Args struct with 7 fields, and the package doc.
Prevent data loss and nil panics across 5 parse functions:
- chain: nil-guard hop entries to avoid deref on empty YAML lists
- hop: build merged metadata map instead of writing inherited values
into the original NodeConfig; swap+restore around ParseNode call
- node: use local connCfg/dialCfg instead of overwriting cfg.Connector
and cfg.Dialer fields; only fill in Type when empty
- parser: preserve existing config file fields when env vars override
Level/Addr (was replacing the entire struct)
- router: only update ipNet from dst CIDR if parse succeeds, keeping
the route.Net fallback instead of overwriting with nil
- Add 808-line loader_test.go covering registerGroup, register, and Load
- Add package and exported symbol doc comments to loader.go
- Fix fmt.Errorf(resp.Status) → errors.New(resp.Status) in sd/plugin/http.go
(resp.Status is a plain string, not a format string)
- loader: guard cfg == nil in Load() to prevent nil-pointer dereference on
cfg.Log / cfg.TLS access.
- loader: defer logger.SetDefault and parsing.SetDefaultTLSConfig until
after register() succeeds, so a failed reload does not leave global
state (logger, default TLS) pointing at the new config while components
remain from the old config.
- loader: extract registerGroup[T] helper to eliminate repeated
unregister-then-register boilerplate. Entries are parsed and collected
before unregistering; a parse error now preserves the previous group
(old code unregistered first, then parsed, leaving an empty registry on
parse failure).
- hop: move cfg.SockOpts.Mark extraction outside the cfg.Metadata != nil
block so the socket mark is read even when hop-level metadata is absent.
- hop: fix copy-paste error in netns inheritance: v.Name was incorrectly
stored as MDKeyNetns instead of v.Netns (introduced in f71351f).
Upgrade github.com/pion/dtls from v2.2.6 to v3.1.1 to fix nonce reuse
vulnerability in AES-GCM ciphers (GHSA-9f3f-wv7r-qc8r). Migrate from
deprecated Config-struct API to ListenWithOptions/ClientWithOptions
options-based API.
v2 Config fields mapped to v3 functional options:
- Certificates, InsecureSkipVerify, ExtendedMasterSecret, ServerName,
RootCAs, ClientCAs, ClientAuth, FlightInterval, MTU
ConnectContextMaker removed — no longer exists in v3; explicit
HandshakeContext(ctx) on *Conn is the replacement for timeout control.