Files
x/handler/forward/remote/util.go
T
ginuerzh f8ddb193cb refactor(handler/forward/remote): split handler into 6 focused files with 41 tests
Split the 339-line handler monolith and 1169-line test blob into 11 files
(5 source + 6 test) following the handler/forward/local/ pattern.

Source files: handler.go (core), forward.go (raw forwarding),
sniffing.go (SnifferBuilder + protocol dispatch), util.go (errors +
recorder + rate limit), metadata.go (config parsing).

Fixes: add sync.Mutex for hop access (race), use sentinel errors for
errors.Is compatibility, add nil-addr guard in checkRateLimit, reuse
SnifferBuilder via Build() instead of per-call construction.
2026-05-30 16:27:20 +08:00

51 lines
1.3 KiB
Go

package remote
import (
"context"
"errors"
"net"
"time"
xctx "github.com/go-gost/x/ctx"
xrecorder "github.com/go-gost/x/recorder"
)
var (
errRouterNotAvailable = errors.New("router not available")
errNodeNotAvailable = errors.New("node not available")
)
// newRecorderObject creates a HandlerRecorderObject populated with connection
// metadata (service, addresses, network type, session ID, client address).
func (h *forwardHandler) newRecorderObject(ctx context.Context, conn net.Conn, start time.Time) *xrecorder.HandlerRecorderObject {
ro := &xrecorder.HandlerRecorderObject{
Service: h.options.Service,
RemoteAddr: conn.RemoteAddr().String(),
LocalAddr: conn.LocalAddr().String(),
Network: "tcp",
Time: start,
SID: xctx.SidFromContext(ctx).String(),
}
if srcAddr := xctx.SrcAddrFromContext(ctx); srcAddr != nil {
ro.ClientAddr = srcAddr.String()
}
if _, ok := conn.(net.PacketConn); ok {
ro.Network = "udp"
}
return ro
}
func (h *forwardHandler) checkRateLimit(addr net.Addr) bool {
if h.options.RateLimiter == nil {
return true
}
if addr == nil {
return true
}
host, _, _ := net.SplitHostPort(addr.String())
if limiter := h.options.RateLimiter.Limiter(host); limiter != nil {
return limiter.Allow(1)
}
return true
}