@@ -447,7 +447,10 @@ async fn run_session_proxy(advertise_subnets: Vec<Ipv4Network>, send: quinn::Sen
447447 let _: anyhow:: Result < ( ) > = async {
448448 let mut session: SessionStream < _ , _ > = ( send, recv) . into ( ) ;
449449
450- let connect_msg = session. recv_request ( ) . await . context ( "recv ConnectRequest" ) ?;
450+ let connect_msg = tokio:: time:: timeout ( Duration :: from_secs ( 30 ) , session. recv_request ( ) )
451+ . await
452+ . context ( "session handshake timeout" ) ?
453+ . context ( "recv ConnectRequest" ) ?;
451454
452455 info ! (
453456 session_id = %connect_msg. session_id,
@@ -483,14 +486,14 @@ async fn run_session_proxy(advertise_subnets: Vec<Ipv4Network>, send: quinn::Sen
483486 let ( mut send, mut recv) = session. into_inner ( ) ;
484487 let ( mut tcp_read, mut tcp_write) = tcp_stream. into_split ( ) ;
485488
486- tokio :: select! {
487- r = tokio :: io :: copy ( & mut recv , & mut tcp_write ) => {
488- r . inspect_err ( |e| debug! ( %e , "QUIC->TCP copy ended" ) ) ? ;
489- }
490- r = tokio:: io:: copy( & mut tcp_read, & mut send) => {
491- r . inspect_err ( |e| debug! ( %e , "TCP->QUIC copy ended" ) ) ? ;
492- }
493- }
489+ // Use join! (not select!) to wait for BOTH directions to finish.
490+ // select! would cancel in-flight data when one direction closes first.
491+ let ( r1 , r2 ) = tokio :: join! (
492+ tokio :: io :: copy ( & mut recv , & mut tcp_write ) ,
493+ tokio:: io:: copy( & mut tcp_read, & mut send) ,
494+ ) ;
495+ r1 . inspect_err ( |e| debug ! ( %e , "QUIC->TCP copy ended" ) ) ? ;
496+ r2 . inspect_err ( |e| debug ! ( %e , "TCP->QUIC copy ended" ) ) ? ;
494497
495498 Ok ( ( ) )
496499 }
0 commit comments