Skip to content

feat(iroh)!: allow for limiting incoming connections on the router #3157

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 6 commits into from
Mar 14, 2025

Conversation

dignifiedquire
Copy link
Contributor

@dignifiedquire dignifiedquire commented Jan 31, 2025

Description

Changes the ProtocolHandler trait to allow for intercepting connecting and connection states explicitly

Breaking Changes

  • changed: iroh::protocol::ProtocolHandler::accept now takes Connection instead of Connecting

Notes & open questions

The new limiter could also just be part of the test code/an example, instead of giving users an API, unclear to me

Change checklist

  • Self-review.
  • Documentation updates following the style guide, if relevant.
  • Tests if relevant.
  • All breaking changes documented.

Copy link

github-actions bot commented Jan 31, 2025

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

Last updated: 2025-03-14T08:27:30Z

Copy link
Contributor

@rklaehn rklaehn left a comment

Choose a reason for hiding this comment

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

I'm on the way to the airport, so just a bunch of drive by comments.

@dignifiedquire dignifiedquire changed the title feat(iroh): allow for limiting incoming connections on the router feat(iroh)!: allow for limiting incoming connections on the router Feb 10, 2025
Copy link

github-actions bot commented Feb 10, 2025

Netsim report & logs for this PR have been generated and is available at: LOGS
This report will remain available for 3 days.

Last updated for commit: 4a4a54a

@dignifiedquire dignifiedquire marked this pull request as ready for review February 10, 2025 17:35
@dignifiedquire
Copy link
Contributor Author

@matheus23 can check if this change is good enough to still be able to use 0-rtt from ProtocolHandler impl please?

@matheus23
Copy link
Member

Yeah - this change makes using 0-RTT/0.5-RTT on the accepting side possible at all, since otherwise you wouldn't be able to call Connecting::into_0rtt.

And all you need to do on the accepting side is call Connecting::into_0rtt, then if you get Ok, you take the connection, otherwise if you get an Err, you await.
That's it.
(You should also make sure you know the security implications of what you're doing - but from an "enabling 0-RTT" perspective that is indeed it.)

Copy link
Contributor

@flub flub left a comment

Choose a reason for hiding this comment

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

I can also imagine a need for on_incoming or something like that in the future to be able to reject etc even further. But the nice thing about this design is that you can add this later without breaking backwards compatibility.

I have a minor bikeshedding concern that AccessLimit sounds too much like rate-limiting. But I don't know if there is a commonly used term that's better.

@@ -109,10 +112,18 @@ pub struct RouterBuilder {
/// The protocol handler must then be registered on the node for an ALPN protocol with
/// [`crate::protocol::RouterBuilder::accept`].
pub trait ProtocolHandler: Send + Sync + std::fmt::Debug + 'static {
/// Optional interception point to handle the `Connecting` state.
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 always a fan of being extremely verbose on the docs. I would add a paragraph suggesting when you might to use this:

This enables accepting 0-RTT data from clients, among other things.

pub struct AccessLimit<P: ProtocolHandler + Clone> {
proto: P,
#[debug("limiter")]
limiter: Arc<dyn Fn(NodeId) -> bool + Send + Sync + 'static>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this was discussed before: will we get folks upset that they can't do async stuff here? I think this itself runs in an async context.

Copy link
Contributor

Choose a reason for hiding this comment

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

Of course we/they can just make an AsyncAcessLimit which is probably nicer than forcing everyone to use async.

Choose a reason for hiding this comment

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

@flub @dignifiedquire

How would you feel if I created a PR for AsyncAccessLimit?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, why not. Don't think there'd be an objection to this.

let remote = conn.remote_node_id()?;
let is_allowed = (this.limiter)(remote);
if !is_allowed {
conn.close(0u32.into(), b"not allowed");
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be documented. Probably on the struct itself. Something like:

Any refused connection will be closed with an error code of `0` and reason `not allowed`.

(I can also imagine folks wanting this configurable. But I think that's possible in a backwards-compatible way so should be fine to add later. I can also imagine a world where the function returns those values.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course we/they can just make an AsyncAcessLimit which is probably nicer than forcing everyone to use async.

yeah, this is more of an example for me

@dignifiedquire
Copy link
Contributor Author

I have a minor bikeshedding concern that AccessLimit sounds too much like rate-limiting. But I don't know if there is a commonly used term that's better.

would love to hear better names..

@dignifiedquire dignifiedquire added this pull request to the merge queue Mar 14, 2025
Merged via the queue into main with commit 3e16848 Mar 14, 2025
26 checks passed
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in iroh Mar 14, 2025
@dignifiedquire dignifiedquire deleted the feat-limit-conns branch March 14, 2025 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants