{"record":{"id":"2eb612867d206fd8","repo":"ginuerzh/gost","slug":"not-a-tcp-connection","errorCode":null,"errorMessage":"not a TCP connection","messagePattern":"not a TCP connection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"redirect.go","lineNumber":102,"sourceCode":"\t\treturn\n\t}\n\n\t// only ipv4 support\n\tip := net.IPv4(mreq.Multiaddr[4], mreq.Multiaddr[5], mreq.Multiaddr[6], mreq.Multiaddr[7])\n\tport := uint16(mreq.Multiaddr[2])<<8 + uint16(mreq.Multiaddr[3])\n\taddr, err = net.ResolveTCPAddr(\"tcp4\", fmt.Sprintf(\"%s:%d\", ip.String(), port))\n\tif err != nil {\n\t\treturn\n\t}\n\n\tcc, err := net.FileConn(fc)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tc, ok := cc.(*net.TCPConn)\n\tif !ok {\n\t\terr = errors.New(\"not a TCP connection\")\n\t}\n\treturn\n}\n\ntype udpRedirectHandler struct {\n\toptions *HandlerOptions\n}\n\n// UDPRedirectHandler creates a server Handler for UDP transparent server.\nfunc UDPRedirectHandler(opts ...HandlerOption) Handler {\n\th := &udpRedirectHandler{}\n\th.Init(opts...)\n\n\treturn h\n}\n\nfunc (h *udpRedirectHandler) Init(options ...HandlerOption) {\n\tif h.options == nil {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/redirect.go#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ngo tcpHandler.Handle(conn) // conn may be a wrapped/UDP conn\n// after\nif tc, ok := conn.(*net.TCPConn); ok {\n    go tcpHandler.Handle(tc)\n} else {\n    log.Log(\"skipping non-TCP conn in redirect handler\")\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func asTCPConn(c net.Conn) (*net.TCPConn, bool) {\n    tc, ok := c.(*net.TCPConn)\n    return tc, ok\n}","tryCatchPattern":"if _, ok := conn.(*net.TCPConn); !ok {\n    // route to the appropriate (e.g. UDP) handler or skip\n    return\n}","preventionTips":["Keep TCP redirect handlers strictly for TCP listeners","Unwrap custom conn wrappers to the raw *net.TCPConn","Use separate handlers for UDP transparent proxy"],"tags":["transparent-proxy","tcp","redirect","type-assertion"],"backgroundTag":"connection-type-mismatch","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}