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

Automatic Firewall/NAT Detection #271

Merged
merged 8 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ categories = ["network-programming", "asynchronous"]
exclude = [".gitignore", ".github/*"]

[dependencies]
enr = { version = "0.12", features = ["k256", "ed25519"] }
enr = { git = "https://github.com/sigp/enr", branch = "remove-fields", features = [
"k256",
"ed25519",
] } # enr = { version = "0.12", features = ["k256", "ed25519"] }
tokio = { version = "1", features = ["net", "sync", "macros", "rt"] }
libp2p-identity = { version = "0.2", features = [
"ed25519",
"secp256k1",
"ed25519",
"secp256k1",
], optional = true }
multiaddr = { version = "0.18", optional = true }
zeroize = { version = "1", features = ["zeroize_derive"] }
Expand Down
31 changes: 31 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ pub struct Config {
/// will last indefinitely. Default is 1 hour.
pub ban_duration: Option<Duration>,

/// Auto-discovering our IP address, is only one part in discovering our NAT/firewall
/// situation. We need to determine if we are behind a firewall that is preventing incoming
/// connections (this is especially true for IPv6 where all connections will report the same
/// external IP). To do this, Discv5 uses a heuristic, which is that after we set an address in
/// our ENR, we wait for this duration to see if we have any incoming connections. If we
/// receive a single INCOMING connection in this duration, we consider ourselves contactable,
/// until we update or change our IP address again. If we fail to receive an incoming
/// connection in this duration, we revoke our ENR address advertisement for 6 hours, before
/// trying again. This can be set to None, to always advertise and never revoke. The default is
/// Some(5 minutes).
pub auto_nat_listen_duration: Option<Duration>,

/// A custom executor which can spawn the discv5 tasks. This must be a tokio runtime, with
/// timing support. By default, the executor that created the discv5 struct will be used.
pub executor: Option<Box<dyn Executor + Send + Sync>>,
Expand Down Expand Up @@ -141,6 +153,7 @@ impl ConfigBuilder {
filter_max_bans_per_ip: Some(5),
permit_ban_list: PermitBanList::default(),
ban_duration: Some(Duration::from_secs(3600)), // 1 hour
auto_nat_listen_duration: Some(Duration::from_secs(300)), // 5 minutes
executor: None,
listen_config,
};
Expand Down Expand Up @@ -295,6 +308,24 @@ impl ConfigBuilder {
self
}

/// Auto-discovering our IP address, is only one part in discovering our NAT/firewall
/// situation. We need to determine if we are behind a firewall that is preventing incoming
/// connections (this is especially true for IPv6 where all connections will report the same
/// external IP). To do this, Discv5 uses a heuristic, which is that after we set an address in
/// our ENR, we wait for this duration to see if we have any incoming connections. If we
/// receive a single INCOMING connection in this duration, we consider ourselves contactable,
/// until we update or change our IP address again. If we fail to receive an incoming
/// connection in this duration, we revoke our ENR address advertisement for 6 hours, before
/// trying again. This can be set to None, to always advertise and never revoke. The default is
/// Some(5 minutes).
pub fn auto_nat_listen_duration(
&mut self,
auto_nat_listen_duration: Option<Duration>,
) -> &mut Self {
self.config.auto_nat_listen_duration = auto_nat_listen_duration;
self
}

/// A custom executor which can spawn the discv5 tasks. This must be a tokio runtime, with
/// timing support.
pub fn executor(&mut self, executor: Box<dyn Executor + Send + Sync>) -> &mut Self {
Expand Down
14 changes: 13 additions & 1 deletion src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

lazy_static! {
pub static ref METRICS: InternalMetrics = InternalMetrics::default();
Expand All @@ -16,6 +16,10 @@ pub struct InternalMetrics {
pub bytes_sent: AtomicUsize,
/// The number of bytes received.
pub bytes_recv: AtomicUsize,
/// Whether we consider ourselves contactable or not on ipv4.
pub ipv4_contactable: AtomicBool,
/// Whether we consider ourselves contactable or not on ipv6.
pub ipv6_contactable: AtomicBool,
}

impl Default for InternalMetrics {
Expand All @@ -26,6 +30,8 @@ impl Default for InternalMetrics {
unsolicited_requests_per_window: AtomicUsize::new(0),
bytes_sent: AtomicUsize::new(0),
bytes_recv: AtomicUsize::new(0),
ipv4_contactable: AtomicBool::new(false),
ipv6_contactable: AtomicBool::new(false),
}
}
}
Expand Down Expand Up @@ -55,6 +61,10 @@ pub struct Metrics {
pub bytes_sent: usize,
/// The number of bytes received.
pub bytes_recv: usize,
/// Whether we consider ourselves contactable or not.
pub ipv4_contactable: bool,
/// Whether we consider ourselves contactable or not.
pub ipv6_contactable: bool,
}

impl From<&METRICS> for Metrics {
Expand All @@ -67,6 +77,8 @@ impl From<&METRICS> for Metrics {
/ internal_metrics.moving_window as f64,
bytes_sent: internal_metrics.bytes_sent.load(Ordering::Relaxed),
bytes_recv: internal_metrics.bytes_recv.load(Ordering::Relaxed),
ipv4_contactable: internal_metrics.ipv4_contactable.load(Ordering::Relaxed),
ipv6_contactable: internal_metrics.ipv6_contactable.load(Ordering::Relaxed),
}
}
}
Loading