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

Add timeout for TLS handshakes #1514

Merged
merged 3 commits into from
Oct 7, 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
4 changes: 4 additions & 0 deletions io/zenoh-links/zenoh-link-tls/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,8 @@ pub mod config {

pub const TLS_VERIFY_NAME_ON_CONNECT: &str = "verify_name_on_connect";
pub const TLS_VERIFY_NAME_ON_CONNECT_DEFAULT: bool = true;

/// The time duration in milliseconds to wait for the TLS handshake to complete.
pub const TLS_HANDSHAKE_TIMEOUT_MS: &str = "tls_handshake_timeout_ms";
pub const TLS_HANDSHAKE_TIMEOUT_MS_DEFAULT: u64 = 10_000;
}
25 changes: 22 additions & 3 deletions io/zenoh-links/zenoh-link-tls/src/unicast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,16 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls {
let token = token.clone();
let manager = self.manager.clone();

async move { accept_task(socket, acceptor, token, manager).await }
async move {
accept_task(
socket,
acceptor,
token,
manager,
tls_server_config.tls_handshake_timeout,
)
.await
}
};

// Update the endpoint locator address
Expand Down Expand Up @@ -406,6 +415,7 @@ async fn accept_task(
acceptor: TlsAcceptor,
token: CancellationToken,
manager: NewLinkChannelSender,
tls_handshake_timeout: Duration,
) -> ZResult<()> {
async fn accept(socket: &TcpListener) -> ZResult<(TcpStream, SocketAddr)> {
let res = socket.accept().await.map_err(|e| zerror!(e))?;
Expand Down Expand Up @@ -436,9 +446,18 @@ async fn accept_task(
};

// Accept the TLS connection
let tls_stream = match acceptor.accept(tcp_stream).await {
Ok(stream) => TlsStream::Server(stream),
let tls_stream = match tokio::time::timeout(
tls_handshake_timeout,
acceptor.accept(tcp_stream),
)
.await
{
Ok(Ok(stream)) => TlsStream::Server(stream),
Err(e) => {
tracing::warn!("TLS handshake timed out: {e}");
continue;
}
Ok(Err(e)) => {
let e = format!("Can not accept TLS connection: {e}");
tracing::warn!("{}", e);
continue;
Expand Down
22 changes: 18 additions & 4 deletions io/zenoh-links/zenoh-link-tls/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
use std::{
convert::TryFrom,
fs::File,
io,
io::{BufReader, Cursor},
io::{self, BufReader, Cursor},
net::SocketAddr,
str::FromStr,
sync::Arc,
time::Duration,
};

use rustls::{
Expand All @@ -37,7 +38,7 @@ use zenoh_protocol::core::{
};
use zenoh_result::{bail, zerror, ZError, ZResult};

use crate::config::*;
use crate::config::{self, *};

#[derive(Default, Clone, Copy, Debug)]
pub struct TlsConfigurator;
Expand Down Expand Up @@ -149,6 +150,7 @@ impl ConfigurationInspector<ZenohConfig> for TlsConfigurator {

pub(crate) struct TlsServerConfig {
pub(crate) server_config: ServerConfig,
pub(crate) tls_handshake_timeout: Duration,
}

impl TlsServerConfig {
Expand Down Expand Up @@ -217,7 +219,19 @@ impl TlsServerConfig {
.with_single_cert(certs, keys.remove(0))
.map_err(|e| zerror!(e))?
};
Ok(TlsServerConfig { server_config: sc })

let tls_handshake_timeout = Duration::from_millis(
config
.get(config::TLS_HANDSHAKE_TIMEOUT_MS)
.map(u64::from_str)
.transpose()?
.unwrap_or(config::TLS_HANDSHAKE_TIMEOUT_MS_DEFAULT),
);

Ok(TlsServerConfig {
server_config: sc,
tls_handshake_timeout,
})
}

async fn load_tls_private_key(config: &Config<'_>) -> ZResult<Vec<u8>> {
Expand Down