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

Allow disabling binding to IPv4 or IPv6 entirely in iroh_net::Endpoint #2866

Open
CGamesPlay opened this issue Oct 30, 2024 · 7 comments
Open

Comments

@CGamesPlay
Copy link

Iroh does not respect my bind address, as set in bind_addr_v4 and bind_addr_v6.

To reproduce, apply the following patch and running cargo run --example listen in the iroh-net crate.

diff --git i/iroh-net/examples/listen.rs w/iroh-net/examples/listen.rs
index 1a3828c6e..208ee0938 100644
--- i/iroh-net/examples/listen.rs
+++ w/iroh-net/examples/listen.rs
@@ -31,6 +31,7 @@ async fn main() -> anyhow::Result<()> {
         // Use `RelayMode::Disable` to disable holepunching and relaying over HTTPS
         // If you want to experiment with relaying using your own relay server, you must pass in the same custom relay url to both the `listen` code AND the `connect` code
         .relay_mode(RelayMode::Default)
+        .bind_addr_v4("127.0.0.1:0".parse().unwrap())
         // you can choose a port to bind to, but passing in `0` will bind the socket to a random available port
         .bind()
         .await?;

Running this example produces the following output:

listen example!

secret key: xusfx2ih3ebarzrzpisvyykhyjlcjtswq2o6kgdwxfduqqb5ux7a
node id: hpo5y5nak7fgr3vq7gqazesn4nsuupubvdeotiswwgvfexz6qdrq
node listening addresses:
	127.0.0.1:52784
	[c485:7363:7251:89ec:8e9:ecfb:c298:abaf]:52785
	[c485:7363:7251:89ec:7c1f:66ff:2aad:dde]:52785
node relay server url: https://aps1-1.relay.iroh.network./

The IPv4 address is correct, but Iroh has adding my public interface IPv6 addresses (and I have also confirmed that it will use them when connecting).

The same problem happens with bind_addr_v6, where it uses my public IPv4 addresses, and completes STUN:

diff --git i/iroh-net/examples/listen.rs w/iroh-net/examples/listen.rs
index 1a3828c6e..9ad034579 100644
--- i/iroh-net/examples/listen.rs
+++ w/iroh-net/examples/listen.rs
@@ -31,6 +31,7 @@ async fn main() -> anyhow::Result<()> {
         // Use `RelayMode::Disable` to disable holepunching and relaying over HTTPS
         // If you want to experiment with relaying using your own relay server, you must pass in the same custom relay url to both the `listen` code AND the `connect` code
         .relay_mode(RelayMode::Default)
+        .bind_addr_v6("[::1]:0".parse().unwrap())
         // you can choose a port to bind to, but passing in `0` will bind the socket to a random available port
         .bind()
         .await?;
listen example!

secret key: 7yocbsxce3uzq3tv366t2g3pho3duhjbxgax52adnv6izfqms5nq
node id: inqwwfwdlhss4qyuweck5mbklhri3nhgkry4a7unnjftvuu5pgca
node listening addresses:
	142.251.222.238:30314
	192.168.64.1:52913
	192.168.100.5:52913
	192.168.191.105:52913
	[::1]:60052
node relay server url: https://aps1-1.relay.iroh.network./
@CGamesPlay
Copy link
Author

CGamesPlay commented Oct 30, 2024

It occurs to me that there just isn't a way to disable v4/v6 networking, and so I can call both bind_addr_v4 and bind_addr_v6 to restrict both to loopback and get the desired behavior.

In that case, consider this a feature request to pass None to either of these methods to disable that IP stack (or perhaps a set of disable_v4 and disable_v6 methods). Note that using a loopback address is not as good as disabling that stack, since it still requires that I allocate a port, and it makes network tracing harder since I have to monitor more interfaces. It may even be worth changing the interface to bind_addrs(self, addrs: impl std::net::ToSocketAddrs), which should specify all allowed addresses of all protocols.

@CGamesPlay
Copy link
Author

In testing this, I found that using both bind_addr_v4 and bind_addr_v6 does stop the addresses from appearing in the NodeAddr, but the port mapper service will still access the public interface. This causes macOS to open a dialog box alerting the user that the program is accessing the network. This is quite annoying, given that I am using the loopback addresses in my test cases, and now I get a stream of dialog boxes every time I run tests.

[2024-10-30T02:02:48Z DEBUG iroh_net::magicsock::udp_conn] binding addr=127.0.0.1:0
[2024-10-30T02:02:48Z DEBUG iroh_net::magicsock::udp_conn] candidate ports ports=[0]
[2024-10-30T02:02:48Z DEBUG iroh_net::magicsock::udp_conn] successfully bound addr=127.0.0.1:0 local_addr=127.0.0.1:51453
[2024-10-30T02:02:48Z DEBUG iroh_net::magicsock::udp_conn] binding addr=[::1]:0
[2024-10-30T02:02:48Z DEBUG iroh_net::magicsock::udp_conn] candidate ports ports=[0]
[2024-10-30T02:02:48Z DEBUG iroh_net::magicsock::udp_conn] successfully bound addr=[::1]:0 local_addr=[::1]:56018
...
[2024-10-30T02:02:48Z TRACE tracing::span::active] -> portmapper.service;
[2024-10-30T02:02:48Z DEBUG iroh_net::portmapper] portmap starting
[2024-10-30T02:02:48Z TRACE iroh_net::portmapper] tick: msg Some(UpdateLocalPort { local_port: Some(51453) })
[2024-10-30T02:02:48Z DEBUG iroh_net::portmapper] getting a port mapping for 192.168.100.5:51453 -> None
[2024-10-30T02:02:48Z INFO  tracing::span] upnp;
[2024-10-30T02:02:48Z TRACE tracing::span::active] <- portmapper.service;

@flub flub changed the title iroh_net::Endpoint::bind_addr_v4/v6 don't respect bind address Allow disabling binging to IPv4 or IPv6 entirely in iroh_net::Endpoint Oct 30, 2024
@flub
Copy link
Contributor

flub commented Oct 30, 2024

Great narrowing this down to needing a way to disable an interface, I've changed the title.

Would you mind moving the portmapper problem to a new issue? I totally agree that it also shouldn't be doing this.

@flub
Copy link
Contributor

flub commented Oct 30, 2024

So far we need to bind a single IPv4 socket and optionally a single IPv6 socket. This puts a bit of a limit on how flexible we can be here. I agree that long term perhaps something that does impl ToSocketAddrs would be nice, but that is a larger refactor in the guts of iroh-net which is not going to happen anytime soon. I would perfer to only look at this once we have migrated the protocol to QUIC multipath. It would have to be able to deal with an arbitrary number of sockets bound with no guarantee on which network families they are bound.

Finally that may or may not interact with #2228.

However simply being able to disable IPv6 is probably a reasonable demand in the short term.

I'm guessing a Builder::disable_ipv6 method could be sufficient for this.

@dignifiedquire
Copy link
Contributor

  • if you don't set a ipv6 addr on the iroh-net builder ipv6 binding will be disabled already
  • disabling ipv4 is not possible currently, due to how iroh works under the hood

@CGamesPlay
Copy link
Author

if you don't set a ipv6 addr on the iroh-net builder ipv6 binding will be disabled already

This is not the result I received when I applied the patch given in the initial issue description.

@flub
Copy link
Contributor

flub commented Oct 31, 2024

if you don't set a ipv6 addr on the iroh-net builder ipv6 binding will be disabled already

This is not the result I received when I applied the patch given in the initial issue description.

Yeah, you can't currently disable IPv6 binding. It is something we could reasonably add right now, though not trivially.

@ramfox ramfox moved this to 📋 Backlog in iroh Nov 27, 2024
@flub flub changed the title Allow disabling binging to IPv4 or IPv6 entirely in iroh_net::Endpoint Allow disabling binding to IPv4 or IPv6 entirely in iroh_net::Endpoint Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

3 participants