mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-06-03 05:49:31 +00:00
webrtc/signalling: Fix potential hang and FD leak
If a peer connects via TCP and never initiates TLS, then the server will get stuck in the accept loop. Spawn a task when accepting a TLS connection, and timeout if it doesn't complete in 5 seconds. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1412>
This commit is contained in:
parent
d9397ef174
commit
63b568f4a0
|
@ -2,17 +2,20 @@
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use gst_plugin_webrtc_signalling::handlers::Handler;
|
use gst_plugin_webrtc_signalling::handlers::Handler;
|
||||||
use gst_plugin_webrtc_signalling::server::Server;
|
use gst_plugin_webrtc_signalling::server::{Server, ServerError};
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use tracing_subscriber::prelude::*;
|
use tracing_subscriber::prelude::*;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
use std::time::Duration;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tokio_native_tls::native_tls::TlsAcceptor;
|
use tokio_native_tls::native_tls::TlsAcceptor;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
const TLS_HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(about, version, author)]
|
#[clap(about, version, author)]
|
||||||
/// Program arguments
|
/// Program arguments
|
||||||
|
@ -94,15 +97,20 @@ async fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
info!("Accepting connection from {}", address);
|
info!("Accepting connection from {}", address);
|
||||||
|
|
||||||
if let Some(ref acceptor) = acceptor {
|
if let Some(acceptor) = acceptor.clone() {
|
||||||
let stream = match acceptor.accept(stream).await {
|
tokio::spawn(async move {
|
||||||
Ok(stream) => stream,
|
match tokio::time::timeout(TLS_HANDSHAKE_TIMEOUT, acceptor.accept(stream)).await {
|
||||||
Err(err) => {
|
Ok(Ok(stream)) => server_clone.accept_async(stream).await,
|
||||||
|
Ok(Err(err)) => {
|
||||||
warn!("Failed to accept TLS connection from {}: {}", address, err);
|
warn!("Failed to accept TLS connection from {}: {}", address, err);
|
||||||
continue;
|
Err(ServerError::TLSHandshake(err))
|
||||||
}
|
}
|
||||||
};
|
Err(elapsed) => {
|
||||||
task::spawn(async move { server_clone.accept_async(stream).await });
|
warn!("TLS connection timed out {} after {}", address, elapsed);
|
||||||
|
Err(ServerError::TLSHandshakeTimeout(elapsed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
task::spawn(async move { server_clone.accept_async(stream).await });
|
task::spawn(async move { server_clone.accept_async(stream).await });
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,10 @@ pub struct Server {
|
||||||
pub enum ServerError {
|
pub enum ServerError {
|
||||||
#[error("error during handshake {0}")]
|
#[error("error during handshake {0}")]
|
||||||
Handshake(#[from] async_tungstenite::tungstenite::Error),
|
Handshake(#[from] async_tungstenite::tungstenite::Error),
|
||||||
|
#[error("error during TLS handshake {0}")]
|
||||||
|
TLSHandshake(#[from] tokio_native_tls::native_tls::Error),
|
||||||
|
#[error("timeout during TLS handshake {0}")]
|
||||||
|
TLSHandshakeTimeout(#[from] tokio::time::error::Elapsed),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
|
|
Loading…
Reference in a new issue