mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
fix: disable SO_REUSEADDR & enable SO_EXCLUSIVEADDRUSE on Windows (#2128)
This commit is contained in:
Generated
+87
-6
@@ -2368,9 +2368,8 @@ dependencies = [
|
||||
"wildmatch",
|
||||
"winapi",
|
||||
"windivert",
|
||||
"windows 0.52.0",
|
||||
"windows 0.62.2",
|
||||
"windows-service",
|
||||
"windows-sys 0.52.0",
|
||||
"winreg 0.52.0",
|
||||
"x25519-dalek",
|
||||
"zerocopy 0.7.35",
|
||||
@@ -11234,11 +11233,23 @@ version = "0.61.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-collections 0.2.0",
|
||||
"windows-core 0.61.2",
|
||||
"windows-future",
|
||||
"windows-future 0.2.1",
|
||||
"windows-link 0.1.3",
|
||||
"windows-numerics",
|
||||
"windows-numerics 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||
dependencies = [
|
||||
"windows-collections 0.3.2",
|
||||
"windows-core 0.62.2",
|
||||
"windows-future 0.3.2",
|
||||
"windows-numerics 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11250,6 +11261,15 @@ dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
||||
dependencies = [
|
||||
"windows-core 0.62.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
@@ -11285,6 +11305,19 @@ dependencies = [
|
||||
"windows-strings 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||
dependencies = [
|
||||
"windows-implement 0.60.2",
|
||||
"windows-interface 0.59.3",
|
||||
"windows-link 0.2.1",
|
||||
"windows-result 0.4.1",
|
||||
"windows-strings 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.1"
|
||||
@@ -11293,7 +11326,18 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-link 0.1.3",
|
||||
"windows-threading",
|
||||
"windows-threading 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
||||
dependencies = [
|
||||
"windows-core 0.62.2",
|
||||
"windows-link 0.2.1",
|
||||
"windows-threading 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11362,6 +11406,16 @@ dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
||||
dependencies = [
|
||||
"windows-core 0.62.2",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.2.0"
|
||||
@@ -11391,6 +11445,15 @@ dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-service"
|
||||
version = "0.7.0"
|
||||
@@ -11421,6 +11484,15 @@ dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
@@ -11546,6 +11618,15 @@ dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-version"
|
||||
version = "0.1.7"
|
||||
|
||||
+6
-10
@@ -274,11 +274,15 @@ windivert = { git = "https://github.com/EasyTier/windivert-rust.git", rev = "adc
|
||||
] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows = { version = "0.52.0", features = [
|
||||
windows = { version = "0.62.2", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_NetworkManagement_IpHelper",
|
||||
"Win32_NetworkManagement_Ndis",
|
||||
"Win32_NetworkManagement_WindowsFirewall",
|
||||
"Win32_System_Com",
|
||||
"Win32_Networking",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_Diagnostics",
|
||||
"Win32_System_Diagnostics_Debug",
|
||||
"Win32_System_Ole",
|
||||
"Win32_System_Variant",
|
||||
"Win32_Networking_WinSock",
|
||||
@@ -287,14 +291,6 @@ windows = { version = "0.52.0", features = [
|
||||
encoding = "0.2"
|
||||
winreg = "0.52"
|
||||
windows-service = "0.7.0"
|
||||
windows-sys = { version = "0.52", features = [
|
||||
"Win32_NetworkManagement_IpHelper",
|
||||
"Win32_NetworkManagement_Ndis",
|
||||
"Win32_Networking_WinSock",
|
||||
"Win32_Foundation",
|
||||
"Win32_System_Diagnostics",
|
||||
"Win32_System_Diagnostics_Debug",
|
||||
] }
|
||||
winapi = { version = "0.3.9", features = ["impl-default"] }
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
|
||||
@@ -4,15 +4,16 @@ use anyhow::Context;
|
||||
use network_interface::NetworkInterfaceConfig;
|
||||
use windows::{
|
||||
Win32::{
|
||||
Foundation::{BOOL, FALSE},
|
||||
Foundation::FALSE,
|
||||
NetworkManagement::WindowsFirewall::{
|
||||
INetFwPolicy2, INetFwRule, NET_FW_ACTION_ALLOW, NET_FW_PROFILE2_DOMAIN,
|
||||
NET_FW_PROFILE2_PRIVATE, NET_FW_PROFILE2_PUBLIC, NET_FW_RULE_DIR_IN,
|
||||
NET_FW_RULE_DIR_OUT,
|
||||
},
|
||||
Networking::WinSock::{
|
||||
IP_UNICAST_IF, IPPROTO_IP, IPPROTO_IPV6, IPV6_UNICAST_IF, SIO_UDP_CONNRESET, SOCKET,
|
||||
SOCKET_ERROR, WSAGetLastError, WSAIoctl, htonl, setsockopt,
|
||||
IP_UNICAST_IF, IPPROTO_IP, IPPROTO_IPV6, IPV6_UNICAST_IF, SIO_UDP_CONNRESET,
|
||||
SO_EXCLUSIVEADDRUSE, SOCKET, SOCKET_ERROR, SOL_SOCKET, WSAGetLastError, WSAIoctl,
|
||||
htonl, setsockopt,
|
||||
},
|
||||
System::Com::{
|
||||
CLSCTX_ALL, COINIT_MULTITHREADED, CoCreateInstance, CoInitializeEx, CoUninitialize,
|
||||
@@ -20,7 +21,7 @@ use windows::{
|
||||
System::Ole::{SafeArrayCreateVector, SafeArrayPutElement},
|
||||
System::Variant::{VARENUM, VARIANT, VT_ARRAY, VT_BSTR, VT_VARIANT},
|
||||
},
|
||||
core::BSTR,
|
||||
core::{BOOL, BSTR},
|
||||
};
|
||||
|
||||
pub fn disable_connection_reset<S: AsRawSocket>(socket: &S) -> io::Result<()> {
|
||||
@@ -88,13 +89,7 @@ pub fn find_interface_index(iface_name: &str) -> io::Result<u32> {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn set_ip_unicast_if<S: AsRawSocket>(
|
||||
socket: &S,
|
||||
addr: &SocketAddr,
|
||||
iface: &str,
|
||||
) -> io::Result<()> {
|
||||
let handle = SOCKET(socket.as_raw_socket() as usize);
|
||||
|
||||
pub fn set_ip_unicast_if(socket: SOCKET, addr: &SocketAddr, iface: &str) -> io::Result<()> {
|
||||
let if_index = find_interface_index(iface)?;
|
||||
|
||||
unsafe {
|
||||
@@ -103,12 +98,12 @@ pub fn set_ip_unicast_if<S: AsRawSocket>(
|
||||
SocketAddr::V4(..) => {
|
||||
let if_index = htonl(if_index);
|
||||
let if_index_bytes = if_index.to_ne_bytes();
|
||||
setsockopt(handle, IPPROTO_IP.0, IP_UNICAST_IF, Some(&if_index_bytes))
|
||||
setsockopt(socket, IPPROTO_IP.0, IP_UNICAST_IF, Some(&if_index_bytes))
|
||||
}
|
||||
SocketAddr::V6(..) => {
|
||||
let if_index_bytes = if_index.to_ne_bytes();
|
||||
setsockopt(
|
||||
handle,
|
||||
socket,
|
||||
IPPROTO_IPV6.0,
|
||||
IPV6_UNICAST_IF,
|
||||
Some(&if_index_bytes),
|
||||
@@ -141,8 +136,16 @@ pub fn setup_socket_for_win<S: AsRawSocket>(
|
||||
disable_connection_reset(socket)?;
|
||||
}
|
||||
|
||||
let socket = SOCKET(socket.as_raw_socket() as usize);
|
||||
let optval = 1_i32.to_ne_bytes();
|
||||
unsafe {
|
||||
if setsockopt(socket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, Some(&optval)) == SOCKET_ERROR {
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(iface) = bind_dev {
|
||||
set_ip_unicast_if(socket, bind_addr, iface.as_str())?;
|
||||
set_ip_unicast_if(socket, bind_addr, &iface)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -152,7 +155,7 @@ struct ComInitializer;
|
||||
|
||||
impl ComInitializer {
|
||||
fn new() -> windows::core::Result<Self> {
|
||||
unsafe { CoInitializeEx(None, COINIT_MULTITHREADED)? };
|
||||
unsafe { CoInitializeEx(None, COINIT_MULTITHREADED).ok()? };
|
||||
Ok(Self)
|
||||
}
|
||||
}
|
||||
@@ -354,7 +357,7 @@ fn add_protocol_firewall_rules(
|
||||
(*interface_variant.Anonymous.Anonymous).vt = VARENUM(VT_ARRAY.0 | VT_VARIANT.0);
|
||||
(*interface_variant.Anonymous.Anonymous).Anonymous.parray = interface_array;
|
||||
|
||||
rule.SetInterfaces(interface_variant)?;
|
||||
rule.SetInterfaces(&interface_variant)?;
|
||||
|
||||
// Get rule collection and add new rule
|
||||
let rules = policy.Rules()?;
|
||||
|
||||
@@ -6,15 +6,16 @@ use cidr::{Ipv4Inet, Ipv6Inet};
|
||||
use std::{
|
||||
io,
|
||||
net::{Ipv4Addr, Ipv6Addr},
|
||||
ptr::null_mut,
|
||||
};
|
||||
use windows_sys::Win32::{
|
||||
use windows::Win32::NetworkManagement::IpHelper::INTERNAL_IF_OPER_STATUS;
|
||||
use windows::Win32::{
|
||||
Foundation::NO_ERROR,
|
||||
NetworkManagement::IpHelper::{GetIfEntry, MIB_IFROW, SetIfEntry},
|
||||
System::Diagnostics::Debug::{
|
||||
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_IGNORE_INSERTS, FormatMessageW,
|
||||
},
|
||||
};
|
||||
use windows::core::PWSTR;
|
||||
use winreg::{
|
||||
RegKey,
|
||||
enums::{HKEY_LOCAL_MACHINE, KEY_READ, KEY_WRITE},
|
||||
@@ -32,12 +33,12 @@ fn format_win_error(error: u32) -> String {
|
||||
unsafe {
|
||||
FormatMessageW(
|
||||
flags,
|
||||
null_mut(),
|
||||
None,
|
||||
error,
|
||||
0,
|
||||
buffer.as_mut_ptr(),
|
||||
PWSTR(buffer.as_mut_ptr()),
|
||||
size,
|
||||
null_mut(),
|
||||
None,
|
||||
);
|
||||
}
|
||||
let str_end = buffer.iter().position(|&b| b == 0).unwrap_or(buffer.len());
|
||||
@@ -100,7 +101,7 @@ impl WindowsIfConfiger {
|
||||
dwPhysAddrLen: 0,
|
||||
bPhysAddr: [0; 8],
|
||||
dwAdminStatus: if up { 1 } else { 2 }, // 1 = up, 2 = down
|
||||
dwOperStatus: 0,
|
||||
dwOperStatus: INTERNAL_IF_OPER_STATUS(0),
|
||||
dwLastChange: 0,
|
||||
dwInOctets: 0,
|
||||
dwInUcastPkts: 0,
|
||||
@@ -118,8 +119,8 @@ impl WindowsIfConfiger {
|
||||
bDescr: [0; 256],
|
||||
};
|
||||
|
||||
if GetIfEntry(&mut if_row) == NO_ERROR {
|
||||
if SetIfEntry(&if_row) == NO_ERROR {
|
||||
if GetIfEntry(&mut if_row) == NO_ERROR.0 {
|
||||
if SetIfEntry(&if_row) == NO_ERROR.0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow::anyhow!("Failed to set interface status").into())
|
||||
|
||||
@@ -423,7 +423,7 @@ fn setup_socket2_ext(
|
||||
}
|
||||
|
||||
socket2_socket.set_nonblocking(true)?;
|
||||
socket2_socket.set_reuse_address(true)?;
|
||||
socket2_socket.set_reuse_address(!cfg!(target_os = "windows"))?;
|
||||
if let Err(e) = socket2_socket.bind(&socket2::SockAddr::from(*bind_addr)) {
|
||||
if bind_addr.is_ipv4() {
|
||||
return Err(e.into());
|
||||
|
||||
Reference in New Issue
Block a user