MULTI-CIRCUIT TOR PARALLEL DOWNLOADER · x64 + ARM64 10 CIRCUIT WORKERS HTTP RANGE STREAM Tor 0.4.9.11 EMBED NATIVE ARM64 + x64 2.64 MiB STANDALONE C++23 / WINAPI ONION DOWNLOADER MULTI-CIRCUIT TOR PARALLEL DOWNLOADER · x64 + ARM64
Download od.7z   Download od.zip   Download Source Code   Source on GitHub ARCHIVE PASSWORD: github.com

2026-11-01 - Anti-DDoS PoW Gate solver, per-worker circuit isolation, sparse NTFS allocation, ARM64 target

Onion Downloader combines a native graphical queue and a complete command-line downloader in one
2.64 MiB (2,771,456-byte) Windows executable. Its original HTTP, SOCKS5, range scheduling and resume engines spread
one file over multiple independent Tor circuits. An in-process pure C++ SHA-256 Proof-of-Work (PoW) solver (5–15 ms)
defeats modern Onion anti-DDoS challenge gates (/_gate/challenge / /_gate/verify), and per-worker session cookie isolation
bypasses server-side connection concurrency limits to unlock full aggregate wire speed. A specialized client-only
Tor 0.4.9.11 is packed into the application's icon resource—no installer, browser bundle, external runtime
or loose tor.exe required.

Onion Downloader - Native Multi-Circuit Tor Downloader for Windows

**One file • Native GUI and CLI • Multiple independent Tor circuits** *Ten parallel range workers, native SHA-256 PoW solver, durable resume and a complete Tor client inside 2.64 MiB* *C++23, WinAPI, no browser engine, no libcurl, no external runtime DLLs*

Graphical queue - a multi-gigabyte transfer spread across ten parallel circuits

Onion Downloader graphical interface downloading a 6.97 GB file over ten Tor circuits

Command line - the same engine and the same binary, od_x64.exe --help

Onion Downloader command-line help screen


Table of Contents


Overview

Downloading a large file through one Tor circuit means that one slow path controls the whole transfer. Onion Downloader takes a different route. If an HTTP server supports byte ranges, the file is divided into independent regions and fetched by parallel workers distributed over several Tor daemons. Every daemon maintains its own circuits, so a weak route can continue working without preventing faster routes from advancing other parts of the file.

This is not a browser automation tool and it does not contain pieces of Tor Browser. The application implements the downloader itself: HTTP requests and response parsing, native SHA-256 Anti-DDoS PoW challenge solving, SOCKS5 negotiation, range planning, direct random-access sparse writes, progress accounting, queue persistence and validated resume metadata. Tor is used for Onion transport and nothing else.

Property Current release
Final executable 2.64 MiB x64 (2,771,456 bytes) • 2.10 MiB ARM64 (2,200,064 bytes)
Platform Windows x64 and native ARM64 (Windows on ARM)
Default parallelism 10 range workers
Tor process pool Automatically selected, normally 2-8 daemons (ports 19050+)
Anti-DDoS Gate Solver Pure C++ SHA-256 (5–15 ms) for /_gate/challenge
Session Architecture Per-worker isolated gate_sid session cookies
Disk Allocation NTFS sparse pre-allocation (FSCTL_SET_SPARSE)
Embedded Tor 0.4.9.11, client-only, proof-of-work enabled
Interface Native Win32 GUI and CLI in the same PE file
Runtime dependencies Windows system libraries only
Default destination Current user's Windows Downloads folder

Real speed still depends on the Onion service, its range support, relay conditions and the user's connection. Multi-circuit scheduling removes the single-route bottleneck; it cannot manufacture bandwidth the remote service does not have.


Highlights

  • Parallel HTTP ranges over independent Tor paths - ten workers by default, configurable up to 64.
  • Native Anti-DDoS Proof-of-Work (PoW) solver - pure C++ SHA-256 engine solves /_gate/challenge in 5–15 ms without any bloated JavaScript runtime.
  • Per-worker session cookie isolation - each worker over its assigned circuit acquires an isolated gate_sid cookie, defeating server-side limit_conn throttling that previously choked multi-stream transfers to ~100 KB/s.
  • Transparent URL sanitization - automatically encodes raw spaces (%20) and Unicode characters in Onion paths according to RFC 3986.
  • Sparse disk pre-allocation - uses NTFS FSCTL_SET_SPARSE to reserve file bounds instantly with zero physical disk zero-fill overhead.
  • Native x64 and ARM64 builds - od_x64.exe and od_arm64.exe, each embedding its own native Tor engine; the ARM64 build runs natively on Windows on ARM, not under x64 emulation.
  • Adaptive Tor pool - multiple local SOCKS endpoints (ports 19050, 19052, 19054...) without requiring a separately installed Tor service.
  • Correct non-range fallback - a server that ignores Range is downloaded as one ordinary stream instead of producing a corrupted file.
  • Durable pause and resume - data already written is retained in place and described by compact metadata beside it; updates are committed atomically via ReplaceFileW.
  • Safe restart behaviour - unfinished GUI jobs are restored as paused; the user decides when network work resumes.
  • Native Windows presentation - automatic light/dark mode, Windows 11 Mica, flicker-free double-buffered ListView and PerMonitorV2 DPI scaling.
  • Window-level paste and drag-and-drop - Ctrl+V works without focusing the edit control; dropped URLs go directly to the address field.
  • One self-contained binary - Tor is embedded, compressed and extracted to a version-aware local cache only when necessary.
  • No downloader libraries - no libcurl, aria2, Chromium, Gecko, Qt, Electron or .NET.
  • Clean child lifetime - Tor processes live in a Windows Job Object (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) and are terminated instantly with the application.

Two Heads, One Download Engine

od_x64.exe is a dual-mode executable in the same sense as a good native system utility: the presence and meaning of command-line arguments choose the interface, not a second launcher.

flowchart TD classDef startStyle fill:#1e1035,stroke:#a78bfa,stroke-width:1.5px,color:#ede9fe classDef decisionStyle fill:#2e1065,stroke:#7c3aed,stroke-width:2px,color:#ffffff classDef guiStyle fill:#0f172a,stroke:#38bdf8,stroke-width:1.5px,color:#f0f9ff classDef cliStyle fill:#1e293b,stroke:#f59e0b,stroke-width:1.5px,color:#fffbeb classDef coreStyle fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#ecfdf5 START["Binary Entry: od_x64.exe / od_arm64.exe
Subsystem: Windows (/SUBSYSTEM:WINDOWS)"]:::startStyle --> ARGS{"Command-Line
Arguments Present?"}:::decisionStyle ARGS -->|No Args or --gui| GUI_INIT["Win32 Window Creation
PerMonitorV2 DPI • Mica / Dark Mode"]:::guiStyle ARGS -->|URL Provided| CLI_ATTACH["AttachConsole(ATTACH_PARENT_PROCESS)
AllocConsole() fallback"]:::cliStyle GUI_INIT --> MSG_LOOP["Win32 Message Loop
Clipboard Ctrl+V • Drag & Drop • Queue"]:::guiStyle CLI_ATTACH --> CLI_LOOP["ConsoleApp Execution
SetConsoleCtrlHandler • Progress Bar"]:::cliStyle MSG_LOOP --> ENGINE["Shared Core Engine (C++23)
DownloadEngine • TorPool • HttpClient • PartFile"]:::coreStyle CLI_LOOP --> ENGINE ENGINE --> TOR["Embedded Tor 0.4.9.11
FDI In-Memory Extraction from Icon Resource"]:::coreStyle

With no arguments it enters its Win32 message loop and presents the graphical queue. With a URL it behaves as a console downloader suitable for batch files and terminals. Both heads call the same coordinator and share every important implementation below the presentation layer. A transfer created in either mode follows the same range validation, circuit allocation and part-file rules.

Invocation Behaviour
od_x64.exe Launch the graphical interface
od_x64.exe http://service.onion/file.zip Download through the CLI using the default worker and circuit policy
od_x64.exe --gui Explicitly launch the GUI
od_x64.exe --help Print command-line usage

Multi-Circuit Architecture

flowchart TB classDef inputStyle fill:#1e1035,stroke:#a78bfa,stroke-width:1.5px,color:#ede9fe classDef coordStyle fill:#2e1065,stroke:#7c3aed,stroke-width:2px,color:#ffffff classDef torStyle fill:#0f172a,stroke:#38bdf8,stroke-width:1.5px,color:#f0f9ff classDef workerStyle fill:#1e293b,stroke:#818cf8,stroke-width:1.5px,color:#f8fafc classDef onionStyle fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#ecfdf5 classDef storageStyle fill:#14532d,stroke:#22c55e,stroke-width:1.5px,color:#f0fdf4 URL["Onion URL
GUI paste, drop or CLI"]:::inputStyle --> COORD["Download Coordinator
Probe, plan, progress, cancellation"]:::coordStyle COORD --> PROBE{"HTTP Range
supported?"}:::coordStyle PROBE -->|Yes| MAP["SegmentMap Scheduler
10 workers • 8 segments/worker"]:::workerStyle PROBE -->|No| STREAM["Sequential Fallback
Single continuous stream"]:::workerStyle subgraph POOL ["Independent Tor Daemon Pool (127.0.0.1:19050 + 2k)"] T1["Tor Daemon #1
Port 19050 • Private Profile 1"]:::torStyle T2["Tor Daemon #2
Port 19052 • Private Profile 2"]:::torStyle TN["Tor Daemon #N
Port 19050+2k • Private Profile N"]:::torStyle end MAP --> W1["Worker 1
Range A"]:::workerStyle MAP --> W2["Worker 2
Range B"]:::workerStyle MAP --> WN["Worker N
Range K"]:::workerStyle W1 -->|SOCKS5| T1 W2 -->|SOCKS5| T2 WN -->|SOCKS5| TN subgraph ISOLATION ["Per-Worker / Per-Circuit PoW Gate Isolation"] T1 -->|Independent Circuit| O1["Onion Service
Session Cookie A"]:::onionStyle T2 -->|Independent Circuit| O2["Onion Service
Session Cookie B"]:::onionStyle TN -->|Independent Circuit| ON["Onion Service
Session Cookie N"]:::onionStyle end O1 --> PART["NTFS Sparse Writes
target.odpart (FSCTL_SET_SPARSE)"]:::storageStyle O2 --> PART ON --> PART STREAM --> PART PART --> META["Atomic State Checkpoints
target.odmeta (ReplaceFileW)"]:::storageStyle META --> DONE["Verified Destination File
Final Atomic Rename"]:::storageStyle

Each Tor instance gets an isolated data directory and SOCKS listener. The pool waits for bootstrap rather than treating a process launch as network readiness. Workers open SOCKS5 connections to the Onion hostname through selected instances and write only into their assigned regions of the pre-sized part file.


Anti-DDoS Proof-of-Work (PoW) Gate Engine

Modern high-traffic Onion services protect themselves from denial-of-service attacks by deploying dynamic Proof-of-Work challenges. When an unauthenticated request hits the service, it responds with HTTP 401 Unauthorized or redirects to /_gate/challenge:

sequenceDiagram autonumber participant W as Worker Thread participant T as Tor SOCKS5 Circuit participant S as Onion Reverse Proxy (NGINX / HAProxy) participant B as Onion Origin Backend W->>T: GET /path/file.bin (Range: bytes=0-1048575) T->>S: Forward Request over Tor Circuit Note over S: DDoS Filter Active
No valid session cookie found S-->>T: HTTP 401 Unauthorized (or 429 Retry) T-->>W: Forward 401 Challenge Payload Note over W: Native C++ SHA-256 Engine
Iterate nonces (5-15 ms)
Match target prefix W->>T: POST /_gate/verify (nonce, salt) T->>S: Submit PoW Solution S->>S: Verify SHA-256 Digest S-->>T: HTTP 200 OK + Set-Cookie: gate_sid=SESSION_TOKEN T-->>W: Receive Validated Session Cookie Note over W: Store Cookie for Circuit Worker W->>T: GET /path/file.bin (Range: 0-1048575 + Cookie: gate_sid) T->>S: Authenticated Ranged Request S->>B: Forward to Storage Backend B-->>S: HTTP 206 Partial Content (Payload) S-->>T: Stream Payload Bytes T-->>W: Receive 64 KiB Data Blocks Note over W: Direct Random-Access Write
target.odpart via Win32 FileHandle

Standard CLI tools (curl, wget, aria2) fail with HTTP 401 because they lack PoW gate support. Tor Browser succeeds because it runs a client-side JavaScript Web Worker. Onion Downloader achieves the same compatibility natively: its in-process pure C++ SHA-256 engine finds the valid nonce in 5 to 15 milliseconds, without the memory or startup overhead of a JavaScript runtime.


Per-Worker Session Isolation (Solving the 100 KB/s Bottleneck)

Early multi-stream onion downloaders encountered a puzzling performance trap: configured for 10 parallel connections, the total transfer speed remained throttled at ~100 KB/s.

Root Cause

Onion reverse proxies enforce strict per-session concurrency controls:

limit_conn_zone $cookie_gate_sid zone=session_limit:10m;
limit_conn session_limit 1;
limit_rate 150k;

When 10 workers over different Tor circuits passed the same gate_sid cookie, the reverse proxy identified them as the same client session and throttled cumulative throughput to a single stream's quota.

The Architectural Solution

Onion Downloader gives every worker thread its own private session:

  1. Each worker connects through its designated Tor daemon and SOCKS5 circuit.
  2. Each worker independently solves its own PoW gate challenge over that circuit and receives a distinct gate_sid cookie.
  3. Requests carry the worker's own session cookie.
  4. The server sees $N$ distinct authenticated clients, unlocking full parallel bandwidth across all circuits and elevating transfers from ~100 KB/s to multi-megabyte per second wire speeds.

URL Sanitization and Normalization

Onion paths frequently contain unencoded spaces, brackets, or Unicode characters (for example, /Data Archive (2026)/Sample File.iso). Raw spaces violate HTTP/1.1 request line syntax and trigger HTTP 400 Bad Request.

HttpClient::SanitizeRequestPath parses the URI path, preserves delimiters (/, ?, &, =, #), and automatically percent-encodes spaces to %20 and non-ASCII characters to standard percent-encoded octets. Clipboard paste and drag-and-drop inputs in the GUI automatically trim whitespace and normalize quotes.


Engineering Decisions and Invariants

The most important decisions are encoded as invariants rather than UI conventions:

More segments than workers

A naive parallel downloader cuts a file into exactly as many pieces as it has workers. Over Tor, circuit speeds can differ by an order of magnitude. Onion Downloader creates a dynamic work queue with a target of eight segments per worker (2 MiB to 16 MiB each). Workers claim the next available segment dynamically, letting fast circuits complete multiple regions while a slower circuit is still handling one.

A completed bit means a completed range

Progress bytes are useful for presentation but are not the source of resume truth. A segment changes from Pending to InFlight when claimed and to Complete only after its entire expected body has been received and written. The completion bitmap never claims that a partially received segment is durable.

The server must prove the range

The initial probe asks for byte zero only. Parallel mode is accepted only when the response is HTTP 206, contains a parseable Content-Range, and reports a non-zero total instance length.

Retry means a new Tor isolation identity

Every worker authenticates to SOCKS5 with its own generated isolation username. When a connection fails, the socket closes and the credential nonce advances before the range is retried. Tor's IsolateSOCKSAuth policy prevents the retry from silently returning to the path that just stalled.

Cancellation must break blocked network calls

Pause cannot merely set a Boolean and wait for a long receive timeout. Each live HttpConnection is registered with the job; cancellation closes its atomic socket handle, which wakes a thread blocked inside Winsock.

Disk writers share a file, not a file pointer

The part file is opened once, but each worker performs explicit offset-based writes (SetFilePointerEx + WriteFile). No shared sequential file position exists to race between threads.


Pause, Resume and Recovery

An unfinished archive.zip is represented by two files next to the future destination:

File Purpose
archive.zip.odpart Sparse data file pre-allocated with FSCTL_SET_SPARSE; completed ranges occupy final offsets
archive.zip.odmeta Small JSON description used to validate the URL, expected size and completed segment map

Resume metadata is checkpointed at controlled intervals and committed atomically via a temporary file (.odmeta.tmp) and ReplaceFileW. Instantaneous transfer speed upon resume is calculated strictly from active newly transferred bytes, preventing artificial speed spikes.


How the Entire Program Fits in 2.64 MiB

flowchart LR classDef srcStyle fill:#1e1035,stroke:#a78bfa,stroke-width:1.5px,color:#ede9fe classDef optStyle fill:#2e1065,stroke:#7c3aed,stroke-width:1.5px,color:#ffffff classDef binStyle fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#ecfdf5 TOR_SRC["Upstream Tor 0.4.9.11
C-Tor Sources"]:::srcStyle --> MOD["Prune Unused Modules
No relay, dirauth or dircache"]:::optStyle SSL_SRC["OpenSSL 3.5.7 Sources"]:::srcStyle --> SSL_PRUNE["Prune Ciphers & Algorithms
No legacy, tests, CLI, docs"]:::optStyle LIB_SRC["libevent 2.1 + zlib"]:::srcStyle --> LIB_STATIC["Static Linkage Closure"]:::optStyle MOD --> GC["MinGW / Clang Section GC
-ffunction-sections -fdata-sections"]:::optStyle SSL_PRUNE --> GC LIB_STATIC --> GC GC --> RAW["Specialized tor.exe
6.54 MiB raw PE"]:::optStyle RAW --> CAB["makecab.exe /D CompressionType=LZX
LZX-21 Cabinet: ~2.15 MiB"]:::optStyle ICO["Valid Win32 ICO
app_orig.ico"]:::srcStyle --> JOIN["Icon + Appended Cabinet
resources/app.ico"]:::optStyle CAB --> JOIN APP_SRC["C++23 GUI + CLI Engine
Direct Win32 • /O1 /Os /GL /GR-"]:::srcStyle --> LINK["MSVC v145 Linker (/MT)
Dead COMDAT elimination"]:::optStyle JOIN --> LINK LINK --> FINAL["Single Executable
od_x64.exe: 2.64 MiB (2,771,456 B)
od_arm64.exe: 2.10 MiB (2,200,064 B)"]:::binStyle
  1. GUI and CLI share one PE and one engine. No secondary launcher executable.
  2. The interface is direct WinAPI. Zero third-party GUI framework dependencies.
  3. Tor is compiled for the client role only. Relay and directory-server machinery never reaches the linker.
  4. OpenSSL is pruned before compilation. Unused algorithms, tests, and CLI tools are omitted.
  5. Static runtime. Statically linked with MSVC /MT—no VC++ Redistributable needed.
  6. Windows Cabinet LZX-21. Compresses the ~6.54 MiB Tor PE into ~2.15 MiB.
  7. Appended to ICO resource. Embedded directly inside resources/app.ico.
  8. In-memory FDI decompression. Extracted via Windows native cabinet.dll directly to %LOCALAPPDATA%\od\tor\bin.

The Embedded Tor Engine

Tor capability Included? Reason
Onion client and SOCKS proxy Yes Core transport required by the downloader
Onion-service proof-of-work client Yes Required for compatibility with services defending themselves under load
Relay module No Onion Downloader never carries traffic for other clients
Directory authority module No It never operates Tor network authority infrastructure
Directory cache role No It is a client, not a public cache
Unit tests, manuals and Tor applications No Build-time material, not runtime client functionality
System-wide torrc No Each managed process receives its explicit private configuration

A Linux-Built Native Windows Tor

The embedded engine uses Tor 0.4.9.11 compiled inside Ubuntu under WSL via MinGW-w64. The output is a native Windows PE executable with ASLR, high-entropy ASLR, and NX compatibility.

A second native ARM64 (AArch64) engine is cross-compiled with llvm-mingw (clang, aarch64-w64-mingw32). The ARM64 build od_arm64.exe embeds this native engine: nothing runs under emulation on Windows on ARM.


Graphical Interface

The GUI uses native controls, PerMonitorV2 scaling, system light/dark preference, and Mica on Windows 11. The ListView uses double buffering and diffed cell updates to eliminate flickering during rapid progress refreshes.

Paste an Onion URL with Ctrl+V anywhere in the main window, drag and drop a URL, or type into the address field.


Command-Line Usage

od_x64.exe http://example.onion/dataset.zip
od_x64.exe -s 20 -c 8 -o D:\Data http://example.onion/bigfile.bin
od_x64.exe --gui
Option Meaning
<URL> Target HTTP address, normally an Onion service
-s, --split <N> Parallel workers; default 10, maximum 64
-c, --circuits <N> Independent Tor daemons; default automatic, normally 2-8
-o, --out <dir> Destination directory; default is the user's Downloads folder
-g, --gui Launch the graphical interface explicitly
-h, --help Print help and exit
-v, --version Print version and build information

Source Architecture

Area Responsibility
src/core/DownloadEngine.* Job lifecycle, probing, worker creation, retry policy, progress monitoring and finalization
src/core/SegmentMap.* Dynamic range work queue, Pending/InFlight/Complete state and compact resume bitmap
src/core/PartFile.* Sparse NTFS writer (FSCTL_SET_SPARSE), independent offset writers, atomic metadata
src/core/SessionManager.* GUI queue persistence and safe restoration of active work as Paused
src/core/TorPool.* Private profiles, ports, process Job Object, control authentication, bootstrap
src/core/TorExtractor.* In-memory Cabinet FDI callbacks, embedded payload fingerprint and local Tor cache
src/net/Socks5.* Cancellable Winsock stream and SOCKS5 hostname connection with authentication isolation
src/net/HttpClient.* URL parsing, HTTP requests, PoW SHA-256 solver, Range headers, path sanitization
src/ui/OdWindow.* Native window lifecycle, queue interaction, clipboard, OLE drop target and command routing
src/ui/Controls.* ListView subclass, owner-drawn controls and theme palettes
src/cli/* Strict argument parsing, console ownership and terminal progress presentation

Validation Strategy

  • Cold Tor bootstrap - start without a prepared profile, reach control-port progress 100%, verify SOCKS listener.
  • Warm multi-instance bootstrap - reuse directory material, seed sibling profiles, verify pool readiness.
  • Anti-DDoS PoW Gate - solve live /_gate/challenge puzzles under load and verify cookie persistence.
  • Circuit isolation - verify distinct gate_sid cookies across workers, defeating concurrency throttling.
  • Range negotiation - distinguish valid 206 responses from servers returning 200 to a range probe.
  • Job Object lifecycle - terminate downloader and verify zero orphaned tor.exe child processes.
  • Atomic resume - simulate process crash during transfer and verify .odmeta integrity.

Building from Source

# From the source-tree root:
.\build.ps1                  # builds x64 AND ARM64
.\build.ps1 -Platform x64    # or a single architecture
.\build.ps1 -Platform ARM64

Downloads and Source Code

Archive Size Description
od.7z 4.08 MiB (4,283,101 bytes) Both native binaries (od_x64.exe + od_arm64.exe), password: github.com
od.zip 4.18 MiB (4,381,533 bytes) Both native binaries (od_x64.exe + od_arm64.exe), standard ZIP (no password)
od_source_code.zip 3.86 MiB (4,045,575 bytes) Full clean C++23 source code, project files and build scripts

Binaries inside the archives:

  • od_x64.exe: 2,771,456 bytes (2.64 MiB), native Intel/AMD x64 PE
  • od_arm64.exe: 2,200,064 bytes (2.10 MiB), native Windows on ARM PE

License

Onion Downloader's original source is released under the MIT License.

The embedded Tor executable remains a separate GPLv3-or-later program. OpenSSL, libevent and zlib retain their upstream licenses.


Author

Marek Wesołowski - WESMAR
https://kvc.pl

Add a comment

human test