$ show SadeghHayeri/GreenTunnel
GreenTunnel is a local proxy that bypasses DPI (Deep Packet Inspection) censorship by fragmenting the TLS ClientHello so the SNI never appears whole in a single packet, and by resolving DNS over encrypted channels (DoH/DoT). It is a ground-up TypeScript rewrite of the original GreenTunnel, fixing numerous bugs from v2 (backpressure, timeouts, HTTP framing corruption, DNS cache expiry, system proxy crash safety). The repository is a monorepo containing a core engine library, a CLI tool (`gt`), and an Electron desktop app. The engine implements a full HTTP/HTTPS proxy with TLS fragmentation, HTTP request rewriting (absolute-form to origin-form), a caching DNS resolver with TTL-based expiration and in-flight deduplication, and a system-proxy management layer with snapshot/restore and crash recovery. The desktop app provides a 340px frameless window with a live log panel (virtual list), tray integration, and non-intrusive advocacy prompts. The codebase is exceptionally well-documented (CLAUDE.md serves as the authoritative design document), uses modern Node.js features (parseArgs, styleText, pipeline), and has a strong emphasis on correctness and edge-case handling (e.g., stranded proxy detection, HTTP framing awareness, signal handling for clean shutdown).
The LLM identified 8 files worth highlighting for reuse:
Detects TLS ClientHello and splits it into multiple TCP segments or valid TLS records so no single packet contains the complete SNI, evading DPI inspection. Supports two strategies: TCP split (simple byte chopping) and record split (re-framing as valid TLS records per RFC 8446 ยง5.1). Non-TLS traffic is passed through unchanged. The module is self-contained, well-tested, and could be extracted into a standalone library for TLS fragmentation.
A state-machine-based HTTP request rewriter that correctly handles keep-alive connections by tracking Content-Length and chunked transfer encoding to identify request boundaries. Converts absolute-form request targets to origin-form for upstream servers, drops proxy-only headers, and synthesizes Host headers when missing. Unlike naive line-by-line parsers, it does not corrupt binary bodies that happen to contain method-like strings. Includes a stream wrapper for use in pipelines.
Abstract caching DNS resolver with TTL-based expiration (clamped to configurable min/max), in-flight request deduplication to collapse concurrent lookups for the same hostname, and IPv4/IPv6 family preference ordering. Uses an LRU cache with per-entry TTL. The base class provides the caching and concurrency logic; subclasses implement the actual query method for different DNS transports (DoH, DoT, plain). Reusable pattern for any application needing a smart DNS resolver.
macOS system proxy driver that manages proxy settings across all network services using networksetup. Implements snapshot/restore pattern with careful handling of edge cases: applies changes only to services captured in the snapshot (avoiding stranded proxies on newly connected interfaces), restores both HTTP and HTTPS endpoints independently, preserves bypass lists, and uses a settle function to attempt restoration on all services even if some fail. Includes crash recovery via a persisted snapshot file.
Crash recovery module for system proxy settings. Persists a snapshot of the OS proxy configuration to disk before making changes, so that if the process is killed (SIGKILL, power loss), the next launch can detect and undo the orphaned proxy. Includes validation of the persisted file (platform check, PID liveness check) to prevent restoring a snapshot that belongs to a still-running instance or a different OS. The file path is shared between CLI and desktop app for cross-tool recovery.
A bounded ring buffer (5000 entries) for collecting log records from the engine, with batched emission to the UI (~120ms intervals) to avoid flooding IPC with individual messages. Deliberately independent of the engine lifecycle so that log history survives tunnel restarts. Supports clear and provides a dropped count when entries overflow. The buffer is the sole sink for the engine's logger and feeds the log panel's virtual list.
A minimal (~40 lines) typed JSON store for persisting application settings and state. Writes to a temporary file then renames into place to prevent corruption from crashes mid-write. Provides a normalize function to validate and clamp values from disk, treating corrupt or missing files as empty objects rather than failing to boot. Used for settings, window state, and advocacy state.
Schedules non-intrusive 'star or share' prompts with relative delays (3 days, then 27, then 60) measured from the previous prompt rather than absolute deadlines, preventing a burst of prompts for users who open the app infrequently. Tracks state (first run, last prompt, helped/dismissed) in a JSON store. The prompt is only shown when the window is visible and has settled, and the slot is consumed only when the prompt is actually displayed. Three asks ever, then retired.