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.

Solutions

  1. Ensure the redirect handler only receives raw TCP connections (check listener type)
  2. Unwrap custom conn wrappers to the underlying *net.TCPConn before handling
  3. 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

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


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/2eb612867d206fd8. Report an issue: GitHub.

Appendix: 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)