fix(tunnel): prevent tunnel backpressure buffering from exhausting memory and cancel stream handlers before TLS shutdown
This commit is contained in:
@@ -587,21 +587,23 @@ async fn connect_to_hub_and_run(
|
||||
}
|
||||
};
|
||||
|
||||
// Graceful TLS shutdown: send close_notify so the hub sees a clean disconnect
|
||||
// instead of "peer closed connection without sending TLS close_notify".
|
||||
let mut tls_stream = tunnel_io.into_inner();
|
||||
let _ = tokio::time::timeout(
|
||||
Duration::from_secs(2),
|
||||
tls_stream.shutdown(),
|
||||
).await;
|
||||
|
||||
// Cleanup
|
||||
// Cancel stream tokens FIRST so stream handlers exit immediately.
|
||||
// If we TLS-shutdown first, stream handlers are stuck sending to dead channels
|
||||
// for up to 2 seconds while the shutdown times out on a dead connection.
|
||||
connection_token.cancel();
|
||||
stun_handle.abort();
|
||||
for (_, h) in port_listeners.drain() {
|
||||
h.abort();
|
||||
}
|
||||
|
||||
// Graceful TLS shutdown: send close_notify so the hub sees a clean disconnect.
|
||||
// Stream handlers are already cancelled, so no new data is being produced.
|
||||
let mut tls_stream = tunnel_io.into_inner();
|
||||
let _ = tokio::time::timeout(
|
||||
Duration::from_secs(2),
|
||||
tls_stream.shutdown(),
|
||||
).await;
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
@@ -844,17 +844,19 @@ async fn handle_edge_connection(
|
||||
}
|
||||
}
|
||||
|
||||
// Graceful TLS shutdown: send close_notify so the edge sees a clean disconnect
|
||||
// instead of "peer closed connection without sending TLS close_notify".
|
||||
// Cancel stream tokens FIRST so stream handlers exit immediately.
|
||||
// If we TLS-shutdown first, stream handlers are stuck sending to dead channels
|
||||
// for up to 2 seconds while the shutdown times out on a dead connection.
|
||||
edge_token.cancel();
|
||||
config_handle.abort();
|
||||
|
||||
// Graceful TLS shutdown: send close_notify so the edge sees a clean disconnect.
|
||||
// Stream handlers are already cancelled, so no new data is being produced.
|
||||
let mut tls_stream = tunnel_io.into_inner();
|
||||
let _ = tokio::time::timeout(
|
||||
Duration::from_secs(2),
|
||||
tls_stream.shutdown(),
|
||||
).await;
|
||||
|
||||
// Cleanup: cancel edge token to propagate to all child tasks
|
||||
edge_token.cancel();
|
||||
config_handle.abort();
|
||||
{
|
||||
let mut edges = connected.lock().await;
|
||||
edges.remove(&edge_id);
|
||||
|
||||
Reference in New Issue
Block a user