Tor (The Onion Router) is best known for enabling anonymous browsing, but under the hood, it’s a beautifully layered system of networking, cryptography, and client-server orchestration.
If you’ve ever peeked at Tor’s codebase, it might feel overwhelming — so let’s break it down in a way that maps directly to what you experience as a user.
🔎 How the Codebase Maps to Features
Tor’s repository can be thought of in three big layers:
- UI / Browsing Experience
- Not in Tor’s core repo itself (Tor is a daemon, not a browser).
- The Tor Browser (a separate project) integrates Tor as its backend.
- Features like “Connect to Tor” or “New Identity” are user-facing but rely on Tor’s core services.
- Core Networking (The Heart of Tor)
-
src/core/or/
→ Onion routing logic, circuits, relays. -
src/core/mainloop/
→ Event loop, scheduling, async I/O. -
src/feature/hs/
→ Hidden services (now called Onion Services). -
src/feature/control/
→ Controller protocol (for Tor Browser & apps to talk to Tor).
- Under-the-Hood Connectors & Utilities
-
src/lib/crypt_ops/
→ Encryption, key exchange, crypto primitives. -
src/lib/net/
→ Low-level socket and connection management. -
src/lib/log/
→ Logging & diagnostics. -
src/test/
→ Unit & integration tests.
Think of it as: Tor Browser asks → Tor Core builds onion routes → Networking + Crypto libraries do the heavy lifting.
📊 Sequence: How a Webpage Request Works Over Tor
Here’s a simplified flow of what happens when you type a URL in the Tor Browser:
sequenceDiagram
participant User as User (Tor Browser)
participant TorClient as Tor Client (Daemon)
participant Entry as Entry Node
participant Middle as Middle Node
participant Exit as Exit Node
participant Server as Destination Server
User->>TorClient: Request webpage
TorClient->>Entry: Build encrypted circuit
TorClient->>Middle: Extend circuit
TorClient->>Exit: Extend circuit (3 hops total)
User->>TorClient: HTTP(S) request
TorClient->>Exit: Forward encrypted request
Exit->>Server: Plain HTTP(S) request
Server->>Exit: Response
Exit->>TorClient: Encrypted response
TorClient->>User: Decrypted webpage
🖥️ Tor System Architecture
Here’s how Tor’s main components connect — with onion encryption layers visualized across the hops:
flowchart LR
subgraph UserSide[User Side]
Browser[Tor Browser]
Client[Tor Client (Daemon)]
end
subgraph TorNetwork[Tor Network]
Entry[Entry Node\n(Encryption Layer 3)]
Middle[Middle Node\n(Encryption Layer 2)]
Exit[Exit Node\n(Encryption Layer 1)]
end
subgraph Services[Services]
Hidden[Hidden Service (.onion)]
Server[Regular Destination Server]
end
Browser -->|SOCKS Request| Client
Client -->|Circuit Build| Entry
Entry --> Middle --> Exit
Exit --> Server
Client --> Hidden
Hidden --> Client
🥑 Side-by-Side Comparison: User vs Codebase
User’s Perspective | What’s Happening in the Code |
---|---|
“I click a link in Tor Browser.” | Tor Browser issues a SOCKS request to the Tor client (src/feature/control/ ). |
“Connecting to Tor network…” | Client bootstraps by contacting directory authorities (src/core/or/directory.c ). |
“Building secure connection…” | Multi-hop circuit built (src/core/or/circuitbuild.c ). |
“Page loads via Tor.” | Data onion-wrapped & relayed through entry → middle → exit (src/core/or/relay.c ). |
“I can access a .onion site.” | Hidden service rendezvous (src/feature/hs/ ). |
“Tor keeps running silently.” | Event loop keeps sockets + circuits alive (src/core/mainloop/ ). |
🎯 Key Takeaways
- Tor’s core repo is not a browser — it’s the routing engine.
- The code is layered: control interface, onion routing logic, crypto & networking utilities.
- The user’s “simple” experience of clicking a link actually triggers a sophisticated chain of circuit building, encryption, and relay coordination.
- Sequence diagrams help bridge the gap between user actions and what the code is doing.
✍️ If you’re curious, explore the Tor GitLab repo — just start from src/core/or/
to see the onion routing logic in action.
Would you like me to also add a system architecture diagram (Mermaid flowchart) showing Tor’s main components (browser ↔ tor client ↔ relays ↔ hidden services), so your Dev.to readers get a visual overview too?
Top comments (0)