Purpose: Firestack is a VPN and network tunneling system that intercepts device traffic through a TUN device, processes it through a userspace TCP/IP stack (gVisor), and routes it through configurable DNS resolvers and proxy servers. The system provides advanced features including DNS Application Layer Gateway (ALG), NAT64, multiple proxy types (WireGuard, SOCKS5, HTTP), intelligent routing, and connection retry mechanisms.
Scope: This page provides a high-level architectural overview of the firestack codebase. For detailed information about specific subsystems, see:
Firestack implements a layered architecture where network traffic flows from the TUN device through the gVisor netstack to protocol handlers, which then consult DNS resolvers and proxy systems before establishing connections:
Overall Architecture Diagram
Sources: intra/tun2socks.go intra/tunnel.go126-137 tunnel/tunnel.go68-78 intra/common.go69-103 intra/tcp.go47-50 intra/udp.go44-47 intra/icmp.go25-27 intra/udpmux.go69-82 intra/dnsx/transport.go184-203 intra/dnsx/alg.go855-874 intra/dnsx/cacher.go92-108 intra/ipn/proxies.go227-263 intra/ipn/wgproxy.go98-151 intra/ipn/auto.go28-43
Firestack is composed of six major subsystems, each with well-defined responsibilities:
Entry Point: intra/tun2socks.go
The Connect() function in tun2socks.go serves as the main API, initializing:
NewTunnel() or NewTunnel2() for tunnel creationBridge interface implementation for callbacksKey Functions:
Connect(fd, mtu, ifaddrs, fakedns, dtr, bdg) - Primary initializationLogLevel(), SetDnsMode(), ExperimentalWireGuard() - Runtime configurationSources: intra/tun2socks.go intra/tunnel.go153-157
Implementation: Two-tier abstraction
High-Level Orchestrator (rtunnel struct):
dnsx.Resolver, ipn.Proxies, and rnet.ServicesSetLinkAndRoutes(), Restart(), CloseConns()Low-Level Tunnel (gtunnel struct):
stack.StackSeamlessEndpoint for TUN ↔ netstack bridgingKey Types:
rtunnel struct {
t *core.Volatile[tunnel.Tunnel]
handlers netstack.GConnHandler
proxies ipn.Proxies
resolver dnsx.Resolver
}
gtunnel struct {
stack *stack.Stack
ep netstack.SeamlessEndpoint
hdl netstack.GConnHandler
}
Sources: intra/tunnel.go126-137 tunnel/tunnel.go68-78 intra/netstack/netstack.go30-55
Architecture: Shared base + protocol-specific implementations
Protocol Handler Flow
baseHandler (intra/common.go69-103):
onFlow(src, dst) - Calls gateway.X() to undo ALG, retrieves domains/IPsonInflow(to, from) - Handles reverse proxy flowsjudge(res) - Determines cid, uid, fid, pids from policy marksisDNS(target) - Checks if target is a fake DNS addressdnsOverride(gconn, uid) - Redirects DNS queries to resolver.Serve()processSummaries() - Forwards SocketSummary to listener.OnSocketClosed()tcpHandler (intra/tcp.go47-50):
Proxy(gconn, src, target) - Main TCP connection handlerhandle(px, gconn, src, dst, ...) - Dials via proxy with retrierforward(gconn, remote, smm) - Bidirectional data copy with statstcpNat for port mapping trackingudpHandler (intra/udp.go44-47):
Proxy(gconn, src, dst) and ProxyMux(gconn, src, dst, dmx) - UDP handlersConnect(gconn, src, target, dmx) - Establishes UDP associationforward(gconn, remote, smm) - Handles datagram forwardingmuxTable for endpoint-independent mappingicmpHandler (intra/icmp.go25-27):
Ping(msg, source, target) - Handles ICMP echo requestsUDP Multiplexing (intra/udpmux.go69-82):
muxTable - Maps local endpoints to proxy IDsmuxer - Multiplexes connections over net.PacketConndemuxconn - Demultiplexed per-remote connectionSources: intra/common.go69-103 intra/tcp.go47-127 intra/udp.go44-89 intra/icmp.go25-40 intra/udpmux.go69-223
Core Architecture:
| Component | File | Purpose |
|---|---|---|
resolver | dnsx/transport.go184-203 | Transport orchestrator, handles Add(), Remove(), forward() |
dnsgateway | dnsx/alg.go855-874 | ALG/NAT64 engine, synthetic IP generation |
ctransport | dnsx/cacher.go92-108 | Per-transport caching with TTL extension |
| Transport types | Various | DoH, DoT, DNS53, DNSCrypt, ODoH, mDNS implementations |
resolver struct key methods:
forward(q, uid, chosenids...) - Main query processingAdd(dt DNSTransport) - Registers new transportServe(proto, conn, uid) - Handles TCP/UDP DNS queriesdetermineTransport(id) - Selects transport by IDdnsgateway struct key methods:
q(t1, t2, preset, network, uid, q, smm) - Dual-transport query with ALGX(maybeAlg, uid, tids...) - Undoes ALG translationPTR(maybeAlg, uid, tid, force) - Reverse lookupRESOLV(domain, uid, tid) - Forward lookupSynthetic IP Ranges:
100.64.0.0/10 (RFC 6598)64:ff9b:1:da19::/96 (RFC 8215a variant)Sources: intra/dnsx/transport.go184-242 intra/dnsx/alg.go855-949 intra/dnsx/cacher.go92-178
Core Orchestrator: proxifier struct (intra/ipn/proxies.go227-263)
Proxy Type Hierarchy
proxifier struct manages:
p map[string]Proxy - All registered proxiesrp map[string]RpnProxy - Main RPN proxieshp map[string][]string - Hop relationships (proxy chaining)ipPins *core.Sieve - IP → proxyid pinninguidPins *core.Sieve2K - uid → [dst → proxyid] pinningKey Methods:
ProxyTo(ipp, uid, pids) - Selects proxy based on pinning, health, routesAddProxy(id, txt) - Registers new proxy from configurationHop(via, origin) - Sets up proxy chainingRefreshProto(l3, mtu, force) - Broadcasts link property changesauto proxy (intra/ipn/auto.go28-43) implements intelligent selection:
exit or RPN proxiesSources: intra/ipn/proxies.go227-333 intra/ipn/wgproxy.go98-172 intra/ipn/auto.go28-115 intra/ipn/proxy.go43-155
Key Components:
| Component | Location | Responsibility |
|---|---|---|
retrier | intra/dialers/ | Transparent retry with TCP splitting/desync |
IPMap/IPMapper | intra/protect/ipmap/ | Hostname→IP caching with confirmation |
protect.Controller | intra/protect/ | Network binding, socket protection |
dialers.RDialer | intra/dialers/ | Dialer abstractions with retry |
Connection Retry Flow:
retrier attempts initial connectionIPMap.Disconfirm() invalidates failed IPIPMap.Confirm() validates successful IPSources: intra/dialers/ intra/protect/ipmap/ intra/protect/
The following diagram traces a typical connection from application to internet:
Key decision points:
baseHandler.isDNS() + baseHandler.dnsOverride()): Intercepts DNS queries to tunnel's fake DNS addresseslistener.Preflow() + listener.Flow()): Determines blocking/routing rules based on UID, source, destinationproxifier.ProxyTo()): Chooses proxy based on pinning, health, and configurationdialers.ResolveFor() + gateway.X()): Resolves hostnames and undoes ALG translationsretrier): Implements TCP splitting and retry strategiesSources: intra/common.go132-227 intra/tcp.go240-364 intra/udp.go168-386 intra/ipn/proxies.go448-637 intra/dialers
Handler Interface Structure
Key Methods:
GBaseConnHandler: onFlow(), judge(), isDNS(), dnsOverride()GTCPConnHandler: Proxy(), ReverseProxy(), Error()GUDPConnHandler: Proxy(), ProxyMux(), ReverseProxy(), Error(), Connect()GICMPHandler: Ping()Sources: intra/netstack/ intra/common.go69-103 intra/tcp.go47-50 intra/udp.go44-47 intra/icmp.go25-27
Proxy Interface Relationships
Proxy interface required methods (intra/ipn/proxies.go165-186):
Dial(network, address), DialBind(network, local, remote)Announce(network, local), Accept(network, local)Hop(p Proxy, dryrun), Refresh(), Ping()Status(), Stop(), GetAddr(), onNotOK()Sources: intra/ipn/proxies.go165-186 intra/ipn/proxy.go43-155 intra/ipn/wgproxy.go160-172 intra/ipn/auto.go28-43
DNS Component Relationships
Key Types:
resolver struct (dnsx/transport.go184-203): Transport orchestratordnsgateway struct (dnsx/alg.go855-874): ALG/NAT64 enginectransport struct (dnsx/cacher.go92-108): Caching wrapperalgans struct (dnsx/alg.go796-799): ALG IP → real IPs + domainsxips struct (dnsx/alg.go194-201): Primary/secondary IP storageSources: intra/dnsx/transport.go164-203 intra/dnsx/alg.go83-102 intra/dnsx/alg.go796-874 intra/dnsx/cacher.go65-108
Sources: intra/tcp.go240-364 intra/common.go132-311 intra/dnsx/transport.go505-718 intra/ipn/proxies.go448-637 intra/ipn/wgproxy.go189-193
Firestack is designed as a cross-platform library that can be embedded into mobile applications (Android/iOS) and desktop systems (Linux/Windows) through Go Mobile bindings.
Build Artifacts by Platform:
| Platform | Artifact Type | Output Path | Build Tool |
|---|---|---|---|
| Android | AAR (Android Archive) | intra/tun2socks.aar | gomobile bind |
| iOS | XCFramework | Tun2socks.xcframework | gomobile bind |
| Linux | Binary | tun2socks (ELF) | xgo |
| Windows | Binary | tun2socks.exe (PE) | xgo |
Bridge Interface Contract
The Bridge interface (intra/tunnel.go61-67) defines the integration contract:
Bridge interface {
Listener // SocketListener, DNSListener, ServerListener, ProxyListener
Controller // protect.Controller for network binding
Console // Logging callbacks
}
Listener Callbacks:
SocketListener (intra/listener.go19-66): OnSocketClosed(summary)DNSListener: OnQuery(), OnUpstreamAnswer(), OnResponse()ProxyListener: OnProxyAdded(), OnProxyRemoved(), OnProxyStopped()Controller Methods (intra/protect/):
Protect(fd) - Exempts socket from VPN routingBind(fd, network) - Binds socket to specific network interfaceSources: Makefile .github/workflows/go.yml intra/tunnel.go61-74 intra/listener.go19-66 intra/protect/
The system maintains several categories of state:
baseHandler.conntracker (connid → [local, remote])proxifier with maps for proxies, RPN proxies, and hop relationshipsdnsgateway ALG/NAT/PTR maps and ctransport cachesipmap.IPMap with confirmation/disconfirmation feedback loopsAll mutable state uses appropriate synchronization primitives (sync.RWMutex, atomic, core.Volatile).
Sources: intra/common.go99 intra/ipn/proxies.go232-240 intra/dnsx/alg.go856-862 intra/protect/ipmap
This overview provides the foundation for understanding firestack's architecture. For detailed information about each subsystem, refer to the linked sections.
Refresh this wiki
This wiki was recently refreshed. Please wait 6 days to refresh again.