Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide bind_device_by_index_v{4|6} methods for linux. #500

Open
Frostie314159 opened this issue Mar 14, 2024 · 8 comments
Open

Provide bind_device_by_index_v{4|6} methods for linux. #500

Frostie314159 opened this issue Mar 14, 2024 · 8 comments

Comments

@Frostie314159
Copy link

Hi, it would be nice if we had the functionality for binding a socket to an interface under linux, since that functionality is available.

@Thomasdezeeuw
Copy link
Collaborator

A pr to add this would be welcome.

@Frostie314159
Copy link
Author

Sure, I'll get to this next week.

@carlocorradini
Copy link

Any update?
This is super useful ☺️🥳

@Thomasdezeeuw
Copy link
Collaborator

Any update? This is super useful ☺️🥳

No pr was made, but they're still welcome.

@Frostie314159
Copy link
Author

I'm in the progress of writing one, however I'm not entirely sure how to go about it.

@Thomasdezeeuw
Copy link
Collaborator

I just look at the code and we have Socket::bind_device_by_index_v4:

socket2/src/sys/unix.rs

Lines 2006 to 2045 in c93cdcc

pub fn bind_device_by_index_v4(&self, interface: Option<NonZeroU32>) -> io::Result<()> {
let index = interface.map_or(0, NonZeroU32::get);
unsafe { setsockopt(self.as_raw(), IPPROTO_IP, libc::IP_BOUND_IF, index) }
}
/// Sets the value for `IPV6_BOUND_IF` option on this socket.
///
/// If a socket is bound to an interface, only packets received from that
/// particular interface are processed by the socket.
///
/// If `interface` is `None`, the binding is removed. If the `interface`
/// index is not valid, an error is returned.
///
/// One can use [`libc::if_nametoindex`] to convert an interface alias to an
/// index.
#[cfg(all(
feature = "all",
any(
target_os = "ios",
target_os = "macos",
target_os = "tvos",
target_os = "watchos",
)
))]
#[cfg_attr(
docsrs,
doc(cfg(all(
feature = "all",
any(
target_os = "ios",
target_os = "macos",
target_os = "tvos",
target_os = "watchos",
)
)))
)]
pub fn bind_device_by_index_v6(&self, interface: Option<NonZeroU32>) -> io::Result<()> {
let index = interface.map_or(0, NonZeroU32::get);
unsafe { setsockopt(self.as_raw(), IPPROTO_IPV6, libc::IPV6_BOUND_IF, index) }
}
. Or is this about another setting then IP_BOUND_IF?

@Frostie314159
Copy link
Author

That setting is Apple specific, this is about the Linux socket option.

@sciguy16
Copy link

I had a similar question and was about to add it myself when I found that SO_BINDTODEVICE option has already been implemented! It was added in 2020 in 6780944, but isn't shown on docs.rs by default due to their platform filtering options.

The default platform is unhelpfully the alphabetically first aarch64-apple-ios, but if we swap it to linux then the full API list is displayed: https://docs.rs/socket2/latest/x86_64-unknown-linux-gnu/socket2/struct.Socket.html#method.bind_device

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants