{"record":{"id":"44f13bc69119634e","repo":"ginuerzh/gost","slug":"not-a-packet-connection","errorCode":null,"errorMessage":"not a packet connection","messagePattern":"not a packet connection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tuntap.go","lineNumber":178,"sourceCode":"\t\t\treturn\n\t\t}\n\t}\n\n\tvar tempDelay time.Duration\n\tfor {\n\t\terr := func() error {\n\t\t\tvar err error\n\t\t\tvar pc net.PacketConn\n\t\t\t// fake tcp mode will be ignored when the client specifies a chain.\n\t\t\tif raddr != nil && !h.options.Chain.IsEmpty() {\n\t\t\t\tcc, err := h.options.Chain.DialContext(context.Background(), \"udp\", raddr.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tvar ok bool\n\t\t\t\tpc, ok = cc.(net.PacketConn)\n\t\t\t\tif !ok {\n\t\t\t\t\terr = errors.New(\"not a packet connection\")\n\t\t\t\t\tlog.Logf(\"[tun] %s - %s: %s\", conn.LocalAddr(), raddr, err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif h.options.TCPMode {\n\t\t\t\t\tif raddr != nil {\n\t\t\t\t\t\tpc, err = tcpraw.Dial(\"tcp\", raddr.String())\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpc, err = tcpraw.Listen(\"tcp\", h.options.Node.Addr)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tladdr, _ := net.ResolveUDPAddr(\"udp\", h.options.Node.Addr)\n\t\t\t\t\tpc, err = net.ListenUDP(\"udp\", laddr)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/tuntap.go#L160-L196","documentation":"When routing UDP-like traffic through the TUN stack, the code takes the established connection cc and asserts it to net.PacketConn. If the underlying connection doesn't implement PacketConn (it's a stream conn), it returns \"not a packet connection\" and logs it with the tun prefix. This guards the packet-forwarding path which requires WriteTo/ReadFrom semantics.","triggerScenarios":"TUN in non-TCP mode forwarding a UDP flow whose relayed connection cc is a stream-oriented net.Conn (e.g. a TCP/mux relay) rather than a net.PacketConn; config routes UDP traffic over a TCP-only transport.","commonSituations":"Routing tun UDP traffic through a TCP-mode relay/chain; version or config change where the UDP relay dialer started returning stream conns; mixing TCPMode with UDP routes.","solutions":["Use a UDP-capable transport/relay (one that returns net.PacketConn) for tun UDP routes","Check the connection type before forwarding and fall back to a packet-capable relay chain","If TCPMode is intended, ensure UDP flows aren't routed through this code path (route/filter them at the tun option level)"],"exampleFix":"// before\npc, ok := cc.(net.PacketConn)\nif !ok { return errors.New(\"not a packet connection\") }\n// after\npc, ok := cc.(net.PacketConn)\nif !ok {\n    pc, err = dialPacketConn(raddr) // use a UDP-capable dialer\n    if err != nil { return err }\n}","handlingStrategy":"type-guard","validationCode":"pc, ok := cc.(net.PacketConn)\nif !ok {\n    // route via a UDP-capable relay before entering the packet path\n    return errors.New(\"transport does not support packet connections\")\n}","typeGuard":"func toPacketConn(c net.Conn) (net.PacketConn, bool) {\n    pc, ok := c.(net.PacketConn)\n    return pc, ok\n}","tryCatchPattern":"if err := forward(conn, raddr); err != nil {\n    if err.Error() == \"not a packet connection\" {\n        // fall back to a UDP-capable relay chain\n        return forwardViaPacketRelay(conn, raddr)\n    }\n    return err\n}","preventionTips":["Configure tun UDP routes to use UDP-capable transports/relays only","Verify chain hops support net.PacketConn before enabling tun UDP mode","Don't mix TCPMode transports with UDP tun routing"],"tags":["tun","udp","packet-conn","type-assertion","routing"],"backgroundTag":"not-a-packet-connection","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}