@@ -19,8 +19,10 @@ use fluxheim_protocol::{
1919} ;
2020use tokio:: io:: { AsyncRead , AsyncReadExt as _, AsyncWrite , AsyncWriteExt as _} ;
2121
22+ mod copy;
2223mod selector;
2324
25+ pub use copy:: { checked_stream_byte_count, copy_bidirectional_with_limits} ;
2426pub use selector:: { StreamSelectedUpstream , StreamUpstreamSelector } ;
2527
2628#[ derive( Debug , Clone , Eq , PartialEq ) ]
@@ -140,6 +142,9 @@ fn stream_dns_resolved_ipv4_address_allowed(address: Ipv4Addr) -> bool {
140142}
141143
142144fn stream_dns_resolved_ipv6_address_allowed ( address : Ipv6Addr ) -> bool {
145+ if let Some ( address) = address. to_ipv4 ( ) {
146+ return stream_dns_resolved_ipv4_address_allowed ( address) ;
147+ }
143148 let segments = address. segments ( ) ;
144149 !( address. is_unspecified ( )
145150 || address. is_loopback ( )
@@ -172,115 +177,6 @@ pub fn stream_error_outcome(error: &FluxError) -> &'static str {
172177 }
173178}
174179
175- pub fn checked_stream_byte_count (
176- current : u64 ,
177- additional : u64 ,
178- max_connection_bytes : Option < u64 > ,
179- ) -> FluxResult < u64 > {
180- let next = current. checked_add ( additional) . ok_or_else ( || {
181- FluxError :: io (
182- "count stream bytes" ,
183- io:: Error :: new (
184- io:: ErrorKind :: InvalidData ,
185- "stream copied byte counter overflowed" ,
186- ) ,
187- )
188- } ) ?;
189- if max_connection_bytes. is_some_and ( |limit| next > limit) {
190- return Err ( FluxError :: io (
191- "enforce stream byte limit" ,
192- io:: Error :: new (
193- io:: ErrorKind :: PermissionDenied ,
194- "stream max connection bytes exceeded" ,
195- ) ,
196- ) ) ;
197- }
198- Ok ( next)
199- }
200-
201- enum StreamCopyEvent {
202- DownstreamTotal ( u64 ) ,
203- UpstreamTotal ( u64 ) ,
204- DownstreamEof ,
205- UpstreamEof ,
206- }
207-
208- pub async fn copy_bidirectional_with_limits (
209- downstream : & mut ( impl AsyncRead + AsyncWrite + Unpin ) ,
210- upstream : & mut ( impl AsyncRead + AsyncWrite + Unpin ) ,
211- idle_timeout : Duration ,
212- max_connection_bytes : Option < u64 > ,
213- ) -> FluxResult < ( u64 , u64 ) > {
214- let ( mut downstream_reader, mut downstream_writer) = tokio:: io:: split ( downstream) ;
215- let ( mut upstream_reader, mut upstream_writer) = tokio:: io:: split ( upstream) ;
216- let mut downstream_buffer = [ 0u8 ; 16 * 1024 ] ;
217- let mut upstream_buffer = [ 0u8 ; 16 * 1024 ] ;
218- let mut downstream_to_upstream = 0u64 ;
219- let mut upstream_to_downstream = 0u64 ;
220- let mut downstream_eof = false ;
221- let mut upstream_eof = false ;
222-
223- while !downstream_eof || !upstream_eof {
224- let event = tokio:: select! {
225- result = async {
226- let bytes = read_with_idle_timeout(
227- & mut downstream_reader,
228- & mut downstream_buffer,
229- idle_timeout,
230- ) . await ?;
231- if bytes == 0 {
232- shutdown_with_idle_timeout( & mut upstream_writer, idle_timeout) . await ?;
233- Ok :: <_, FluxError >( StreamCopyEvent :: DownstreamEof )
234- } else {
235- let next = checked_stream_byte_count(
236- downstream_to_upstream,
237- bytes as u64 ,
238- max_connection_bytes,
239- ) ?;
240- write_with_idle_timeout(
241- & mut upstream_writer,
242- & downstream_buffer[ ..bytes] ,
243- idle_timeout,
244- ) . await ?;
245- Ok :: <_, FluxError >( StreamCopyEvent :: DownstreamTotal ( next) )
246- }
247- } , if !downstream_eof => result,
248- result = async {
249- let bytes = read_with_idle_timeout(
250- & mut upstream_reader,
251- & mut upstream_buffer,
252- idle_timeout,
253- ) . await ?;
254- if bytes == 0 {
255- shutdown_with_idle_timeout( & mut downstream_writer, idle_timeout) . await ?;
256- Ok :: <_, FluxError >( StreamCopyEvent :: UpstreamEof )
257- } else {
258- let next = checked_stream_byte_count(
259- upstream_to_downstream,
260- bytes as u64 ,
261- max_connection_bytes,
262- ) ?;
263- write_with_idle_timeout(
264- & mut downstream_writer,
265- & upstream_buffer[ ..bytes] ,
266- idle_timeout,
267- ) . await ?;
268- Ok :: <_, FluxError >( StreamCopyEvent :: UpstreamTotal ( next) )
269- }
270- } , if !upstream_eof => result,
271- } ?;
272-
273- match event {
274- StreamCopyEvent :: DownstreamTotal ( total) => downstream_to_upstream = total,
275- StreamCopyEvent :: UpstreamTotal ( total) => upstream_to_downstream = total,
276- StreamCopyEvent :: DownstreamEof => downstream_eof = true ,
277- StreamCopyEvent :: UpstreamEof => upstream_eof = true ,
278- }
279- }
280-
281- Ok ( ( downstream_to_upstream, upstream_to_downstream) )
282- }
283-
284180pub async fn write_upstream_proxy_protocol (
285181 upstream : & mut ( impl AsyncWrite + Unpin ) ,
286182 protocol : UpstreamProxyProtocol ,
@@ -414,19 +310,6 @@ where
414310 }
415311}
416312
417- async fn shutdown_with_idle_timeout < W > ( writer : & mut W , idle_timeout : Duration ) -> FluxResult < ( ) >
418- where
419- W : AsyncWrite + Unpin ,
420- {
421- match tokio:: time:: timeout ( idle_timeout, writer. shutdown ( ) ) . await {
422- Ok ( result) => result. map_err ( |error| FluxError :: io ( "shutdown stream" , error) ) ,
423- Err ( _) => Err ( FluxError :: timeout (
424- "stream shutdown timeout" ,
425- "stream shutdown timeout elapsed" ,
426- ) ) ,
427- }
428- }
429-
430313async fn read_exact_with_idle_timeout < R > (
431314 reader : & mut R ,
432315 buffer : & mut [ u8 ] ,
0 commit comments