Ported only the fixes that actually apply to the pre-refactor base
(the handshake fixes 6eb7b36/d65af35 fix bugs the 0.3.1 multi-server
refactor introduced into the new outbounds/ostp.rs; the base bridge.rs
already waits for the handshake response with retransmit + NAT64
fallback, so they are intentionally skipped).
- EMFILE (922cf0b): rlimit::increase_nofile_limit at CLI startup.
- Logs (1151726): UoT connect/disconnect → debug; rate-limit the
unauthorized-probe log to one line / ~30s so a junk/probe flood can't
spam the log (and a client running junk-over-UDP can't self-ban).
- Helper lifecycle + bypass routes (b6e78c1):
* ostp-tun-helper forces std::process::exit(0) after run_server so the
WinTun adapter and its metric-0 default route are reclaimed instead
of lingering as a zombie that breaks the next connect.
* windows_route: delete_routes_for_dest() purges stale /32s, dedupe
bypass IPs, and log add failures at warn!.
* windows: retry tun::create through the transient ERROR_INVALID_
PARAMETER window and widen the adapter-index lookup to ~15s.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The core bug: server sent 5 TLS records in server_hello but client only
read the first one (ServerHello), then passed remaining bytes (CCS + fake
records) into RealityStream. RealityStream saw 0x14 (CCS) != 0x17 and
immediately returned an error, killing the connection.
Changes:
- reality.rs: append ChangeCipherSpec after ClientHello (RFC 8446 D.4)
export REALITY_SERVER_HANDSHAKE_RECORDS=5 constant
- xhttp.rs: drain all 5 server handshake records before creating RealityStream
- uot.rs: rebuild server_hello as proper 5-record TLS 1.3 flight:
ServerHello + CCS + fake EE (108B) + fake Cert (812B) + fake Fin (52B)
drain client CCS from raw stream before wrapping in RealityStream