{"record":{"id":"29184bc15e98d561","repo":"shadowsocks/shadowsocks-rust","slug":"iface","errorCode":null,"errorMessage":"iface","messagePattern":"iface","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks/src/net/sys/windows/mod.rs","lineNumber":283,"sourceCode":"        static INTERFACE_INDEX_CACHE: RefCell<HashMap<String, (u32, Instant)>> =\n            RefCell::new(HashMap::new());\n    }\n\n    let cache_index = INTERFACE_INDEX_CACHE.with(|cache| cache.borrow().get(iface).cloned());\n    if let Some((idx, insert_time)) = cache_index {\n        // short-path, cache hit for most cases\n        let now = Instant::now();\n        if now - insert_time < INDEX_EXPIRE_DURATION {\n            return Ok(idx);\n        }\n    }\n\n    // Get from API GetAdaptersAddresses\n    let idx = match find_adapter_interface_index(addr, iface)? {\n        Some(idx) => idx,\n        None => unsafe {\n            // Windows if_nametoindex requires a C-string for interface name\n            let ifname = CString::new(iface).expect(\"iface\");\n\n            // https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/ff553788(v=vs.85)\n            let if_index = if_nametoindex(ifname.as_ptr() as PCSTR);\n            if if_index == 0 {\n                // If the if_nametoindex function fails and returns zero, it is not possible to determine an error code.\n                error!(\"if_nametoindex {} fails\", iface);\n                return Err(io::Error::new(ErrorKind::InvalidInput, \"invalid interface name\"));\n            }\n\n            if_index\n        },\n    };\n\n    INTERFACE_INDEX_CACHE.with(|cache| {\n        cache.borrow_mut().insert(iface.to_owned(), (idx, Instant::now()));\n    });\n\n    Ok(idx)","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks/src/net/sys/windows/mod.rs#L265-L301","documentation":"On Windows, when resolving an interface name to an index for IP_UNICAST_IF, the code first tries GetAdaptersAddresses; failing that, it calls if_nametoindex with the interface name converted via CString::new().expect(\"iface\"). CString::new fails when the string contains an interior NUL byte, so an interface name with '\\0' panics instead of producing a user-facing error.","triggerScenarios":"Calling set_ip_unicast_if with an interface name containing a NUL byte (corrupt config value, incorrectly parsed CLI argument), after GetAdaptersAddresses could not find the adapter.","commonSituations":"Config files with mangled/escaped interface names on Windows; binary garbage read into the iface field; users specifying a GUID or description instead of the interface name so adapter lookup fails and the CString path runs on bad input.","solutions":["Validate the interface name (non-empty, no NUL bytes) before calling set_ip_unicast_if","Replace expect with error propagation: CString::new(iface).map_err(...)? and log/return a config error","Verify the interface name matches an adapter name shown by `ipconfig /all` or `netsh interface show interface`","If GetAdaptersAddresses already failed, prefer surfacing that error rather than falling through to if_nametoindex with unvalidated input"],"exampleFix":"// before\nlet ifname = CString::new(iface).expect(\"iface\");\n// after\nlet ifname = CString::new(iface).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, format!(\"invalid interface name: {:?}\", iface)))?;","handlingStrategy":"validation","validationCode":"fn valid_iface(name: &str) -> bool { !name.is_empty() && !name.contains('\\0') && name.len() < IFNAMSIZ }","typeGuard":"fn sanitize_iface(name: &str) -> Option<CString> { CString::new(name).ok() }","tryCatchPattern":"let ifname = CString::new(iface).map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;","preventionTips":["Validate interface names read from config for NUL/control bytes","Use the exact adapter name from `netsh interface show interface`","Prefer interface index or GUID where the API allows"],"tags":["rust","windows","panic","network-interface"],"backgroundTag":"invalid-argument-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}