diff --git a/socksx/Cargo.toml b/socksx/Cargo.toml index 8435102..c0632da 100644 --- a/socksx/Cargo.toml +++ b/socksx/Cargo.toml @@ -18,13 +18,18 @@ human-panic = "1" itertools = "0.10" libc = "0.2" log = "0.4" -nix = "0.21" num-derive = "0.3" num-traits = "0.2" thiserror = "1" tokio = { version = "1", features = ["full"] } url = "2.2" +[target.'cfg(unix)'.dependencies] +nix = "0.21" + +[target.'cfg(windows)'.dependencies] +windows = { version = "0.48", features = ["Win32_Networking_WinSock"] } + [dev-dependencies] chacha20 = "0.7" pin-project-lite = "0.2" diff --git a/socksx/examples/client.rs b/socksx/examples/client.rs index 3c8f5b4..41c7450 100644 --- a/socksx/examples/client.rs +++ b/socksx/examples/client.rs @@ -59,9 +59,12 @@ async fn connect_v5( proxy_addr: String, dest_addr: String, ) -> Result<()> { + println!("Creating client..."); let client = Socks5Client::new(proxy_addr, None).await?; + println!("Connecting..."); let (mut outgoing, _) = client.connect(dest_addr).await?; + println!("Writing message!"); outgoing.write(String::from("Hello, world!\n").as_bytes()).await?; Ok(()) diff --git a/socksx/src/common/util.rs b/socksx/src/common/util.rs index 098961e..f631223 100644 --- a/socksx/src/common/util.rs +++ b/socksx/src/common/util.rs @@ -1,23 +1,48 @@ use anyhow::Result; -use std::{net::SocketAddr, os}; +use std::net::SocketAddr; use tokio::net::{self, TcpStream}; /// /// /// -#[cfg(any(target_os = "linux"))] -pub fn get_original_dst(socket: &S) -> Result { +#[cfg(target_os = "linux")] +pub fn get_original_dst(socket: &S) -> Result { use nix::sys::socket::{self, sockopt, InetAddr}; - let orignal_dst = socket::getsockopt(socket.as_raw_fd(), sockopt::OriginalDst)?; - let orignal_dst = InetAddr::V4(orignal_dst).to_std(); + let original_dst = socket::getsockopt(socket.as_raw_fd(), sockopt::OriginalDst)?; + let original_dst = InetAddr::V4(original_dst).to_std(); - Ok(orignal_dst) + println!("{original_dst}"); + Ok(original_dst) } -#[cfg(not(any(target_os = "linux")))] -pub fn get_original_dst(_socket: &S) -> Result { - todo!() +#[cfg(target_os = "windows")] +pub fn get_original_dst(socket: &S) -> Result { + use std::str::FromStr; + use windows::core::PSTR; + use windows::Win32::Networking::WinSock::{SO_ORIGINAL_DST, SOCKET, SOL_SOCKET, getsockopt}; + + // Attempt to recover the original destination + let original_dst: String = unsafe { + // Write the socket option to a buffer + let mut original_dst : [u8; 256] = [0; 256]; + let mut n_bytes : i32 = 256; + if getsockopt(SOCKET(socket.as_raw_socket() as usize), SOL_SOCKET, SO_ORIGINAL_DST as i32, PSTR((&mut original_dst) as *mut u8), &mut n_bytes) != 0 { + panic!("Failed to get original address from socket"); + } + + // Parse it as an address + String::from_utf8_lossy(&original_dst[..n_bytes as usize]).into() + }; + + // Now return the parsed socket address + println!("{original_dst}"); + Ok(SocketAddr::from_str(&original_dst)?) +} + +#[cfg(not(any(target_os = "linux", target_os = "windows")))] +pub fn get_original_dst(socket: S) -> Result { + todo!(); } ///