Files
x/handler/tunnel/entrypoint/config.go
T
ginuerzh 81db46b725 refactor(handler/tunnel): code review fixes and entrypoint subpackage extraction
- Fix dead-code branch in bind.go host assignment (always use endpoint hash)
- Return descriptive error on bypass match in connect.go (was masking as success)
- Update bypass test in connect_test.go for new error behavior
- Extract entrypoint subpackage from monolithic entrypoint.go (6 files)
- Fix observeStats event-loss bug (break -> fallthrough on retry success)
- Add 47 unit tests across handler, connect, bind, metadata packages
- Add architecture doc comments to all key files
- Build and vet clean, 173 tests pass with -race
2026-06-02 23:51:55 +08:00

87 lines
3.1 KiB
Go

package entrypoint
import (
"net"
"net/http"
"time"
"github.com/go-gost/core/ingress"
"github.com/go-gost/core/logger"
"github.com/go-gost/core/recorder"
"github.com/go-gost/core/sd"
)
// Config carries dependencies from the tunnel handler into the entrypoint.
//
// All fields must be set by the caller before calling New. The DialFunc
// bridges the package boundary to avoid an import cycle.
type Config struct {
// Node is the local tunnel node ID (from tunnelHandler.id).
Node string
// Service is the parent handler's service name, used for ingress lookups,
// logging, and TLS certificate selection.
Service string
Ingress ingress.Ingress
SD sd.SD
Logger logger.Logger
Recorder recorder.RecorderObject
SniffingWebsocket bool
WebsocketSampleRate float64
// ReadTimeout is applied as SetReadDeadline on upstream connections
// before sniffing HTTP/TLS reads. Also used as
// http.Transport.ResponseHeaderTimeout. 0 or negative defaults to 15s.
ReadTimeout time.Duration
// ProxyProtocol is the PROXY protocol version (1 or 2) for the listener.
ProxyProtocol int
// KeepAlive enables HTTP keep-alive for the transport. Disabled by default.
KeepAlive bool
// Compression enables HTTP transport-level compression. Disabled by default.
Compression bool
}
// DialFunc is the function signature for establishing a tunnel connection.
// Implemented by the parent package (tunnel) to avoid import cycles.
//
// ctx carries recorder objects and loggers for the tunnel connection.
// network is always "tcp" for entrypoint connections.
// tid is the string representation of the target tunnel ID.
type DialFunc func(ctx DialContext, network, tid string) (conn net.Conn, node, cid string, err error)
// DialContext carries metadata for a dial request.
// This interface satisfies the context.Context Value() contract,
// allowing the parent package to pass a real context.Context which is
// recovered via type assertion in the DialFunc implementation.
type DialContext interface {
Value(any) any
}
// New creates a new Entrypoint with the given config and dial function.
//
// The config fields are copied into the Entrypoint struct. The dial function
// is stored as-is — nil functions cause dial failures at runtime, not at
// construction time.
//
// The HTTP transport is initialized immediately with ep.dial as its
// DialContext; responses time out after cfg.ReadTimeout (default 15s).
func New(cfg *Config, dialFn DialFunc) *Entrypoint {
ep := &Entrypoint{
node: cfg.Node,
service: cfg.Service,
ingress: cfg.Ingress,
sd: cfg.SD,
log: cfg.Logger,
recorder: cfg.Recorder,
sniffingWebsocket: cfg.SniffingWebsocket,
websocketSampleRate: cfg.WebsocketSampleRate,
readTimeout: cfg.ReadTimeout,
dialFn: dialFn,
}
ep.transport = &http.Transport{
DialContext: ep.dial,
IdleConnTimeout: 30 * time.Second,
ResponseHeaderTimeout: cfg.ReadTimeout,
DisableKeepAlives: !cfg.KeepAlive,
DisableCompression: !cfg.Compression,
}
return ep
}