Skip to content

enable HttpConnector::interface on macOS and Solarish systems #176

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

Merged
merged 5 commits into from
Mar 31, 2025

Conversation

hawkw
Copy link
Contributor

@hawkw hawkw commented Mar 26, 2025

The client::legacy::connect::HttpConnector type has a method
set_interface that configures the connector to bind TCP connections
only on the provided interface name. Presently, this is enabled only on
Linux, Android, and Fuchsia, as it uses the Linux-only socket option
SO_BINDTODEVICE.

On macOS (and other Apple operating systems such as iOS, watchOS,
etc), and Solaris and Solaris-like systems like illumos, the Solaris
socket option [IP_BOUND_IF] provides similar functionality to
SO_BINDTODEVICE, as it also restricts connections to a particular
network itnerface. Unlike the Linux socket option, IP_BOUND_IF takes
the numeric index of the interface, so in order to accept a string
interface name similarly to the Linux implementation, we must use
if_nametoindex(3socket) from libc to determine the index
corresponding to the interface name. This is done every time we open a
connection, to avoid TOCTOU issues in case interface indices or names
change.

Note that this PR currently requires an unreleased change in socket2
(rust-lang/socket2#566) to enable IP_BOUND_IF on Solarish operating
systems. We will need to remove the Cargo patch for socket2 once that
change is released, prior to merging this PR.

This points the `socket2` dependency at
rust-lang/socket2@d95e914 temporarily
so that we can use these APIs on Solarish operating systems.
@hawkw hawkw requested a review from seanmonstar March 26, 2025 18:22
@seanmonstar
Copy link
Member

LGTM, thanks! Will just wait till that socket2 release :)

@hawkw
Copy link
Contributor Author

hawkw commented Mar 26, 2025

LGTM, thanks! Will just wait till that socket2 release :)

Yup, no rush --- just wanted to get this ready to go when that's out. :)

@seanmonstar seanmonstar merged commit 5831ace into hyperium:master Mar 31, 2025
16 checks passed
@hawkw
Copy link
Contributor Author

hawkw commented Mar 31, 2025

Haha, I was just about to leave a comment mentioning that the socket2 release had been published --- impressive reaction time, @seanmonstar! :)

@hawkw hawkw deleted the eliza/ip-bound-if branch March 31, 2025 16:59
hawkw added a commit to hawkw/reqwest that referenced this pull request Mar 31, 2025
The `ClientBuilder` type has an `interface` method that sets the name of
a specific network interface to bind TCP connections on. This method is
currently only enabled on Linux, Android, and Fuchsia, as it uses the
`SO_BINDTODEVICE` socket option, which only exists on those systems.
Upstream changes to `socket2` (rust-lang/socket2#561) and `hyper-util`
(hyperium/hyper-util#176) have added support for similar functionality
on macOS (and other Apple operating systems, such as iOS, watchOS, tvOS,
and visionOS), and Solaris and Solaris-like systems like illumos, using
the `IP_BOUND_IF`/`IPV6_BOUND_IF` socket options on those systems.

This branch enables the `ClientBuilder::interface` API on these
additional target OSes.

Note that this presently requires a Cargo patch to take a Git dependency
on hyperium/hyper-util@5831ace. Once
that commit is published, the patch can be removed. This PR should not be
merged until then.

Fixes seanmonstar#2571
seanmonstar pushed a commit to seanmonstar/reqwest that referenced this pull request Apr 9, 2025
The `ClientBuilder` type has an `interface` method that sets the name of
a specific network interface to bind TCP connections on. This method is
currently only enabled on Linux, Android, and Fuchsia, as it uses the
`SO_BINDTODEVICE` socket option, which only exists on those systems.
Upstream changes to `socket2` (rust-lang/socket2#561) and `hyper-util`
(hyperium/hyper-util#176) have added support for similar functionality
on macOS (and other Apple operating systems, such as iOS, watchOS, tvOS,
and visionOS), and Solaris and Solaris-like systems like illumos, using
the `IP_BOUND_IF`/`IPV6_BOUND_IF` socket options on those systems.

This branch enables the `ClientBuilder::interface` API on these
additional target OSes.

Fixes #2571
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

Successfully merging this pull request may close these issues.

None yet

2 participants