@@ -30,7 +30,7 @@ use std::pin::Pin;
3030use std:: sync:: Arc ;
3131use std:: sync:: atomic:: { AtomicBool , Ordering } ;
3232use tokio:: net:: { TcpListener , TcpStream } ;
33- use tokio:: sync:: mpsc;
33+ use tokio:: sync:: { mpsc, oneshot } ;
3434use tokio_stream:: wrappers:: ReceiverStream ;
3535use tonic:: { Request , Response , Status } ;
3636use tracing:: { debug, info, warn} ;
@@ -737,29 +737,10 @@ pub(super) async fn handle_exec_sandbox(
737737 let ( tx, rx) = mpsc:: channel :: < Result < ExecSandboxEvent , Status > > ( 256 ) ;
738738 tokio:: spawn ( async move {
739739 // Wait for the supervisor's reverse CONNECT to deliver the relay stream.
740- let relay_stream = match tokio:: time:: timeout ( std:: time:: Duration :: from_secs ( 10 ) , relay_rx)
741- . await
742- {
743- Ok ( Ok ( Ok ( stream) ) ) => stream,
744- Ok ( Ok ( Err ( status) ) ) => {
745- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, error = %status. message( ) , "ExecSandbox: relay target open failed" ) ;
746- let _ = tx. send ( Err ( status) ) . await ;
747- return ;
748- }
749- Ok ( Err ( _) ) => {
750- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "ExecSandbox: relay channel dropped" ) ;
751- let _ = tx
752- . send ( Err ( Status :: unavailable ( "relay channel dropped" ) ) )
753- . await ;
754- return ;
755- }
756- Err ( _) => {
757- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "ExecSandbox: relay open timed out" ) ;
758- let _ = tx
759- . send ( Err ( Status :: deadline_exceeded ( "relay open timed out" ) ) )
760- . await ;
761- return ;
762- }
740+ let Some ( relay_stream) =
741+ await_relay_stream ( relay_rx, & tx, & sandbox_id, & channel_id, "ExecSandbox" ) . await
742+ else {
743+ return ;
763744 } ;
764745
765746 if let Err ( err) = stream_exec_over_relay (
@@ -782,6 +763,41 @@ pub(super) async fn handle_exec_sandbox(
782763 Ok ( Response :: new ( ReceiverStream :: new ( rx) ) )
783764}
784765
766+ /// Wait for the supervisor's reverse CONNECT to deliver a relay stream.
767+ ///
768+ /// Returns `Some(stream)` on success. On any failure the error is sent on `tx`
769+ /// and `None` is returned; the caller should then `return` immediately.
770+ async fn await_relay_stream < T : Send + ' static > (
771+ relay_rx : oneshot:: Receiver < Result < tokio:: io:: DuplexStream , Status > > ,
772+ tx : & mpsc:: Sender < Result < T , Status > > ,
773+ sandbox_id : & str ,
774+ channel_id : & str ,
775+ context : & str ,
776+ ) -> Option < tokio:: io:: DuplexStream > {
777+ match tokio:: time:: timeout ( std:: time:: Duration :: from_secs ( 10 ) , relay_rx) . await {
778+ Ok ( Ok ( Ok ( stream) ) ) => Some ( stream) ,
779+ Ok ( Ok ( Err ( status) ) ) => {
780+ warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, error = %status. message( ) , "{context}: relay target open failed" ) ;
781+ let _ = tx. send ( Err ( status) ) . await ;
782+ None
783+ }
784+ Ok ( Err ( _) ) => {
785+ warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "{context}: relay channel dropped" ) ;
786+ let _ = tx
787+ . send ( Err ( Status :: unavailable ( "relay channel dropped" ) ) )
788+ . await ;
789+ None
790+ }
791+ Err ( _) => {
792+ warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "{context}: relay open timed out" ) ;
793+ let _ = tx
794+ . send ( Err ( Status :: deadline_exceeded ( "relay open timed out" ) ) )
795+ . await ;
796+ None
797+ }
798+ }
799+ }
800+
785801pub ( super ) async fn handle_forward_tcp (
786802 state : & Arc < ServerState > ,
787803 request : Request < tonic:: Streaming < TcpForwardFrame > > ,
@@ -831,29 +847,10 @@ pub(super) async fn handle_forward_tcp(
831847 let ( tx, rx) = mpsc:: channel :: < Result < TcpForwardFrame , Status > > ( 256 ) ;
832848 tokio:: spawn ( async move {
833849 let _connection_guard = connection_guard;
834- let relay_stream = match tokio:: time:: timeout ( std:: time:: Duration :: from_secs ( 10 ) , relay_rx)
835- . await
836- {
837- Ok ( Ok ( Ok ( stream) ) ) => stream,
838- Ok ( Ok ( Err ( status) ) ) => {
839- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, error = %status. message( ) , "ForwardTcp: relay target open failed" ) ;
840- let _ = tx. send ( Err ( status) ) . await ;
841- return ;
842- }
843- Ok ( Err ( _) ) => {
844- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "ForwardTcp: relay channel dropped" ) ;
845- let _ = tx
846- . send ( Err ( Status :: unavailable ( "relay channel dropped" ) ) )
847- . await ;
848- return ;
849- }
850- Err ( _) => {
851- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "ForwardTcp: relay open timed out" ) ;
852- let _ = tx
853- . send ( Err ( Status :: deadline_exceeded ( "relay open timed out" ) ) )
854- . await ;
855- return ;
856- }
850+ let Some ( relay_stream) =
851+ await_relay_stream ( relay_rx, & tx, & sandbox_id, & channel_id, "ForwardTcp" ) . await
852+ else {
853+ return ;
857854 } ;
858855
859856 bridge_forward_tcp_stream ( inbound, relay_stream, tx, & sandbox_id, & channel_id) . await ;
@@ -1179,29 +1176,16 @@ pub(super) async fn handle_exec_sandbox_interactive(
11791176
11801177 let ( tx, rx) = mpsc:: channel :: < Result < ExecSandboxEvent , Status > > ( 256 ) ;
11811178 tokio:: spawn ( async move {
1182- let relay_stream = match tokio:: time:: timeout ( std:: time:: Duration :: from_secs ( 10 ) , relay_rx)
1183- . await
1184- {
1185- Ok ( Ok ( Ok ( stream) ) ) => stream,
1186- Ok ( Ok ( Err ( status) ) ) => {
1187- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, error = %status. message( ) , "ExecSandboxInteractive: relay target open failed" ) ;
1188- let _ = tx. send ( Err ( status) ) . await ;
1189- return ;
1190- }
1191- Ok ( Err ( _) ) => {
1192- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "ExecSandboxInteractive: relay channel dropped" ) ;
1193- let _ = tx
1194- . send ( Err ( Status :: unavailable ( "relay channel dropped" ) ) )
1195- . await ;
1196- return ;
1197- }
1198- Err ( _) => {
1199- warn ! ( sandbox_id = %sandbox_id, channel_id = %channel_id, "ExecSandboxInteractive: relay open timed out" ) ;
1200- let _ = tx
1201- . send ( Err ( Status :: deadline_exceeded ( "relay open timed out" ) ) )
1202- . await ;
1203- return ;
1204- }
1179+ let Some ( relay_stream) = await_relay_stream (
1180+ relay_rx,
1181+ & tx,
1182+ & sandbox_id,
1183+ & channel_id,
1184+ "ExecSandboxInteractive" ,
1185+ )
1186+ . await
1187+ else {
1188+ return ;
12051189 } ;
12061190
12071191 if let Err ( err) = stream_interactive_exec_over_relay (
0 commit comments