@@ -1789,6 +1789,68 @@ impl crate::Socket {
1789
1789
}
1790
1790
}
1791
1791
1792
+ /// Get the value for the `SO_ORIGINAL_DST` option on this socket.
1793
+ ///
1794
+ /// This value contains the original destination IPv4 address of the connection
1795
+ /// redirected using `iptables` `REDIRECT` or `TPROXY`.
1796
+ #[ cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) ]
1797
+ #[ cfg_attr(
1798
+ docsrs,
1799
+ doc( cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) )
1800
+ ) ]
1801
+ pub fn original_dst ( & self ) -> io:: Result < Option < SockAddr > > {
1802
+ // Safety: `getsockopt` initialises the `SockAddr` for us.
1803
+ unsafe {
1804
+ SockAddr :: try_init ( |storage, len| {
1805
+ syscall ! ( getsockopt(
1806
+ self . as_raw( ) ,
1807
+ libc:: SOL_IP ,
1808
+ libc:: SO_ORIGINAL_DST ,
1809
+ storage. cast( ) ,
1810
+ len
1811
+ ) )
1812
+ } )
1813
+ }
1814
+ . map_or_else (
1815
+ |e| match e. raw_os_error ( ) {
1816
+ Some ( libc:: ENOENT ) => Ok ( None ) ,
1817
+ _ => Err ( e) ,
1818
+ } ,
1819
+ |( _, addr) | Ok ( Some ( addr) ) ,
1820
+ )
1821
+ }
1822
+
1823
+ /// Get the value for the `IP6T_SO_ORIGINAL_DST` option on this socket.
1824
+ ///
1825
+ /// This value contains the original destination IPv6 address of the connection
1826
+ /// redirected using `ip6tables` `REDIRECT` or `TPROXY`.
1827
+ #[ cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) ]
1828
+ #[ cfg_attr(
1829
+ docsrs,
1830
+ doc( cfg( all( feature = "all" , any( target_os = "android" , target_os = "linux" ) ) ) )
1831
+ ) ]
1832
+ pub fn original_dst_ipv6 ( & self ) -> io:: Result < Option < SockAddr > > {
1833
+ // Safety: `getsockopt` initialises the `SockAddr` for us.
1834
+ unsafe {
1835
+ SockAddr :: try_init ( |storage, len| {
1836
+ syscall ! ( getsockopt(
1837
+ self . as_raw( ) ,
1838
+ libc:: SOL_IPV6 ,
1839
+ libc:: IP6T_SO_ORIGINAL_DST ,
1840
+ storage. cast( ) ,
1841
+ len
1842
+ ) )
1843
+ } )
1844
+ }
1845
+ . map_or_else (
1846
+ |e| match e. raw_os_error ( ) {
1847
+ Some ( libc:: ENOENT ) => Ok ( None ) ,
1848
+ _ => Err ( e) ,
1849
+ } ,
1850
+ |( _, addr) | Ok ( Some ( addr) ) ,
1851
+ )
1852
+ }
1853
+
1792
1854
/// Copies data between a `file` and this socket using the `sendfile(2)`
1793
1855
/// system call. Because this copying is done within the kernel,
1794
1856
/// `sendfile()` is more efficient than the combination of `read(2)` and
0 commit comments