Skip to content

feat(iroh)!: introduce transport abstraction #3279

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

Open
wants to merge 101 commits into
base: main
Choose a base branch
from

Conversation

dignifiedquire
Copy link
Contributor

@dignifiedquire dignifiedquire commented Apr 28, 2025

A first step towards the work of #3276

Breaking changes

  • iroh::watcher is now its own crate n0-watcher
  • iroh::endpoint::Endpoint::node_addr now returns impl Watcher<Value = Option<NodeAddr>>
  • iroh::endpoint::Endpoint::home_relay now returns impl Watcher<Value = Vec<RelayUrl>>
  • iroh::endpoint::Endpoint::bound_sockets now returns Vec<SocketAddr>

Depends on

@n0bot n0bot bot added this to iroh Apr 28, 2025
@github-project-automation github-project-automation bot moved this to 🏗 In progress in iroh Apr 28, 2025
@Frando
Copy link
Member

Frando commented May 5, 2025

(Note: my "merged main into refactor-transports" commit was a pushed-the-button-by-accident, didn't actually want to do that at that point in time)

Copy link

github-actions bot commented May 8, 2025

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/iroh/pr/3279/docs/iroh/

Last updated: 2025-05-28T12:31:31Z

@dignifiedquire dignifiedquire disabled auto-merge May 21, 2025 15:13
@dignifiedquire dignifiedquire mentioned this pull request May 23, 2025
2 tasks
iroh-quinn = { git = "https://github.com/n0-computer/quinn", branch = "matheus23/mut-self" }
iroh-quinn-udp = { git = "https://github.com/n0-computer/quinn", branch = "matheus23/mut-self" }
iroh-quinn-proto = { git = "https://github.com/n0-computer/quinn", branch = "matheus23/mut-self" }
netwatch = { git = "https://github.com/n0-computer/net-tools", branch = "feat-new-udp-api"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the plan to merge this with git refs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I guess the netwatch branch is also a dependency I should have reviewed before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I guess the netwatch branch is also a dependency I should have reviewed before?

yes..

@@ -5489,7 +5488,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.59.0",
"windows-sys 0.48.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no idea, this changes back in my other PR, cargo seems to resolve this differently in some cases 🤷

.expect("disconnected")
.into_iter()
.filter_map(|addr| SocketAddr::try_from(addr).ok())
.collect();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure this could be written without allocating to a Vec with a bit more gymnastics... Anyway, I don't mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

#[instrument(skip_all)]
fn try_send(&self, transmit: &quinn_udp::Transmit) -> io::Result<()> {
fn prepare_send(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this have a doc comment? It seems it is supposed to find the transport addresses on which to send?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +402 to +403
for sender in &self.ip {
if sender.is_valid_send_addr(addr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is like super-nitpicky. But I noticed every time when I review that that I have to double-check these lines to figure out what is going on. In a way something like for sender in self.ip.iter().filter(|ip| ip.is_valid_send_addr(addr)) would be clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually find that much harder to read, because the for loop gets split over multiple lines


match destination {
#[cfg(wasm_browser)]
Addr::Ip(..) => return Err(io::Error::other("IP is unsupported in browser")),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if ErrorKind::AddrNotAvailable would be suitable for these errors. Though making it an Other probably makes it clearer where this is coming from, so perhaps this is better anyway.

metrics: Arc<MagicsockMetrics>,
) -> Self {
// Currently gets updated on manual rebind
// TODO: update when UdpSocket under the hood rebinds automatically
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how important is this todo? probably fairly important for ios?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's important todo eventually, but the world doesn't end if it doesn't make it in this PR

pub(crate) fn new(config: RelayActorConfig) -> Self {
let (relay_datagram_send_tx, relay_datagram_send_rx) = mpsc::channel(256);

let (relay_datagram_recv_tx, relay_datagram_recv_rx) = mpsc::channel(512);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you're probably copying these values... but how did we end up with the recv queue being twice as long as the send queue? Anyway, something to clean up some other time.

}
};

buf_out[..dm.buf.len()].copy_from_slice(&dm.buf);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long, long in the future I can now see us polling the TCP socket from the relay server directly during this poll, allowing us to avoid this copy. Especially once we don't have any non-quic messages left since then only very few times we'll need to send a non-QUIC message over the relay protocol that should not be passed up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one can dream

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

Successfully merging this pull request may close these issues.

4 participants