Source: Dev.to | Jan 21, 2026 (UTC)
TL;DR:
My transparent proxy was architecturally correct, fully implemented, and thoroughly tested — yet it silently failed on Wi-Fi. The reason wasn’t a bug, a missing flag, or bad code. It was a Windows + Wi-Fi driver boundary that user-mode tools like WinDivert simply cannot cross.
This article documents the journey, the dead ends, the hard evidence, and the final, correct conclusion.
I was building a transparent TCP proxy on Windows using:
- Rust
- WinDivert (user-mode packet capture/injection)
- SOCKS5 upstream
- Full DNAT / SNAT redirection
- No explicit proxy configuration on the client
The goal was simple:
Intercept outbound TCP connections (ports 80/443), transparently redirect them to a local proxy, and forward traffic upstream — without breaking applications or TCP semantics.
This is a solved problem on Linux (iptables + REDIRECT).
On Windows, it’s much harder.
Phase 1: The Wrong Idea (Packet Forging)
The initial design attempted to:
- Intercept outbound SYN packets
- Drop them
- Forge a SYN-ACK pretending to be the real server
- Maintain a user-space TCP state machine
- Relay data via SOCKS5
On paper, everything worked:
- Correct TCP flags
- Correct SEQ/ACK numbers
- Correct IP + TCP checksums
- Verified hex dumps
- Passing unit tests
Reality:
Windows silently dropped every forged SYN-ACK.
No ACK.
No handshake.
No error.
Windows enforces TCP anti-spoofing below WinDivert.
User-mode code cannot inject packets claiming to originate from external IPs and expect the TCP stack to accept them.
This is not configurable.
No WinDivert layer fixes this.
Not Impostor, not REFLECT, not FORWARD.
Conclusion:
Forging TCP peers in user mode on Windows is architecturally impossible.
Phase 2: The Correct Architecture (Redirection)
After discarding packet forging entirely, I implemented the only correct approach:
Transparent Redirection (DNAT / SNAT)
- Intercept outbound SYN
- Record original destination
(dst_ip, dst_port) - Rewrite destination →
LOCAL_IP:8899 - Flip packet direction to INBOUND
- Let Windows complete a real TCP handshake
- Proxy connects upstream via SOCKS5
- Rewrite source on return packets back to original server
- Flip direction to OUTBOUND
- Clean up mappings on FIN/RST
Key rules:
- No forged packets
- No custom TCP state machine
- Windows owns TCP semantics
This is how all real transparent proxies work on Windows.
Everything Was Correct — Yet Nothing Worked
Even with the correct architecture:
-
curlhung - No outbound SYN visible
- WinDivert captured only inbound packets
-
Outbound=1never appeared -
NETWORK_FORWARDlayer captured nothing - Filters were correct
- Injection logic was correct
At this point, the usual suspects were gone.
The Critical Discovery: Wi-Fi Fast-Path
The system used an Intel Wi-Fi adapter.
After exhaustive testing:
- WinDivert never saw outbound TCP packets
- Even with filter
"tcp" - Even after disabling all configurable offloads
- Even after restarting the adapter
- Even at different WinDivert layers
PowerShell confirmed it:
Get-NetAdapterAdvancedProperty -Name "Wi-Fi"
Enter fullscreen mode
Exit fullscreen mode


Залишити відповідь