ginuerzh/gost · error
not a TCP connection
Error message
not a TCP connection
What it means
getOriginalDstAddr needs to access OS-specific socket options that only exist on *net.TCPConn to recover the original destination address of a transparently redirected connection. If the underlying connection is not a TCP connection, the retrieval cannot proceed and this error is returned.
Source
Thrown at redirect.go:102
return
}
// only ipv4 support
ip := net.IPv4(mreq.Multiaddr[4], mreq.Multiaddr[5], mreq.Multiaddr[6], mreq.Multiaddr[7])
port := uint16(mreq.Multiaddr[2])<<8 + uint16(mreq.Multiaddr[3])
addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", ip.String(), port))
if err != nil {
return
}
cc, err := net.FileConn(fc)
if err != nil {
return
}
c, ok := cc.(*net.TCPConn)
if !ok {
err = errors.New("not a TCP connection")
}
return
}
type udpRedirectHandler struct {
options *HandlerOptions
}
// UDPRedirectHandler creates a server Handler for UDP transparent server.
func UDPRedirectHandler(opts ...HandlerOption) Handler {
h := &udpRedirectHandler{}
h.Init(opts...)
return h
}
func (h *udpRedirectHandler) Init(options ...HandlerOption) {
if h.options == nil {View on GitHub (pinned to a33fdbf4c9)
Solutions
- Ensure the redirect handler only receives raw TCP connections (check listener type)
- Unwrap custom conn wrappers to the underlying *net.TCPConn before handling
- For UDP traffic, use the UDP redirect handler instead
Example fix
// before
go tcpHandler.Handle(conn) // conn may be a wrapped/UDP conn
// after
if tc, ok := conn.(*net.TCPConn); ok {
go tcpHandler.Handle(tc)
} else {
log.Log("skipping non-TCP conn in redirect handler")
} Defensive patterns
Strategy: type-guard
Type guard
func asTCPConn(c net.Conn) (*net.TCPConn, bool) {
tc, ok := c.(*net.TCPConn)
return tc, ok
} Try / catch
if _, ok := conn.(*net.TCPConn); !ok {
// route to the appropriate (e.g. UDP) handler or skip
return
} Prevention
- Keep TCP redirect handlers strictly for TCP listeners
- Unwrap custom conn wrappers to the raw *net.TCPConn
- Use separate handlers for UDP transparent proxy
When it happens
Trigger: Handle is invoked on a connection whose underlying type fails the type assertion cc.(*net.TCPConn) — e.g. a UDP flow or a wrapped/tunneled conn passed to a TCP redirect handler.
Common situations: Wiring a UDP listener's connections into the TCP redirect handler, or wrapping conns in a custom type that doesn't expose the inner *net.TCPConn via Unwrap-style access.
Related errors
- accpet on closed listener
- wrong connection type
- kcp: wrong connection type
- UDP redirect is not available on the Windows platform
- not a packet connection
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/2eb612867d206fd8.
Report an issue: GitHub.