Skip to content

Commit 4fc67a9

Browse files
committed
Added bind_device_by_index_{v4,v6} and device_index_{v4,v6} for linux and android (rust-lang#569)
1 parent 36dec54 commit 4fc67a9

File tree

2 files changed

+89
-5
lines changed

2 files changed

+89
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ targets = [
5151
features = ["all"]
5252

5353
[target."cfg(unix)".dependencies]
54-
libc = "0.2.171"
54+
libc = "0.2.172"
5555

5656
[target.'cfg(windows)'.dependencies.windows-sys]
5757
version = "0.52"

src/sys/unix.rs

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ use std::net::{Ipv4Addr, Ipv6Addr};
2424
target_os = "watchos",
2525
target_os = "illumos",
2626
target_os = "solaris",
27+
target_os = "linux",
28+
target_os = "android",
2729
)
2830
))]
2931
use std::num::NonZeroU32;
@@ -1820,7 +1822,7 @@ impl crate::Socket {
18201822
.map(|_| ())
18211823
}
18221824

1823-
/// Sets the value for `IP_BOUND_IF` option on this socket.
1825+
/// Sets the value for `IP_BOUND_IF` or `SO_BINDTOIFINDEX` option on this socket.
18241826
///
18251827
/// If a socket is bound to an interface, only packets received from that
18261828
/// particular interface are processed by the socket.
@@ -1840,14 +1842,38 @@ impl crate::Socket {
18401842
target_os = "watchos",
18411843
target_os = "illumos",
18421844
target_os = "solaris",
1845+
target_os = "linux",
1846+
target_os = "android",
18431847
)
18441848
))]
18451849
pub fn bind_device_by_index_v4(&self, interface: Option<NonZeroU32>) -> io::Result<()> {
18461850
let index = interface.map_or(0, NonZeroU32::get);
1847-
unsafe { setsockopt(self.as_raw(), IPPROTO_IP, libc::IP_BOUND_IF, index) }
1851+
1852+
#[cfg(any(
1853+
target_os = "ios",
1854+
target_os = "visionos",
1855+
target_os = "macos",
1856+
target_os = "tvos",
1857+
target_os = "watchos",
1858+
target_os = "illumos",
1859+
target_os = "solaris",
1860+
))]
1861+
unsafe {
1862+
setsockopt(self.as_raw(), IPPROTO_IP, libc::IP_BOUND_IF, index)
1863+
}
1864+
1865+
#[cfg(any(target_os = "linux", target_os = "android",))]
1866+
unsafe {
1867+
setsockopt(
1868+
self.as_raw(),
1869+
libc::SOL_SOCKET,
1870+
libc::SO_BINDTOIFINDEX,
1871+
index,
1872+
)
1873+
}
18481874
}
18491875

1850-
/// Sets the value for `IPV6_BOUND_IF` option on this socket.
1876+
/// Sets the value for `IPV6_BOUND_IF` or `SO_BINDTOIFINDEX` option on this socket.
18511877
///
18521878
/// If a socket is bound to an interface, only packets received from that
18531879
/// particular interface are processed by the socket.
@@ -1867,11 +1893,35 @@ impl crate::Socket {
18671893
target_os = "watchos",
18681894
target_os = "illumos",
18691895
target_os = "solaris",
1896+
target_os = "linux",
1897+
target_os = "android",
18701898
)
18711899
))]
18721900
pub fn bind_device_by_index_v6(&self, interface: Option<NonZeroU32>) -> io::Result<()> {
18731901
let index = interface.map_or(0, NonZeroU32::get);
1874-
unsafe { setsockopt(self.as_raw(), IPPROTO_IPV6, libc::IPV6_BOUND_IF, index) }
1902+
1903+
#[cfg(any(
1904+
target_os = "ios",
1905+
target_os = "visionos",
1906+
target_os = "macos",
1907+
target_os = "tvos",
1908+
target_os = "watchos",
1909+
target_os = "illumos",
1910+
target_os = "solaris",
1911+
))]
1912+
unsafe {
1913+
setsockopt(self.as_raw(), IPPROTO_IPV6, libc::IPV6_BOUND_IF, index)
1914+
}
1915+
1916+
#[cfg(any(target_os = "linux", target_os = "android",))]
1917+
unsafe {
1918+
setsockopt(
1919+
self.as_raw(),
1920+
libc::SOL_SOCKET,
1921+
libc::SO_BINDTOIFINDEX,
1922+
index,
1923+
)
1924+
}
18751925
}
18761926

18771927
/// Gets the value for `IP_BOUND_IF` option on this socket, i.e. the index
@@ -1889,11 +1939,28 @@ impl crate::Socket {
18891939
target_os = "watchos",
18901940
target_os = "illumos",
18911941
target_os = "solaris",
1942+
target_os = "linux",
1943+
target_os = "android",
18921944
)
18931945
))]
18941946
pub fn device_index_v4(&self) -> io::Result<Option<NonZeroU32>> {
1947+
#[cfg(any(
1948+
target_os = "ios",
1949+
target_os = "visionos",
1950+
target_os = "macos",
1951+
target_os = "tvos",
1952+
target_os = "watchos",
1953+
target_os = "illumos",
1954+
target_os = "solaris",
1955+
))]
18951956
let index =
18961957
unsafe { getsockopt::<libc::c_uint>(self.as_raw(), IPPROTO_IP, libc::IP_BOUND_IF)? };
1958+
1959+
#[cfg(any(target_os = "linux", target_os = "android",))]
1960+
let index = unsafe {
1961+
getsockopt::<libc::c_uint>(self.as_raw(), libc::SOL_SOCKET, libc::SO_BINDTOIFINDEX)?
1962+
};
1963+
18971964
Ok(NonZeroU32::new(index))
18981965
}
18991966

@@ -1912,12 +1979,29 @@ impl crate::Socket {
19121979
target_os = "watchos",
19131980
target_os = "illumos",
19141981
target_os = "solaris",
1982+
target_os = "linux",
1983+
target_os = "android",
19151984
)
19161985
))]
19171986
pub fn device_index_v6(&self) -> io::Result<Option<NonZeroU32>> {
1987+
#[cfg(any(
1988+
target_os = "ios",
1989+
target_os = "visionos",
1990+
target_os = "macos",
1991+
target_os = "tvos",
1992+
target_os = "watchos",
1993+
target_os = "illumos",
1994+
target_os = "solaris",
1995+
))]
19181996
let index = unsafe {
19191997
getsockopt::<libc::c_uint>(self.as_raw(), IPPROTO_IPV6, libc::IPV6_BOUND_IF)?
19201998
};
1999+
2000+
#[cfg(any(target_os = "linux", target_os = "android",))]
2001+
let index = unsafe {
2002+
getsockopt::<libc::c_uint>(self.as_raw(), libc::SOL_SOCKET, libc::SO_BINDTOIFINDEX)?
2003+
};
2004+
19212005
Ok(NonZeroU32::new(index))
19222006
}
19232007

0 commit comments

Comments
 (0)