Skip to content

Commit 4d2c340

Browse files
author
pingoo
committed
proxy: fix minor TLS hang
1 parent 1f5fd90 commit 4d2c340

File tree

5 files changed

+102
-55
lines changed

5 files changed

+102
-55
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pingoo"
3-
version = "0.14.8"
3+
version = "0.14.9"
44
edition = "2024"
55

66
[[bin]]

pingoo/listeners/https_listener.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -82,32 +82,34 @@ impl Listener for HttpsListener {
8282
Err(_) => continue,
8383
};
8484

85-
let tls_stream = match accept_tls_connection(
86-
tcp_stream,
87-
self.tls_manager.clone(),
88-
client_socket_addr,
89-
&self.name,
90-
tls_server_config.clone(),
91-
)
92-
.await
93-
{
94-
Ok(Some(tls_stream)) => tls_stream,
95-
_ => continue,
96-
};
85+
tokio::spawn({
86+
let tls_stream = match accept_tls_connection(
87+
tcp_stream,
88+
self.tls_manager.clone(),
89+
client_socket_addr,
90+
&self.name,
91+
tls_server_config.clone(),
92+
)
93+
.await
94+
{
95+
Ok(Some(tls_stream)) => tls_stream,
96+
_ => return,
97+
};
9798

98-
tokio::spawn(serve_http_requests(
99-
TokioIo::new(tls_stream),
100-
self.services.clone(),
101-
client_socket_addr,
102-
self.address,
103-
self.name.clone(),
104-
self.rules.clone(),
105-
self.lists.clone(),
106-
self.geoip.clone(),
107-
self.captcha_manager.clone(),
108-
true,
109-
graceful_shutdown.watcher(),
110-
));
99+
serve_http_requests(
100+
TokioIo::new(tls_stream),
101+
self.services.clone(),
102+
client_socket_addr,
103+
self.address,
104+
self.name.clone(),
105+
self.rules.clone(),
106+
self.lists.clone(),
107+
self.geoip.clone(),
108+
self.captcha_manager.clone(),
109+
true,
110+
graceful_shutdown.watcher(),
111+
)
112+
});
111113
},
112114
_ = shutdown_signal.changed() => {
113115
break;

pingoo/listeners/mod.rs

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{
66

77
use rustls::{ServerConfig, server::Acceptor};
88
use socket2::{Domain, Socket, Type};
9-
use tokio::{io::AsyncWriteExt, net::TcpStream, sync::watch};
9+
use tokio::{io::AsyncWriteExt, net::TcpStream, sync::watch, time};
1010
use tokio_rustls::{LazyConfigAcceptor, server::TlsStream};
1111
use tracing::debug;
1212

@@ -26,6 +26,7 @@ pub use tcp_listener::TcpListener;
2626
pub use tcp_tls_listener::TcpAndTlsListener;
2727

2828
pub const GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(20);
29+
pub const TLS_HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(10);
2930

3031
/// Listeners handle connections and dispatch HTTP requests to services
3132
#[async_trait::async_trait]
@@ -116,37 +117,76 @@ async fn accept_tls_connection<IO: Unpin + tokio::io::AsyncRead + tokio::io::Asy
116117
listener_name: &str,
117118
tls_server_config: Arc<ServerConfig>,
118119
) -> Result<Option<TlsStream<IO>>, ()> {
119-
let tls_start_handshake = match LazyConfigAcceptor::new(Acceptor::default(), tcp_stream).await {
120-
Ok(tls_start_handshake) => tls_start_handshake,
121-
Err(err) => {
122-
debug!(listener = listener_name, client = ?client_socket_addr, "error accepting TLS connection: {err:?}");
123-
return Err(());
124-
}
125-
};
120+
let tls_start_handshake =
121+
match time::timeout(TLS_HANDSHAKE_TIMEOUT, LazyConfigAcceptor::new(Acceptor::default(), tcp_stream)).await {
122+
Ok(Ok(tls_start_handshake)) => tls_start_handshake,
123+
Ok(Err(err)) => {
124+
debug!(
125+
listener = listener_name,
126+
client = ?client_socket_addr,
127+
"error accepting TLS connection: {err:?}"
128+
);
129+
return Err(());
130+
}
131+
Err(err) => {
132+
debug!(
133+
listener = listener_name,
134+
client = ?client_socket_addr,
135+
"TLS handshake timeout before ClientHello: {err:?}"
136+
);
137+
return Err(());
138+
}
139+
};
126140

127141
let client_hello = tls_start_handshake.client_hello();
128142

129143
// handle ACME tls-alpn-01 challenges
130144
if is_tls_alpn_challenge(&client_hello) {
131145
let tls_config_acme = tls_manager.get_tls_alpn_01_server_config(&client_hello).await;
132-
let mut stream = match tls_start_handshake.into_stream(tls_config_acme).await {
133-
Ok(stream) => stream,
134-
Err(err) => {
135-
debug!(listener = listener_name, client = ?client_socket_addr, "error converting TLS stream to TCP stream for ACME: {err:?}");
136-
return Err(());
137-
}
138-
};
146+
let mut stream =
147+
match time::timeout(TLS_HANDSHAKE_TIMEOUT, tls_start_handshake.into_stream(tls_config_acme)).await {
148+
Ok(Ok(stream)) => stream,
149+
Ok(Err(err)) => {
150+
debug!(
151+
listener = listener_name,
152+
client = ?client_socket_addr,
153+
"error converting TLS stream to TCP stream for ACME: {err:?}"
154+
);
155+
return Err(());
156+
}
157+
Err(err) => {
158+
debug!(
159+
listener = listener_name,
160+
client = ?client_socket_addr,
161+
"TLS handshake timeout during ACME: {err:?}"
162+
);
163+
return Err(());
164+
}
165+
};
139166
let _ = stream.shutdown().await;
140167
return Ok(None);
141168
}
142169

143-
let tcp_stream = match tls_start_handshake.into_stream(tls_server_config).await {
144-
Ok(tcp_stream) => tcp_stream,
145-
Err(err) => {
146-
debug!(listener = listener_name, client = ?client_socket_addr, "error converting TLS stream to TCP stream: {err:?}");
147-
return Err(());
148-
}
149-
};
170+
let tcp_stream =
171+
match time::timeout(TLS_HANDSHAKE_TIMEOUT, tls_start_handshake.into_stream(tls_server_config)).await {
172+
Ok(Ok(tcp_stream)) => tcp_stream,
173+
Ok(Err(err)) => {
174+
debug!(
175+
listener = listener_name,
176+
client = ?client_socket_addr,
177+
"error converting TLS stream to TCP stream: {err:?}"
178+
);
179+
return Err(());
180+
}
181+
Err(err) => {
182+
debug!(
183+
listener = listener_name,
184+
client = ?client_socket_addr,
185+
"TLS handshake timeout during server config: {err:?}"
186+
);
187+
return Err(());
188+
}
189+
};
150190

151191
debug!(listener = listener_name, client = ?client_socket_addr, "TLS connection accepted");
152192

pingoo/listeners/tcp_tls_listener.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,17 @@ impl Listener for TcpAndTlsListener {
5656
Err(_) => continue,
5757
};
5858

59-
if let Ok(Some(tls_stream)) =
60-
accept_tls_connection(tcp_stream, self.tls_manager.clone(), client_socket_addr, &self.name, tls_server_config.clone()).await
61-
{
62-
let service = self.service.clone();
63-
connections.spawn(service.serve_connection(Box::new(tls_stream), client_socket_addr));
64-
};
59+
let service = self.service.clone();
60+
let tls_server_config = tls_server_config.clone();
61+
let name = self.name.clone();
62+
let tls_manager = self.tls_manager.clone();
63+
64+
connections.spawn(async move {
65+
if let Ok(Some(tls_stream)) =
66+
accept_tls_connection(tcp_stream, tls_manager, client_socket_addr, &name, tls_server_config).await {
67+
service.serve_connection(Box::new(tls_stream), client_socket_addr).await;
68+
}
69+
});
6570
},
6671
_ = shutdown_signal.changed() => {
6772
break;

0 commit comments

Comments
 (0)