Skip to content

Commit 227ae86

Browse files
committed
Implement original_dst for windows
Signed-off-by: Keith Mattix II <[email protected]>
1 parent 3a93893 commit 227ae86

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ include = [
2929
[package.metadata.docs.rs]
3030
all-features = true
3131
rustdoc-args = ["--cfg", "docsrs"]
32-
targets = ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-unknown-fuchsia", "x86_64-pc-windows-msvc", "x86_64-pc-solaris", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-redox", "armv7-linux-androideabi", "i686-linux-android"]
32+
targets = ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-unknown-fuchsia", "x86_64-pc-windows-msvc", "x86_64-pc-windows-gnu", "x86_64-pc-solaris", "x86_64-unknown-freebsd", "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", "x86_64-unknown-redox", "armv7-linux-androideabi", "i686-linux-android"]
3333

3434
[package.metadata.playground]
3535
features = ["all"]

src/sys/windows.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@ use std::time::{Duration, Instant};
2020
use std::{process, ptr, slice};
2121

2222
use windows_sys::Win32::Foundation::{SetHandleInformation, HANDLE, HANDLE_FLAG_INHERIT};
23-
#[cfg(feature = "all")]
24-
use windows_sys::Win32::Networking::WinSock::SO_PROTOCOL_INFOW;
2523
use windows_sys::Win32::Networking::WinSock::{
2624
self, tcp_keepalive, FIONBIO, IN6_ADDR, IN6_ADDR_0, INVALID_SOCKET, IN_ADDR, IN_ADDR_0,
2725
POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, SD_BOTH, SD_RECEIVE, SD_SEND, SIO_KEEPALIVE_VALS,
2826
SOCKET_ERROR, WSABUF, WSAEMSGSIZE, WSAESHUTDOWN, WSAPOLLFD, WSAPROTOCOL_INFOW,
2927
WSA_FLAG_NO_HANDLE_INHERIT, WSA_FLAG_OVERLAPPED,
3028
};
29+
#[cfg(feature = "all")]
30+
use windows_sys::Win32::Networking::WinSock::{
31+
IP6T_SO_ORIGINAL_DST, SOL_IP, SO_ORIGINAL_DST, SO_PROTOCOL_INFOW,
32+
};
3133
use windows_sys::Win32::System::Threading::INFINITE;
3234

3335
use crate::{MsgHdr, RecvFlags, SockAddr, TcpKeepalive, Type};
@@ -927,6 +929,52 @@ impl crate::Socket {
927929
}
928930
}
929931

932+
/// Get the value for the `SO_ORIGINAL_DST` option on this socket.
933+
///
934+
#[cfg(feature = "all")]
935+
#[cfg_attr(docsrs, doc(cfg(all(windows, feature = "all"))))]
936+
pub fn original_dst(&self) -> io::Result<SockAddr> {
937+
unsafe {
938+
SockAddr::try_init(|storage, len| {
939+
syscall!(
940+
getsockopt(
941+
self.as_raw(),
942+
SOL_IP as i32,
943+
SO_ORIGINAL_DST as i32,
944+
storage.cast(),
945+
len,
946+
),
947+
PartialEq::eq,
948+
SOCKET_ERROR
949+
)
950+
})
951+
}
952+
.map(|(_, addr)| addr)
953+
}
954+
955+
/// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket.
956+
///
957+
#[cfg(feature = "all")]
958+
#[cfg_attr(docsrs, doc(cfg(all(windows, feature = "all"))))]
959+
pub fn original_dst_ipv6(&self) -> io::Result<SockAddr> {
960+
unsafe {
961+
SockAddr::try_init(|storage, len| {
962+
syscall!(
963+
getsockopt(
964+
self.as_raw(),
965+
SOL_IP as i32,
966+
IP6T_SO_ORIGINAL_DST as i32,
967+
storage.cast(),
968+
len,
969+
),
970+
PartialEq::eq,
971+
SOCKET_ERROR
972+
)
973+
})
974+
}
975+
.map(|(_, addr)| addr)
976+
}
977+
930978
/// Returns the [`Protocol`] of this socket by checking the `SO_PROTOCOL_INFOW`
931979
/// option on this socket.
932980
///

tests/socket.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ use std::num::NonZeroUsize;
4242
use std::os::unix::io::AsRawFd;
4343
#[cfg(windows)]
4444
use std::os::windows::io::AsRawSocket;
45+
#[cfg(windows)]
46+
use windows_sys::Win32::Networking::WinSock::WSAEINVAL;
47+
4548
#[cfg(unix)]
4649
use std::path::Path;
4750
use std::str;
@@ -1607,7 +1610,27 @@ fn original_dst() {
16071610
}
16081611

16091612
#[test]
1610-
#[cfg(all(feature = "all", any(target_os = "android", target_os = "linux")))]
1613+
#[cfg(all(feature = "all", target_os = "windows"))]
1614+
fn original_dst() {
1615+
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
1616+
match socket.original_dst() {
1617+
Ok(_) => panic!("original_dst on non-redirected socket should fail"),
1618+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
1619+
}
1620+
1621+
// Not supported on IPv6 socket.
1622+
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
1623+
match socket.original_dst_ipv6() {
1624+
Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"),
1625+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
1626+
}
1627+
}
1628+
1629+
#[test]
1630+
#[cfg(all(
1631+
feature = "all",
1632+
any(target_os = "android", target_os = "fuchsia", target_os = "linux")
1633+
))]
16111634
fn original_dst_ipv6() {
16121635
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
16131636
match socket.original_dst_ipv6() {
@@ -1623,6 +1646,23 @@ fn original_dst_ipv6() {
16231646
}
16241647
}
16251648

1649+
#[test]
1650+
#[cfg(all(feature = "all", target_os = "windows"))]
1651+
fn original_dst_ipv6() {
1652+
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();
1653+
match socket.original_dst_ipv6() {
1654+
Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"),
1655+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
1656+
}
1657+
1658+
// Not supported on IPv4 socket.
1659+
let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap();
1660+
match socket.original_dst_ipv6() {
1661+
Ok(_) => panic!("original_dst_ipv6 on non-redirected socket should fail"),
1662+
Err(err) => assert_eq!(err.raw_os_error(), Some(WSAEINVAL)),
1663+
}
1664+
}
1665+
16261666
#[test]
16271667
#[cfg(all(feature = "all", any(target_os = "freebsd", target_os = "linux")))]
16281668
fn tcp_congestion() {

0 commit comments

Comments
 (0)