Skip to content

Commit 69ca302

Browse files
committed
Add windows original dst
Signed-off-by: keithmattix <[email protected]>
1 parent ed8faff commit 69ca302

File tree

2 files changed

+31
-41
lines changed

2 files changed

+31
-41
lines changed

src/sys/windows.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -955,11 +955,22 @@ impl crate::Socket {
955955
#[cfg(feature = "all")]
956956
#[cfg_attr(docsrs, doc(cfg(all(windows, feature = "all"))))]
957957
pub fn original_dst_ipv6(&self) -> io::Result<SockAddr> {
958-
use windows_sys::Win32::Networking::WinSock::SOL_IPV6;
959-
960958
unsafe {
961-
getsockopt::<SockAddr>(self.as_raw(), SOL_IPV6 as i32, IP6T_SO_ORIGINAL_DST as i32)
959+
SockAddr::try_init(|storage, len| {
960+
syscall!(
961+
getsockopt(
962+
self.as_raw(),
963+
SOL_IP as i32,
964+
IP6T_SO_ORIGINAL_DST as i32,
965+
storage.cast(),
966+
len,
967+
),
968+
PartialEq::eq,
969+
SOCKET_ERROR
970+
)
971+
})
962972
}
973+
.map(|(_, addr)| addr)
963974
}
964975

965976
/// Returns the [`Protocol`] of this socket by checking the `SO_PROTOCOL_INFOW`

tests/socket.rs

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ use std::num::NonZeroUsize;
4242
use std::os::unix::io::AsRawFd;
4343
#[cfg(windows)]
4444
use std::os::windows::io::AsRawSocket;
45+
use windows_sys::Win32::Networking::WinSock::WSAEINVAL;
46+
4547
#[cfg(unix)]
4648
use std::path::Path;
4749
use std::str;
@@ -1607,59 +1609,36 @@ fn original_dst() {
16071609
}
16081610

16091611
#[test]
1610-
#[cfg(all(
1611-
feature = "all",
1612-
target_os = "windows"
1613-
))]
1612+
#[cfg(all(feature = "all", target_os = "windows"))]
16141613
fn original_dst() {
1615-
use windows_sys::Win32::Networking::WinSock::SOMAXCONN;
1616-
1617-
1618-
let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).unwrap();
1619-
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
1620-
match socket.bind(&SockAddr::from(addr)) {
1621-
Ok(_) => {}
1622-
Err(err) => panic!("failed to bind socket: {}", err),
1623-
};
1624-
match socket.listen(SOMAXCONN as i32) {
1625-
Ok(_) => {}
1626-
Err(err) => panic!("failed to listen on socket: {}", err),
1627-
};
1628-
// Socket must be in an accepting state for SOL_IP and SO_ORIGINAL_DST
1629-
match socket.accept() {
1630-
Ok((socket, _)) => {
1631-
match socket.original_dst() {
1632-
Ok(addr) => {
1633-
println!("Original destination: {:?}", addr);
1634-
}
1635-
Err(err) => panic!("failed to get original destination: {}", err),
1636-
}
1637-
}
1638-
Err(err) => panic!("failed to accept connection: {}", err),
1639-
1640-
};
1614+
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
1615+
match socket.original_dst() {
1616+
Ok(_) => panic!("original_dst on non-redirected socket should fail"),
1617+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
1618+
}
16411619

1642-
// let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
1643-
// match socket.original_dst() {
1644-
// Ok(_) => panic!("original_dst on non-redirected socket should fail"),
1645-
// Err(err) => assert_eq!(err.raw_os_error(), Some(SOCKET_ERROR)),
1646-
// }
1620+
// Not supported on IPv6 socket.
1621+
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
1622+
match socket.original_dst_ipv6() {
1623+
Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"),
1624+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
1625+
}
16471626
}
16481627

16491628
#[test]
1650-
#[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))]
1629+
#[cfg(all(feature = "all", target_os = "windows"))]
16511630
fn original_dst_ipv6() {
16521631
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
16531632
match socket.original_dst_ipv6() {
16541633
Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"),
1655-
Err(err) => assert_eq!(err.raw_os_error(), Some(libc::ENOENT)),
1634+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
16561635
}
16571636

16581637
// Not supported on IPv4 socket.
16591638
let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap();
16601639
match socket.original_dst_ipv6() {
16611640
Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"),
1662-
Err(err) => assert_eq!(err.raw_os_error(), Some(libc::EOPNOTSUPP)),
1641+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
16631642
}
16641643
}
16651644

0 commit comments

Comments
 (0)