Turkish ISPs are doing some interesting things. They don't just block domains at DNS level — they actually inspect your TLS handshake to see where you're connecting. This is called DPI, deep packet inspection. So even if you use a different DNS server, they can still see the SNI field in your ClientHello and block you.
Discord got blocked in Turkey on October 9, 2024. I wasn't in a rush at first — I had a VPN, I wasn't panicking. People around me were just installing GoodByeDPI and moving on. I tried to understand what GoodByeDPI was actually doing instead of just running it.
That question pulled me into a rabbit hole. I started reading about how BGP works, how ISPs route traffic, how the internet actually moves data at a physical level. The more I read the more I realized these massive ISP servers — as big and powerful as they are — have limits. They can't hold state forever. They can't wait indefinitely to reassemble packets just to inspect them.
So I started thinking about DNS first. Turkish ISPs were poisoning DNS responses — you ask for discord.com, they give you a fake IP. I solved that part with Cloudflare DoH, DNS over HTTPS. Now I could get the real IP. But it still didn't work. The connection was getting dropped anyway.
That's when I understood the SNI problem. The ClientHello packet — the very first thing your browser sends in a TLS handshake — contains the SNI field in plaintext. It's basically your browser announcing "I want to talk to discord.com" before any encryption happens. The ISP firewall reads this and drops the connection. Real IP didn't matter.
The fix came from the same logic I used to understand the servers. If I split the ClientHello across enough TCP segments, the stateful firewall has to wait and reassemble them all before it can read the SNI. At some point it just gives up and lets the traffic through. The data is all there, just fragmented.
I started with 2 chunks. Didn't work. Increased it. At around 4–5 chunks Discord started loading. I still remember that moment — one F5 and discord.com just opened. No VPN, no GoodByeDPI, nothing. I felt like I found the internet.
I set the default to 7 in the end. Tested it against a few different domains and it worked consistently. The sweet spot where the firewall gives up but performance doesn't suffer. And since I was only touching the ClientHello — the very first packet — I didn't need to worry about optimization for the rest of the connection. After the handshake I'm in TLS territory, traffic flows normally.
I built it in Go. I had maybe 2–3 small Go projects before this — a Hello World, a CRUD app, a simpler version of my ping-tracker. Go was still relatively new for me but I already knew what I wanted to build, so the language was just a tool. The proxy intercepts HTTPS connections, resolves DNS via DoH, fragments the ClientHello, and forwards everything else unchanged. It also sets itself as the system proxy on start and cleans up on exit.
I considered WinDivert for Windows support — kernel-level packet interception. But ZenRoute only touches the ClientHello, everything else flows normally. So it's already optimized where it matters. WinDivert was a big dependency for a tool that was supposed to be small. System proxy level is enough.
One honest limitation: some sites in Turkey are blocked at the IP level, not via DPI. For those, fragmentation does nothing. You need a relay server outside Turkey. ZenRoute can't help there and I say so in the README.
The whole thing is open source. I built it to understand something, then realized it actually worked, then kept using it every day.