fix(gateway): ensure DNS resolution times out before connection (#5419)

When we attempt to establish a connection to a gateway for a DNS
resource, the gateway must resolve the requested domain name before it
can accept the connection. Currently, this timeout is set to 60s which
is much longer than the client's connection timeout.

DNS resolution is typically a very fast protocol so reducing this
timeout to 5s should be safe. In addition, we add a compile-time
assertion that this timeout must be less than the client's connection
timeout.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
This commit is contained in:
Thomas Eizinger
2024-06-19 08:08:49 +10:00
committed by GitHub
parent 42e6e9593a
commit c4e608bd14
5 changed files with 16 additions and 3 deletions

2
rust/Cargo.lock generated
View File

@@ -1916,6 +1916,8 @@ dependencies = [
"secrecy",
"serde",
"serde_json",
"snownet",
"static_assertions",
"tokio",
"tokio-tungstenite",
"tracing",

View File

@@ -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};

View File

@@ -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;

View File

@@ -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"] }

View File

@@ -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<CallbackHandler>,
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),
}
}
}