diff --git a/rust/Cargo.lock b/rust/Cargo.lock index fb22e3593..f508ac74a 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1916,6 +1916,8 @@ dependencies = [ "secrecy", "serde", "serde_json", + "snownet", + "static_assertions", "tokio", "tokio-tungstenite", "tracing", diff --git a/rust/connlib/snownet/src/lib.rs b/rust/connlib/snownet/src/lib.rs index dd06195d3..e34323b90 100644 --- a/rust/connlib/snownet/src/lib.rs +++ b/rust/connlib/snownet/src/lib.rs @@ -13,6 +13,6 @@ mod utils; pub use allocation::RelaySocket; pub use node::{ Answer, Client, ClientNode, Credentials, Error, Event, Node, Offer, Server, ServerNode, - Transmit, + Transmit, HANDSHAKE_TIMEOUT, }; pub use stats::{ConnectionStats, NodeStats}; diff --git a/rust/connlib/snownet/src/node.rs b/rust/connlib/snownet/src/node.rs index 6279c1ec3..d30a782cf 100644 --- a/rust/connlib/snownet/src/node.rs +++ b/rust/connlib/snownet/src/node.rs @@ -38,7 +38,7 @@ const HANDSHAKE_RATE_LIMIT: u64 = 100; const CANDIDATE_TIMEOUT: Duration = Duration::from_secs(10); /// How long we will at most wait for an [`Answer`] from the remote. -const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(20); +pub const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(20); const MAX_UDP_SIZE: usize = (1 << 16) - 1; diff --git a/rust/gateway/Cargo.toml b/rust/gateway/Cargo.toml index 5206b6d91..59e66c131 100644 --- a/rust/gateway/Cargo.toml +++ b/rust/gateway/Cargo.toml @@ -33,6 +33,8 @@ dns-lookup = { workspace = true } libc = { version = "0.2", default-features = false, features = ["std", "const-extern-fn", "extra_traits"] } either = "1" http-health-check = { workspace = true } +static_assertions = "1.1.0" +snownet = { workspace = true } [dev-dependencies] serde_json = { version = "1.0", default-features = false, features = ["std"] } diff --git a/rust/gateway/src/eventloop.rs b/rust/gateway/src/eventloop.rs index f6baf5d96..8f48f71d8 100644 --- a/rust/gateway/src/eventloop.rs +++ b/rust/gateway/src/eventloop.rs @@ -24,6 +24,15 @@ use std::time::Duration; pub const PHOENIX_TOPIC: &str = "gateway"; +/// How long we allow a DNS resolution via `libc::get_addr_info`. +const DNS_RESOLUTION_TIMEOUT: Duration = Duration::from_secs(10); + +// DNS resolution happens as part of every connection setup. +// For a connection to succeed, DNS resolution must be less than `snownet`'s handshake timeout. +static_assertions::const_assert!( + DNS_RESOLUTION_TIMEOUT.as_secs() < snownet::HANDSHAKE_TIMEOUT.as_secs() +); + pub struct Eventloop { tunnel: GatewayTunnel, portal: PhoenixChannel<(), IngressMessages, ()>, @@ -40,7 +49,7 @@ impl Eventloop { Self { tunnel, portal, - resolve_tasks: futures_bounded::FuturesTupleSet::new(Duration::from_secs(60), 100), + resolve_tasks: futures_bounded::FuturesTupleSet::new(DNS_RESOLUTION_TIMEOUT, 100), } } }