{"record":{"id":"dbf81bbd776680a5","repo":"shadowsocks/shadowsocks-rust","slug":"not-supported-udp-transparent-proxy-type-dbf81b","errorCode":null,"errorMessage":"not supported udp transparent proxy type","messagePattern":"not supported udp transparent proxy type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/linux.rs","lineNumber":63,"sourceCode":"                libc::setsockopt(\n                    socket.as_raw_fd(),\n                    libc::SOL_SOCKET,\n                    libc::SO_MARK,\n                    &mark as *const _ as *const _,\n                    mem::size_of_val(&mark) as libc::socklen_t,\n                )\n            };\n            if ret != 0 {\n                return Err(Error::last_os_error());\n            }\n        }\n\n        Ok(socket)\n    }\n\n    fn bind(ty: RedirType, addr: SocketAddr, reuse_port: bool) -> io::Result<Self> {\n        if ty != RedirType::TProxy {\n            return Err(Error::new(\n                ErrorKind::InvalidInput,\n                \"not supported udp transparent proxy type\",\n            ));\n        }\n\n        let socket = Socket::new(Domain::for_address(addr), Type::DGRAM, Some(Protocol::UDP))?;\n        set_socket_before_bind(&addr, &socket)?;\n\n        socket.set_nonblocking(true)?;\n        socket.set_reuse_address(true)?;\n        if reuse_port && let Err(err) = socket.set_reuse_port(true) {\n            if let Some(libc::ENOPROTOOPT) = err.raw_os_error() {\n                // SO_REUSEPORT is supported after 3.9\n                trace!(\"failed to set SO_REUSEPORT, error: {}\", err);\n            } else {\n                error!(\"failed to set SO_REUSEPORT, error: {}\", err);\n                return Err(err);\n            }","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/local/redir/udprelay/sys/unix/linux.rs#L45-L81","documentation":"bind() on Linux UDP transparent proxy only supports RedirType::TProxy for UDP; any other RedirType (e.g. Redirect) yields InvalidInput. It is a compile-time-style runtime guard ensuring the caller picks a UDP-capable transparent proxy mode.","triggerScenarios":"Calling UdpRedirSocket::bind (directly or via bind_nonlocal) with ty set to anything other than RedirType::TProxy on Linux — typically because the config's udp redir type was set to 'redirect' or left as NotSupported.","commonSituations":"Configuring the local redir server with redir-type=redirect for TCP but reusing the same type for UDP; on Linux UDP requires tproxy (TPROXY iptables rules).","solutions":["Set the UDP transparent proxy type to 'tproxy' in the local server configuration","Add iptables TPROXY rules (mangle table, PREROUTING with TPROXY target) so tproxy mode actually works","If only plain redirect is available, do not instantiate the UDP relay with the redirect type","Verify the RedirType enum value passed in comes from parsed config, not a default"],"exampleFix":"// before\nlet ty = RedirType::Redirect;\nUdpRedirSocket::bind(ty, addr, false)?;\n// after\nlet ty = RedirType::TProxy; // UDP on Linux requires tproxy\nUdpRedirSocket::bind(ty, addr, false)?;","handlingStrategy":"validation","validationCode":"if redir_type != RedirType::TProxy {\n    return Err(\"Linux UDP transparent proxy requires redir-type=tproxy\");\n}","typeGuard":"fn udp_supported(ty: RedirType) -> bool { matches!(ty, RedirType::TProxy) }","tryCatchPattern":"match UdpRedirSocket::bind(ty, addr, reuse) { Err(e) if e.kind()==InvalidInput => bail!(\"configure udp redir-type=tproxy\"), r => r }","preventionTips":["Set redir-type=tproxy for UDP on Linux","Validate config RedirType at startup","Install iptables TPROXY rules before starting the server","Keep TCP (redirect) and UDP (tproxy) types separate in config"],"tags":["network","udp","transparent-proxy","linux","config"],"backgroundTag":"invalid-enum-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}