Conflict resolution:
- src/config/load.rs: Merge HEAD's is_safe_include_path (path traversal guard)
with upstream/flow's LoadedConfig, normalize_config_path, hash_rendered_snapshot,
and the new 4-parameter preprocess_includes signature. Update two test call
sites that still used the old 3-arg signature.
- src/config/hot_reload.rs: Take upstream/flow's tokio::spawn-contained watcher
setup (inotify + poll via manifest_state). HEAD's pre-spawn block was broken:
it referenced notify_tx before the channel was created.
Copilot review fixes (already applied in working tree, now committed):
- src/transport/pool.rs: Handle EINTR in is_connection_alive with retry loop
(treating it as alive) instead of a false dead-connection verdict.
- src/transport/middle_proxy/wire.rs: On u32 overflow in extra-block length
encoding, truncate buffer back to the length-field position and write 0 so wire
representation stays self-consistent. Annotate 16 MiB boundary tests with
#[ignore] to avoid OOM on low-memory CI runners.
- src/stream/buffer_pool.rs: Restore fail-fast expect() in Deref/DerefMut (was
silently returning empty buffer after take(), masking use-after-take bugs).
Add MAX_POOL_BUFFER_OVERSIZE_MULT upper bound in return_buffer to prevent
memory amplification from excessively-grown buffers staying in the pool.
Fix contradictory test: oversized_buffer_is_returned_to_pool now grows within
the 4x bound; oversized_buffer_is_dropped_not_pooled (8x growth) now passes.
- src/api/mod.rs: Fix constant_time_eq to iterate over b.len() (expected token
length) rather than min(a.len(), b.len()), closing the timing oracle where an
attacker could influence iteration count by sending a shorter candidate
(OWASP ASVS V6.6.1). Revert ApiRuntimeState and ApiShared to pub(super).
- src/protocol/obfuscation.rs: Replace no-op test_obfuscation_params_is_not_clone
with static_assertions::assert_not_impl_any!(ObfuscationParams: Clone) which
is an actual compile-time enforcement.
- Remove unused imports across multiple modules
- Add #![allow(dead_code)] for public API items preserved for future use
- Add #![allow(deprecated)] for rand::Rng::gen_range usage
- Add #![allow(unused_assignments)] in main.rs
- Add #![allow(unreachable_code)] in network/stun.rs
- Prefix unused variables with underscore (_ip_tracker, _prefer_ipv6)
- Fix unused_must_use warning in tls_front/cache.rs
This ensures clean compilation without warnings while preserving
public API items that may be used in the future.
- Fixed tests that failed to compile due to mismatched generic parameters of HandshakeResult:
- Changed `HandshakeResult<i32>` to `HandshakeResult<i32, (), ()>`
- Changed `HandshakeResult::BadClient` to `HandshakeResult::BadClient { reader: (), writer: () }`
- Added Zeroize for all structures holding key material:
- AesCbc – key and IV are zeroized on drop
- SecureRandomInner – PRNG output buffer is zeroized on drop; local key copy in constructor is zeroized immediately after being passed to the cipher
- ObfuscationParams – all four key‑material fields are zeroized on drop
- HandshakeSuccess – all four key‑material fields are zeroized on drop
- Added protocol‑requirement documentation for legacy hashes (CodeQL suppression) in hash.rs (MD5/SHA‑1)
- Added documentation for zeroize limitations of AesCtr (opaque cipher state) in aes.rs
- Implemented silent‑mode logging and refactored initialization:
- Added LogLevel enum to config and CLI flags --silent / --log-level
- Added parse_cli() to handle --silent, --log-level, --help
- Restructured main.rs initialization order: CLI → config load → determine log level → init tracing
- Errors before tracing initialization are printed via eprintln!
- Proxy links (tg://) are printed via println! – always visible regardless of log level
- Configuration summary and operational messages are logged via info! (suppressed in silent mode)
- Connection processing errors are lowered to debug! (hidden in silent mode)
- Warning about default tls_domain moved to main (after tracing init)
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>