From 2099d0bd87fe53aa98a7c02334852d279baeb779 Mon Sep 17 00:00:00 2001 From: Campbell He Date: Wed, 10 Aug 2022 21:30:08 +0800 Subject: [PATCH] net: add `device` and `bind_device` methods to TCP/UDP sockets (#4882) --- tokio/src/net/tcp/socket.rs | 28 ++++++++++++++++++++++++++++ tokio/src/net/udp.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/tokio/src/net/tcp/socket.rs b/tokio/src/net/tcp/socket.rs index a6605dc10ca..b00df95f4a6 100644 --- a/tokio/src/net/tcp/socket.rs +++ b/tokio/src/net/tcp/socket.rs @@ -453,6 +453,34 @@ impl TcpSocket { self.inner.set_tos(tos) } + /// Gets the value for the `SO_BINDTODEVICE` option on this socket + /// + /// This value gets the socket binded device's interface name. + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))] + #[cfg_attr( + docsrs, + doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))) + )] + pub fn device(&self) -> io::Result>> { + self.inner.device() + } + + /// Sets the value for the `SO_BINDTODEVICE` option on this socket + /// + /// If a socket is bound to an interface, only packets received from that + /// particular interface are processed by the socket. Note that this only + /// works for some socket types, particularly `AF_INET` sockets. + /// + /// If `interface` is `None` or an empty string it removes the binding. + #[cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))) + )] + pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> { + self.inner.bind_device(interface) + } + /// Gets the local address of this socket. /// /// Will fail on windows if called before `bind`. diff --git a/tokio/src/net/udp.rs b/tokio/src/net/udp.rs index 917e6769ed2..d2d4d4273a8 100644 --- a/tokio/src/net/udp.rs +++ b/tokio/src/net/udp.rs @@ -1569,6 +1569,34 @@ impl UdpSocket { self.as_socket().set_tos(tos) } + /// Gets the value for the `SO_BINDTODEVICE` option on this socket + /// + /// This value gets the socket binded device's interface name. + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))] + #[cfg_attr( + docsrs, + doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))) + )] + pub fn device(&self) -> io::Result>> { + self.as_socket().device() + } + + /// Sets the value for the `SO_BINDTODEVICE` option on this socket + /// + /// If a socket is bound to an interface, only packets received from that + /// particular interface are processed by the socket. Note that this only + /// works for some socket types, particularly `AF_INET` sockets. + /// + /// If `interface` is `None` or an empty string it removes the binding. + #[cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))] + #[cfg_attr( + docsrs, + doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))) + )] + pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> { + self.as_socket().bind_device(interface) + } + /// Executes an operation of the `IP_ADD_MEMBERSHIP` type. /// /// This function specifies a new multicast group for this socket to join.