@@ -555,6 +555,7 @@ async fn proxy_connected_stream_connection(
555555 options. upstream_proxy_protocol ,
556556 source,
557557 destination,
558+ options. idle_timeout ,
558559 )
559560 . await ?;
560561
@@ -658,15 +659,19 @@ async fn copy_bidirectional_with_limits(
658659 idle_timeout,
659660 ) . await ?;
660661 if bytes == 0 {
661- upstream_writer . shutdown ( ) . await ?;
662+ shutdown_with_idle_timeout ( & mut upstream_writer , idle_timeout ) . await ?;
662663 Ok :: <_, io:: Error >( StreamCopyEvent :: DownstreamEof )
663664 } else {
664665 let next = checked_stream_byte_count(
665666 downstream_to_upstream,
666667 bytes as u64 ,
667668 max_connection_bytes,
668669 ) ?;
669- upstream_writer. write_all( & downstream_buffer[ ..bytes] ) . await ?;
670+ write_with_idle_timeout(
671+ & mut upstream_writer,
672+ & downstream_buffer[ ..bytes] ,
673+ idle_timeout,
674+ ) . await ?;
670675 Ok :: <_, io:: Error >( StreamCopyEvent :: DownstreamTotal ( next) )
671676 }
672677 } , if !downstream_eof => result,
@@ -677,15 +682,19 @@ async fn copy_bidirectional_with_limits(
677682 idle_timeout,
678683 ) . await ?;
679684 if bytes == 0 {
680- downstream_writer . shutdown ( ) . await ?;
685+ shutdown_with_idle_timeout ( & mut downstream_writer , idle_timeout ) . await ?;
681686 Ok :: <_, io:: Error >( StreamCopyEvent :: UpstreamEof )
682687 } else {
683688 let next = checked_stream_byte_count(
684689 upstream_to_downstream,
685690 bytes as u64 ,
686691 max_connection_bytes,
687692 ) ?;
688- downstream_writer. write_all( & upstream_buffer[ ..bytes] ) . await ?;
693+ write_with_idle_timeout(
694+ & mut downstream_writer,
695+ & upstream_buffer[ ..bytes] ,
696+ idle_timeout,
697+ ) . await ?;
689698 Ok :: <_, io:: Error >( StreamCopyEvent :: UpstreamTotal ( next) )
690699 }
691700 } , if !upstream_eof => result,
@@ -719,6 +728,36 @@ where
719728 }
720729}
721730
731+ async fn write_with_idle_timeout < W > (
732+ writer : & mut W ,
733+ buffer : & [ u8 ] ,
734+ idle_timeout : Duration ,
735+ ) -> io:: Result < ( ) >
736+ where
737+ W : tokio:: io:: AsyncWrite + Unpin ,
738+ {
739+ match tokio:: time:: timeout ( idle_timeout, writer. write_all ( buffer) ) . await {
740+ Ok ( result) => result,
741+ Err ( _) => Err ( io:: Error :: new (
742+ io:: ErrorKind :: TimedOut ,
743+ "stream write timeout elapsed" ,
744+ ) ) ,
745+ }
746+ }
747+
748+ async fn shutdown_with_idle_timeout < W > ( writer : & mut W , idle_timeout : Duration ) -> io:: Result < ( ) >
749+ where
750+ W : tokio:: io:: AsyncWrite + Unpin ,
751+ {
752+ match tokio:: time:: timeout ( idle_timeout, writer. shutdown ( ) ) . await {
753+ Ok ( result) => result,
754+ Err ( _) => Err ( io:: Error :: new (
755+ io:: ErrorKind :: TimedOut ,
756+ "stream shutdown timeout elapsed" ,
757+ ) ) ,
758+ }
759+ }
760+
722761fn checked_stream_byte_count (
723762 current : u64 ,
724763 additional : u64 ,
@@ -793,42 +832,44 @@ async fn connect_tls_upstream(
793832 feature = "tls-s2n"
794833 ) ) ]
795834 {
796- let socket_addr = resolve_upstream_socket_addr ( upstream_authority) . await ?;
797- let sni = options
798- . upstream_sni
799- . as_deref ( )
800- . map ( str:: to_owned)
801- . or_else ( || upstream_host ( upstream_authority) )
802- . unwrap_or_default ( ) ;
803- let mut peer = HttpPeer :: new ( socket_addr, true , sni) ;
804- peer. options . connection_timeout = Some ( options. connect_timeout ) ;
805- peer. options . total_connection_timeout = Some ( options. connect_timeout ) ;
806- peer. options . verify_cert = options. upstream_verify_cert ;
807- peer. options . verify_hostname = options. upstream_verify_hostname ;
808- peer. options . alternative_cn = options
809- . upstream_alternative_cn
810- . as_deref ( )
811- . map ( str:: to_owned) ;
812- #[ cfg( any(
813- feature = "tls-rustls-backend" ,
814- feature = "tls-openssl" ,
815- feature = "tls-boringssl"
816- ) ) ]
817- {
818- peer. options . ca = options. upstream_tls_material . ca . clone ( ) ;
819- peer. client_cert_key = options. upstream_tls_material . client_cert_key . clone ( ) ;
820- }
821- let Some ( connector) = & options. connector else {
822- return Err ( io:: Error :: new (
823- io:: ErrorKind :: InvalidInput ,
824- "stream upstream TLS connector is not initialized" ,
825- ) ) ;
835+ let connect = async {
836+ let socket_addr = resolve_upstream_socket_addr ( upstream_authority) . await ?;
837+ let sni = stream_upstream_tls_sni ( options. upstream_sni . as_deref ( ) , upstream_authority) ;
838+ let mut peer = HttpPeer :: new ( socket_addr, true , sni) ;
839+ peer. options . connection_timeout = Some ( options. connect_timeout ) ;
840+ peer. options . total_connection_timeout = Some ( options. connect_timeout ) ;
841+ peer. options . verify_cert = options. upstream_verify_cert ;
842+ peer. options . verify_hostname = options. upstream_verify_hostname ;
843+ peer. options . alternative_cn = options
844+ . upstream_alternative_cn
845+ . as_deref ( )
846+ . map ( str:: to_owned) ;
847+ #[ cfg( any(
848+ feature = "tls-rustls-backend" ,
849+ feature = "tls-openssl" ,
850+ feature = "tls-boringssl"
851+ ) ) ]
852+ {
853+ peer. options . ca = options. upstream_tls_material . ca . clone ( ) ;
854+ peer. client_cert_key = options. upstream_tls_material . client_cert_key . clone ( ) ;
855+ }
856+ let Some ( connector) = & options. connector else {
857+ return Err ( io:: Error :: new (
858+ io:: ErrorKind :: InvalidInput ,
859+ "stream upstream TLS connector is not initialized" ,
860+ ) ) ;
861+ } ;
862+ connector
863+ . get_stream ( & peer)
864+ . await
865+ . map ( |( stream, _reused) | stream)
866+ . map_err ( |error| {
867+ io:: Error :: other ( format ! ( "stream upstream TLS connect failed: {error}" ) )
868+ } )
826869 } ;
827- match tokio:: time:: timeout ( options. connect_timeout , connector. get_stream ( & peer) ) . await {
828- Ok ( Ok ( ( stream, _reused) ) ) => Ok ( stream) ,
829- Ok ( Err ( error) ) => Err ( io:: Error :: other ( format ! (
830- "stream upstream TLS connect failed: {error}"
831- ) ) ) ,
870+
871+ match tokio:: time:: timeout ( options. connect_timeout , connect) . await {
872+ Ok ( result) => result,
832873 Err ( _) => Err ( io:: Error :: new (
833874 io:: ErrorKind :: TimedOut ,
834875 "stream upstream TLS connect timeout elapsed" ,
@@ -849,6 +890,22 @@ async fn connect_tls_upstream(
849890 }
850891}
851892
893+ #[ cfg( any(
894+ feature = "tls-rustls-backend" ,
895+ feature = "tls-openssl" ,
896+ feature = "tls-boringssl" ,
897+ feature = "tls-s2n"
898+ ) ) ]
899+ fn stream_upstream_tls_sni ( configured : Option < & str > , upstream_authority : & str ) -> String {
900+ configured
901+ . map ( str:: to_owned)
902+ . or_else ( || {
903+ let host = upstream_host ( upstream_authority) ?;
904+ host. parse :: < IpAddr > ( ) . is_err ( ) . then_some ( host)
905+ } )
906+ . unwrap_or_default ( )
907+ }
908+
852909async fn connect_upstream_inner ( upstream_authority : & str ) -> io:: Result < tokio:: net:: TcpStream > {
853910 let socket_addr = resolve_upstream_socket_addr ( upstream_authority) . await ?;
854911 tokio:: net:: TcpStream :: connect ( socket_addr) . await
@@ -873,6 +930,7 @@ async fn write_upstream_proxy_protocol(
873930 protocol : UpstreamProxyProtocol ,
874931 source : Option < SocketAddr > ,
875932 destination : Option < SocketAddr > ,
933+ idle_timeout : Duration ,
876934) -> io:: Result < ( ) > {
877935 let header = match protocol {
878936 UpstreamProxyProtocol :: Off => return Ok ( ( ) ) ,
@@ -883,7 +941,7 @@ async fn write_upstream_proxy_protocol(
883941 crate :: proxy_protocol:: proxy_protocol_v2_header ( source, destination)
884942 }
885943 } ;
886- upstream . write_all ( & header) . await
944+ write_with_idle_timeout ( upstream , & header, idle_timeout ) . await
887945}
888946
889947fn downstream_peer_addr ( downstream : & Stream ) -> Option < SocketAddr > {
0 commit comments