@@ -20,14 +20,16 @@ use std::time::{Duration, Instant};
20
20
use std:: { process, ptr, slice} ;
21
21
22
22
use windows_sys:: Win32 :: Foundation :: { SetHandleInformation , HANDLE , HANDLE_FLAG_INHERIT } ;
23
- #[ cfg( feature = "all" ) ]
24
- use windows_sys:: Win32 :: Networking :: WinSock :: SO_PROTOCOL_INFOW ;
25
23
use windows_sys:: Win32 :: Networking :: WinSock :: {
26
24
self , tcp_keepalive, FIONBIO , IN6_ADDR , IN6_ADDR_0 , INVALID_SOCKET , IN_ADDR , IN_ADDR_0 ,
27
25
POLLERR , POLLHUP , POLLRDNORM , POLLWRNORM , SD_BOTH , SD_RECEIVE , SD_SEND , SIO_KEEPALIVE_VALS ,
28
26
SOCKET_ERROR , WSABUF , WSAEMSGSIZE , WSAESHUTDOWN , WSAPOLLFD , WSAPROTOCOL_INFOW ,
29
27
WSA_FLAG_NO_HANDLE_INHERIT , WSA_FLAG_OVERLAPPED ,
30
28
} ;
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
+ } ;
31
33
use windows_sys:: Win32 :: System :: Threading :: INFINITE ;
32
34
33
35
use crate :: { MsgHdr , RecvFlags , SockAddr , TcpKeepalive , Type } ;
@@ -927,6 +929,64 @@ impl crate::Socket {
927
929
}
928
930
}
929
931
932
+ /// Get the value for the `SO_ORIGINAL_DST` option on this socket.
933
+ /// Only valid for sockets in accepting mode.
934
+ ///
935
+ /// Note: if using this function in a proxy context, you must query the
936
+ /// redirect records for this socket and set them on the outbound socket
937
+ /// created by your proxy in order for any OS level firewall rules to be
938
+ /// applied. Read more in the Windows bind and connect redirection
939
+ /// [documentation](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/using-bind-or-connect-redirection).
940
+ #[ cfg( feature = "all" ) ]
941
+ #[ cfg_attr( docsrs, doc( cfg( all( windows, feature = "all" ) ) ) ) ]
942
+ pub fn original_dst ( & self ) -> io:: Result < SockAddr > {
943
+ unsafe {
944
+ SockAddr :: try_init ( |storage, len| {
945
+ syscall ! (
946
+ getsockopt(
947
+ self . as_raw( ) ,
948
+ SOL_IP as i32 ,
949
+ SO_ORIGINAL_DST as i32 ,
950
+ storage. cast( ) ,
951
+ len,
952
+ ) ,
953
+ PartialEq :: eq,
954
+ SOCKET_ERROR
955
+ )
956
+ } )
957
+ }
958
+ . map ( |( _, addr) | addr)
959
+ }
960
+
961
+ /// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket.
962
+ /// Only valid for sockets in accepting mode.
963
+ ///
964
+ /// Note: if using this function in a proxy context, you must query the
965
+ /// redirect records for this socket and set them on the outbound socket
966
+ /// created by your proxy in order for any OS level firewall rules to be
967
+ /// applied. Read more in the Windows bind and connect redirection
968
+ /// [documentation](https://learn.microsoft.com/en-us/windows-hardware/drivers/network/using-bind-or-connect-redirection).
969
+ #[ cfg( feature = "all" ) ]
970
+ #[ cfg_attr( docsrs, doc( cfg( all( windows, feature = "all" ) ) ) ) ]
971
+ pub fn original_dst_ipv6 ( & self ) -> io:: Result < SockAddr > {
972
+ unsafe {
973
+ SockAddr :: try_init ( |storage, len| {
974
+ syscall ! (
975
+ getsockopt(
976
+ self . as_raw( ) ,
977
+ SOL_IP as i32 ,
978
+ IP6T_SO_ORIGINAL_DST as i32 ,
979
+ storage. cast( ) ,
980
+ len,
981
+ ) ,
982
+ PartialEq :: eq,
983
+ SOCKET_ERROR
984
+ )
985
+ } )
986
+ }
987
+ . map ( |( _, addr) | addr)
988
+ }
989
+
930
990
/// Returns the [`Protocol`] of this socket by checking the `SO_PROTOCOL_INFOW`
931
991
/// option on this socket.
932
992
///
0 commit comments