-
Notifications
You must be signed in to change notification settings - Fork 1k
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
feat(connection-limit): set bypass rules for connections #5720
base: master
Are you sure you want to change the base?
Conversation
I also found that you can get a mutable reference to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think adding bypass rules for a PeerId
makes sense. I am not sure about having them for a MultiAddr
as well.
When would one know the address of a trusted peer, but not it's PeerId
?
I don't know, but trusting an address also kind of makes sense? Though this behaviour is not primarily used for managing trusts between peers. |
Also you can use the rule to allow a range of peers from an address, for example behind a load balancer and such, or a domain(I guess it only works for dialing). Allowing a range of addresses will grant even greater flexibility but it will be a bit difficult to implement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also allow all connections from specific listeners.
Not sure I understand what you mean. Won't using the listeners PeerId
do exactly that?
I still have a slight preference to only allow bypassing of connection limits based on PeerId
s. In allow-block-list
we also only operated on PeerId
s and not on multiaddresses.
But I don't feel strongly about it, so if from a user perspective it's useful and needed I am okay with also bypassing based on addresses.
Sorry for the late response. Looking at the comments and review, I think what we can do for now is exclude the address portion of the code and allow it based on |
fix: bypassed pending connections still take up slots
misc/connection-limits/src/lib.rs
Outdated
type BypassFn = fn( | ||
remote_peer: Option<&PeerId>, | ||
remote_addresses: &[Multiaddr], | ||
local_addresses: Option<&Multiaddr>, | ||
) -> bool; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is function pointer type, an implementation won't be able to capture an environment. So it could only hardcode here a list of allowed peer-ids or multiaddresses, right?
I am not sure this brings any advantage over the former bypass_multiaddr
and is more complex. Do you have an example use-case for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No example for this unfortunately. It only grants more flexibility so that users can mix and match rules. Of course it can be a Box<dyn Fn>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @elenaf9 that allowing a closure here would open up many nice use-cases.
We could also instead do a trait BypassRule
instead and add some default implementations, for example:
HashSet<PeerId>
to allow the whitelisting you implemented,FnMut(Option<&PeerId>, &[Multiaddr], Option<&Multiaddr>)
for convenience,Vec<B>
to compose multiple rules,struct NoBypass;
as default to allow no bypasses.- ...
and then make Behaviour
generic over BypassRule
. But I am not sure if that would add to much complexity for too little added value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting idea!
But I am a bit torn about it. As you also noted, I am unsure if we really need the complexity.
I would expect that you usually know the PeerId
of trusted peers. Thus I think most use-cases can be simply satisfied with the one bypass_peer
function, and the rest is for now only theoretical.
As mentioned before (and I think @dariusc93) agrees, I would prefer if we for now just add bypass rules for PeerId
s, and extend the API and it's complexity only when the need arises.
misc/connection-limits/src/lib.rs
Outdated
@@ -92,6 +97,11 @@ impl Behaviour { | |||
pub fn limits_mut(&mut self) -> &mut ConnectionLimits { | |||
&mut self.limits | |||
} | |||
|
|||
/// Returns a mutable reference to [`BypassRules`]. | |||
pub fn bypass_rules_mut(&mut self) -> &mut BypassRules { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the advantage of having an external structure (BypassRules
) instead of having these methods in the main Behaviour
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a couple of comments. Can we also add a test for this feature?
misc/connection-limits/CHANGELOG.md
Outdated
@@ -1,3 +1,9 @@ | |||
## 0.5.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since there is a breaking change to the API, we should bump the minor version
## 0.5.1 | |
## 0.6.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it a breaking change? We just add new methods no? https://doc.rust-lang.org/cargo/reference/semver.html#item-new
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we added bypass_rules
to Behaviour::new
, which would then require a minor bump to satisfy semver. See #5720 (comment) :)
misc/connection-limits/src/lib.rs
Outdated
@@ -76,9 +80,10 @@ pub struct Behaviour { | |||
} | |||
|
|||
impl Behaviour { | |||
pub fn new(limits: ConnectionLimits) -> Self { | |||
pub fn new(limits: ConnectionLimits, bypass_rules: BypassRules) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should remove bypass_rules
from here and have it be empty internally by default, or have a separate function to supply it when constructing the behaviour. This would then allow us to keep this as a patch release instead of bumping the minor version of the crate due to it being a breaking change. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the follow-ups @drHuangMHT! LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Can you update the versions in both Cargo.toml (crate and workpace)? :)
Description
Add
BypassRules
forconnection_limit::Behaviour
to allow bypasses.May close #5605
Notes & open questions
This implememtation does not distingush between local addresses and remote addresses, will that be a problem?
Change checklist