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

Nat hole punching for discv5.2 #176

Merged
merged 164 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
164 commits
Select commit Hold shift + click to select a range
539aee9
Plug-in hole punching
emhane Mar 18, 2023
db81228
Notification message container
emhane Mar 20, 2023
fdc792c
Plug relaying into service
emhane Mar 20, 2023
9d223e5
Move hole punch trait to extern crate
emhane Mar 21, 2023
25a5cc5
Adjust impl of hole punch trait
emhane Mar 23, 2023
9b8f821
fixup! Plug relaying into service
emhane Mar 23, 2023
f53f3f6
fixup! Plug-in hole punching
emhane Mar 23, 2023
172d120
Update trait impl
emhane Mar 25, 2023
3987108
Consolidate hole punching in Handler
emhane Mar 25, 2023
410201a
fixup! Consolidate hole punching in Handler
emhane Mar 25, 2023
396a595
fixup! Consolidate hole punching in Handler
emhane Mar 25, 2023
32b812e
Add trace info
emhane Mar 25, 2023
5a2bbc8
fixup! Consolidate hole punching in Handler
emhane Mar 25, 2023
84b0561
Reinsert active request on hole punch attempt
emhane Mar 26, 2023
85575f5
Update node address conversion
emhane Mar 27, 2023
f6872cd
RO access kbuckets from handler for hole punch target peer lookup
emhane Mar 28, 2023
867fc04
Replace RO access to kbuckets with channels
emhane Mar 29, 2023
8ef3df7
Add trace messages
emhane Mar 29, 2023
8b03367
fixup! Add trace messages
emhane Mar 29, 2023
2075d5e
Handle each realy init separately
emhane Mar 29, 2023
a8223e6
Receive responses in notification packets
emhane Mar 31, 2023
8ac4618
Reset renaming of packet kind
emhane Mar 31, 2023
7e4f9df
Send responses in notification
emhane Mar 31, 2023
7043e66
fixup! Reset renaming of packet kind
emhane Mar 31, 2023
c6fcccb
fixup! Reinsert active request on hole punch attempt
emhane Apr 1, 2023
6906ab9
Plug in mechanism for keeping hole punched for peer
Apr 6, 2023
a1c9754
Only give work of keeping hole punched to nodes that aren't WAN reach…
Apr 6, 2023
103c230
fixup! Only give work of keeping hole punched to nodes that aren't WA…
Apr 6, 2023
116d350
Correct comment
Apr 18, 2023
79da626
Include nodes that discover reachable address earlier in small networks
Apr 18, 2023
0eb62dc
fixup! Include nodes that discover reachable address earlier in small…
Apr 18, 2023
02c9a8e
Limit sessions with unreachable enrs
Apr 18, 2023
093f598
Set limit for sessions with peers with unreachable ENRs in config
Apr 20, 2023
bb0e597
Allow unlimited sessions with unreachable ENRs like in discv5.0
Apr 21, 2023
32a7eef
Clean up fs
Apr 21, 2023
e0522a8
Update naming to match wire
Apr 21, 2023
2442fa1
Lint fixes
Apr 21, 2023
b18b411
Doc links fix
Apr 21, 2023
36dcfee
Bug fix
Apr 22, 2023
eae9b14
Log messages fixes
Apr 25, 2023
39cd9a3
Updates from nat hole punch crate
Apr 26, 2023
5e88257
fixup! Updates from nat hole punch crate
Apr 27, 2023
b68beaa
Incorporate notification
Apr 30, 2023
afa637b
notif sep
Apr 30, 2023
2b0876a
Incorporate notification from nat_hole_punch crate
Apr 30, 2023
051921d
Move hole punch trait from nat_hole_punch crate into crate
Apr 30, 2023
e8bd067
fixup! Move hole punch trait from nat_hole_punch crate into crate
Apr 30, 2023
e75892f
Make log message more human readbable
May 1, 2023
dc772d5
Clean up
May 3, 2023
f3be2de
Fix merge conflicts
May 3, 2023
42714f3
Stop punching holes for disconnected peers
May 3, 2023
a005ce7
Fix session limiter constructor bug to not write to logs on no limit …
May 3, 2023
1031f37
Fix wrong comments on message types and collect message types
May 3, 2023
6ee4f7f
Check for unused deps in CI (#1262)
michaelsproul Jun 14, 2020
b82adc7
Cherry-pick 6ee4f7f9
May 4, 2023
8f3b17b
Update github CI to latest version
May 4, 2023
76f0953
Remove unused dependencies
May 4, 2023
37739a5
Remove unused varaiable assignment
May 4, 2023
3c820a0
Restore and improve config comments
May 9, 2023
0258cb2
Use derive From macro
May 9, 2023
67b5d59
fixup! Restore and improve config comments
May 9, 2023
01d111b
Restore drive-by commit to master
May 9, 2023
3eec2d5
Return earlier from enr unreachable check
May 9, 2023
101bd69
Replace parse display with dep used in lighthouse
May 9, 2023
fd62453
Safeguard with const evaluation
May 9, 2023
d9740f9
Fix typo
emhane May 9, 2023
d456f1a
Mark unreachable code
May 12, 2023
c651e2c
Allow assertions on constants
May 12, 2023
74c8404
Fix clippy warnings
May 12, 2023
1f7f86d
fixup! Allow assertions on constants
May 13, 2023
876c68a
fixup! Return earlier from enr unreachable check
May 13, 2023
a6998da
fixup! Fix session limiter constructor bug to not write to logs on no…
May 13, 2023
d13832a
fixup! Return earlier from enr unreachable check
May 13, 2023
fbf313f
Shorten debug message
May 13, 2023
9da9c1c
Correct comment correction
May 19, 2023
732bf7b
Revert symbol
May 19, 2023
8a8640b
Nitpick
emhane May 23, 2023
709c514
Clarify comment
May 23, 2023
fdfddb4
Reinsert Cargo.lock in gitignore
May 23, 2023
207d096
Fix curly brace bug
May 23, 2023
14180f8
remove lockfile
divagant-martian May 24, 2023
13f308a
reduce diff
divagant-martian May 24, 2023
0e40463
clippy
divagant-martian May 24, 2023
a7ebf96
Fix typo
emhane May 25, 2023
48f10d2
Check limit in config instead
May 25, 2023
386775d
Restore comment
May 25, 2023
72a9ecf
Simplify docs
May 25, 2023
3926fce
Drop notification already at service layer
May 25, 2023
d2612e9
Improve rust idiomacy
May 25, 2023
8961aae
fixup! Drop notification already at service layer
May 25, 2023
d68ce6b
Nitpick
May 25, 2023
e79df73
Remove hole punch trait
May 25, 2023
9753761
Simplify bind
emhane May 25, 2023
cae34a9
Expose unused ports range parameter in config
May 25, 2023
2a1bf45
Fix typo
emhane May 25, 2023
099a6ae
Fix merge conflicts with remote
May 25, 2023
e398e6f
Merge remote-tracking branch 'remotes/origin/nat-hole-punch-discv5.2'…
May 25, 2023
5b75058
Fix ci for ipv6 tests
May 25, 2023
0f4d7b5
Name consistently with specs
emhane Jul 8, 2023
789f3f0
Fix typo
emhane Jul 8, 2023
f46b964
Only track outgoing packets if node is behind nat
emhane Jun 21, 2023
1b0e0dd
Only process relay messages if we are behind a nat
emhane Jun 21, 2023
4750490
Catch malicious relay init
emhane Jun 21, 2023
0477bdb
Clear hole punch tracker set for remaining entries
emhane Nov 27, 2023
8852d93
Run lint
emhane Nov 27, 2023
f03662a
Introduce bound on relay store
emhane Nov 27, 2023
b5c0766
Remove redundant parameter
emhane Nov 27, 2023
2c60235
Keep session but drop packet that could be spoofed
emhane Nov 27, 2023
7cde68c
Add debug info
emhane Nov 27, 2023
32321a7
Revert layout of hole punch code to use trait
emhane Nov 27, 2023
abe4225
Fix backwards compatibility of packet type Message
emhane Jan 4, 2024
fbb5a00
Remove duplicate guard
emhane Jan 4, 2024
b18e463
Use lru time cach for tracking sent packages
emhane Jan 4, 2024
9241d03
Adjust visibility, handler not alone-standing crate
emhane Jan 4, 2024
5583324
Add signature for using session limiter on cache insert
emhane Jan 4, 2024
535ea0a
Only send expired entries on channel
emhane Jan 4, 2024
58bbb0c
Remove duplicate code
emhane Jan 4, 2024
bf72841
Move assertion on constant outside of function
emhane Jan 4, 2024
4038f35
no unreachables in session enr
divagant-martian May 24, 2023
34e6a4c
Avoid breaking change to lru time cache api
emhane Jan 4, 2024
ac7fe9f
Change name 'session index' to name of session index type
emhane Jan 4, 2024
a0d09c1
Update docs
emhane Jan 4, 2024
89a81ae
Update comment
emhane Jan 4, 2024
7b521d7
Merge branch 'nat-hole-punch-discv5.2' of github.com:emhane/discv5 in…
emhane Jan 4, 2024
35b4877
fixup! Update docs
emhane Jan 4, 2024
a729371
Lint fixes
emhane Jan 4, 2024
b8169fc
Lint fixes
emhane Jan 6, 2024
75627a5
fixup! Lint fixes
emhane Jan 6, 2024
421066b
Fix docs
emhane Jan 6, 2024
12712c4
Fix merge conflicts
emhane Jan 6, 2024
8c7c36e
Fix merge conflicts with discv5.2
emhane Jan 6, 2024
1aed55d
Tweak incorporation of SessionLimiter
emhane Jan 6, 2024
a5ec452
Avoid clone
emhane Jan 6, 2024
defa9ed
Lint fixes
emhane Jan 6, 2024
308d793
Enable ipv6 tests
emhane Jan 6, 2024
d22647b
fixup! Fix merge conflicts with discv5.2
emhane Jan 6, 2024
43be184
fixup! Enable ipv6 tests
emhane Jan 6, 2024
d6550fb
Fix test parallelisation
emhane Jan 6, 2024
07b0c02
Add relay test for handler
emhane Jan 6, 2024
c5f281c
Drive-by, fix param name
emhane Jan 6, 2024
c5d47bb
Drive-by, clean up test
emhane Jan 6, 2024
9138018
Fix handler test parallelisation
emhane Jan 6, 2024
c94c7e1
Skip unnecessary interaction with service task
emhane Jan 14, 2024
3620b37
Add test for target
emhane Jan 14, 2024
b32e750
Remove unnecessary memory re-allocation for sessions cache
emhane Jan 14, 2024
b947364
Reset previous commit
emhane Jan 14, 2024
e0a2d4a
Improve type safety for notifications
emhane Jan 14, 2024
25077d4
Reset commit b32e7507 and check sequence of initiator's enr against k…
emhane Jan 14, 2024
41f0ef6
Refactor initiator abbreviation
emhane Jan 14, 2024
6187597
Trigger ping all peers on upgrade to reachable enr
emhane Jan 15, 2024
8fd5434
Modify session management to inside the lrutimecache
AgeManning Jan 15, 2024
2ecc61f
Merge to the latest
AgeManning Jan 15, 2024
402c964
Add reviewers comments
AgeManning Jan 17, 2024
e50661c
Simplify the code, name changes group handler API
AgeManning Jan 17, 2024
18e44f2
Old mate fmt
AgeManning Jan 17, 2024
5c89f12
Merge pull request #5 from sigp/review-suggestions
emhane Jan 17, 2024
e3478c2
Fix bug broken invariant active-requests and hole punch attempts
emhane Jan 17, 2024
f0a1e51
Merge latest updates
AgeManning Jan 17, 2024
b42e677
Update src/handler/mod.rs
AgeManning Jan 18, 2024
bf4723d
Update src/service.rs
AgeManning Jan 18, 2024
942661c
Update src/handler/mod.rs
AgeManning Jan 18, 2024
08cd2b6
Complete the renaming
AgeManning Jan 18, 2024
fb54740
Fmt
AgeManning Jan 18, 2024
21ea794
Merge pull request #6 from sigp/further-review
emhane Jan 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Get latest version of stable rust
run: rustup update stable
- name: Lint code for quality and style with Clippy
run: cargo clippy --workspace --tests --all-features -- -D warnings
run: cargo clippy --workspace --tests --all-features -- -D warnings -A clippy::assertions_on_constants
release-tests-ubuntu:
runs-on: ubuntu-latest
needs: cargo-fmt
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Get latest version of stable rust
run: rustup update stable
- name: Check rustdoc links
run: RUSTDOCFLAGS="--deny broken_intra_doc_links" cargo doc --verbose --workspace --no-deps --document-private-items
run: RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --verbose --workspace --no-deps --document-private-items
cargo-udeps:
name: cargo-udeps
runs-on: ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ aes = { version = "0.7.5", features = ["ctr"] }
aes-gcm = "0.9.4"
tracing = { version = "0.1.29", features = ["log"] }
tracing-subscriber = { version = "0.3.3", features = ["env-filter"] }
lru = "0.7.1"
lru = {version = "0.7.1", default-features = false }
hashlink = "0.7.0"
delay_map = "0.3.0"
more-asserts = "0.2.2"
derive_more = { version = "0.99.17", default-features = false, features = ["from", "display", "deref", "deref_mut"] }

[dev-dependencies]
rand_07 = { package = "rand", version = "0.7" }
Expand Down
40 changes: 38 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
//! A set of configuration parameters to tune the discovery protocol.
use crate::{
kbucket::MAX_NODES_PER_BUCKET, socket::ListenConfig, Enr, Executor, PermitBanList, RateLimiter,
kbucket::MAX_NODES_PER_BUCKET, Enr, Executor, ListenConfig, PermitBanList, RateLimiter,
RateLimiterBuilder,
};
use std::time::Duration;

/// The minimum number of unreachable Sessions a node must allow. This enables the network to
/// boostrap.
const MIN_SESSIONS_UNREACHABLE_ENR: usize = 10;

use std::{ops::RangeInclusive, time::Duration};

/// Configuration parameters that define the performance of the discovery network.
#[derive(Clone)]
Expand Down Expand Up @@ -96,6 +101,15 @@ pub struct Discv5Config {
/// timing support. By default, the executor that created the discv5 struct will be used.
pub executor: Option<Box<dyn Executor + Send + Sync>>,

/// The max limit for peers with unreachable ENRs. Benevolent examples of such peers are peers
/// that are discovering their externally reachable socket, nodes must assist at least one
/// such peer in discovering their reachable socket via ip voting, and peers behind symmetric
/// NAT. Default is no limit. Minimum is 10.
pub unreachable_enr_limit: Option<usize>,
emhane marked this conversation as resolved.
Show resolved Hide resolved

/// The unused port range to try and bind to when testing if this node is behind NAT based on
/// observed address reported at runtime by peers.
pub unused_port_range: Option<RangeInclusive<u16>>,
/// Configuration for the sockets to listen on.
pub listen_config: ListenConfig,
}
Expand Down Expand Up @@ -142,6 +156,8 @@ impl Discv5ConfigBuilder {
permit_ban_list: PermitBanList::default(),
ban_duration: Some(Duration::from_secs(3600)), // 1 hour
executor: None,
unreachable_enr_limit: None,
unused_port_range: None,
listen_config,
};

Expand Down Expand Up @@ -302,13 +318,33 @@ impl Discv5ConfigBuilder {
self
}

/// Sets the maximum number of sessions with peers with unreachable ENRs to allow. Minimum is 1
/// peer. Default is no limit.
pub fn unreachable_enr_limit(&mut self, peer_limit: Option<usize>) -> &mut Self {
self.config.unreachable_enr_limit = peer_limit;
self
}

/// Sets the unused port range for testing if node is behind a NAT. Default is the range
/// covering user and dynamic ports.
pub fn unused_port_range(
&mut self,
unused_port_range: Option<RangeInclusive<u16>>,
) -> &mut Self {
self.config.unused_port_range = unused_port_range;
self
}

pub fn build(&mut self) -> Discv5Config {
// If an executor is not provided, assume a current tokio runtime is running.
if self.config.executor.is_none() {
self.config.executor = Some(Box::<crate::executor::TokioExecutor>::default());
};

assert!(self.config.incoming_bucket_limit <= MAX_NODES_PER_BUCKET);
if let Some(limit) = self.config.unreachable_enr_limit {
assert!(limit >= MIN_SESSIONS_UNREACHABLE_ENR);
}

self.config.clone()
}
Expand Down
47 changes: 41 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
use crate::{handler::Challenge, node_info::NonContactable};
use crate::{
handler::Challenge,
node_info::{NodeAddress, NonContactable},
};
use derive_more::From;
use rlp::DecoderError;
use std::fmt;

#[derive(Debug)]
#[derive(Debug, From)]
/// A general error that is used throughout the Discv5 library.
pub enum Discv5Error {
/// An invalid message type was received.
InvalidMessage,
/// An invalid ENR was received.
InvalidEnr,
/// The limit for sessions with peers that have an unreachable ENR is reached.
LimitSessionsUnreachableEnr,
/// The public key type is known.
UnknownPublicKey,
/// The ENR key used is not supported.
#[from(ignore)]
KeyTypeNotSupported(&'static str),
/// Failed to derive an ephemeral public key.
KeyDerivationFailed,
Expand All @@ -27,25 +36,48 @@ pub enum Discv5Error {
ServiceAlreadyStarted,
/// A session could not be established with the remote.
SessionNotEstablished,
/// A session to the given peer is already established.
SessionAlreadyEstablished(NodeAddress),
/// An RLP decoding error occurred.
RLPError(DecoderError),
/// Failed to encrypt a message.
#[from(ignore)]
EncryptionFail(String),
/// Failed to decrypt a message.
#[from(ignore)]
DecryptionFailed(String),
/// The custom error has occurred.
#[from(ignore)]
Custom(&'static str),
/// A generic dynamic error occurred.
#[from(ignore)]
Error(String),
/// An IO error occurred.
Io(std::io::Error),
}

impl From<std::io::Error> for Discv5Error {
fn from(err: std::io::Error) -> Discv5Error {
Discv5Error::Io(err)
}
/// An error occurred whilst attempting to hole punch NAT.
#[derive(Debug)]
pub enum NatError {
/// Initiator error.
Initiator(Discv5Error),
/// Relayer error.
Relay(Discv5Error),
/// Target error.
Target(Discv5Error),
}

macro_rules! impl_from_variant {
($(<$($generic: ident,)+>)*, $from_type: ty, $to_type: ty, $variant: path) => {
impl$(<$($generic,)+>)* From<$from_type> for $to_type {
fn from(_e: $from_type) -> Self {
$variant
}
}
};
}
impl_from_variant!(<T,>, tokio::sync::mpsc::error::SendError<T>, Discv5Error, Self::ServiceChannelClosed);
impl_from_variant!(, NonContactable, Discv5Error, Self::InvalidEnr);

#[derive(Debug, Clone, PartialEq, Eq)]
/// Types of packet errors.
Expand Down Expand Up @@ -111,6 +143,9 @@ pub enum RequestError {
InvalidMultiaddr(&'static str),
/// Failure generating random numbers during request.
EntropyFailure(&'static str),
/// Malicious peer tried to initiate nat hole punching for another peer. todo(emhane): this is
/// notification error.
MaliciousRelayInit,
}

#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down
Loading