diff --git a/src/config/load.rs b/src/config/load.rs index 55f38ca..1e455b8 100644 --- a/src/config/load.rs +++ b/src/config/load.rs @@ -640,12 +640,6 @@ impl ProxyConfig { )); } - if config.censorship.mask_relay_max_bytes == 0 { - return Err(ProxyError::Config( - "censorship.mask_relay_max_bytes must be > 0".to_string(), - )); - } - if config.censorship.mask_relay_max_bytes > 67_108_864 { return Err(ProxyError::Config( "censorship.mask_relay_max_bytes must be <= 67108864".to_string(), diff --git a/src/config/types.rs b/src/config/types.rs index 96232bd..f422e4e 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -1768,6 +1768,7 @@ pub struct AntiCensorshipConfig { pub mask_shape_above_cap_blur_max_bytes: usize, /// Maximum bytes relayed per direction on unauthenticated masking fallback paths. + /// Set to 0 to disable byte cap (unlimited within relay/idle timeouts). #[serde(default = "default_mask_relay_max_bytes")] pub mask_relay_max_bytes: usize, diff --git a/src/proxy/masking.rs b/src/proxy/masking.rs index d49e4c3..c48ec9c 100644 --- a/src/proxy/masking.rs +++ b/src/proxy/masking.rs @@ -60,21 +60,18 @@ where let mut buf = Box::new([0u8; MASK_BUFFER_SIZE]); let mut total = 0usize; let mut ended_by_eof = false; - - if byte_cap == 0 { - return CopyOutcome { - total, - ended_by_eof, - }; - } + let unlimited = byte_cap == 0; loop { - let remaining_budget = byte_cap.saturating_sub(total); - if remaining_budget == 0 { - break; - } - - let read_len = remaining_budget.min(MASK_BUFFER_SIZE); + let read_len = if unlimited { + MASK_BUFFER_SIZE + } else { + let remaining_budget = byte_cap.saturating_sub(total); + if remaining_budget == 0 { + break; + } + remaining_budget.min(MASK_BUFFER_SIZE) + }; let read_res = timeout(idle_timeout, reader.read(&mut buf[..read_len])).await; let n = match read_res { Ok(Ok(n)) => n, @@ -930,21 +927,21 @@ async fn consume_client_data( byte_cap: usize, idle_timeout: Duration, ) { - if byte_cap == 0 { - return; - } - // Keep drain path fail-closed under slow-loris stalls. let mut buf = Box::new([0u8; MASK_BUFFER_SIZE]); let mut total = 0usize; + let unlimited = byte_cap == 0; loop { - let remaining_budget = byte_cap.saturating_sub(total); - if remaining_budget == 0 { - break; - } - - let read_len = remaining_budget.min(MASK_BUFFER_SIZE); + let read_len = if unlimited { + MASK_BUFFER_SIZE + } else { + let remaining_budget = byte_cap.saturating_sub(total); + if remaining_budget == 0 { + break; + } + remaining_budget.min(MASK_BUFFER_SIZE) + }; let n = match timeout(idle_timeout, reader.read(&mut buf[..read_len])).await { Ok(Ok(n)) => n, Ok(Err(_)) | Err(_) => break, @@ -955,7 +952,7 @@ async fn consume_client_data( } total = total.saturating_add(n); - if total >= byte_cap { + if !unlimited && total >= byte_cap { break; } }