Module controller

Module controller 

Source
Expand description

High-level controller API for Tor control protocol interaction.

This module provides the primary interface for interacting with Tor’s control protocol. The Controller type wraps a ControlSocket and provides high-level methods for common operations like authentication, circuit management, stream handling, and event subscription.

§Overview

The Controller is the main entry point for most stem-rs users. It handles:

  • Connection Management: Connect via TCP port or Unix domain socket
  • Authentication: Automatic method detection and credential handling
  • Information Queries: GETINFO commands for version, PID, circuit status, etc.
  • Configuration: GETCONF/SETCONF/RESETCONF for Tor configuration
  • Circuit Control: Create, extend, and close circuits
  • Stream Control: Attach and close streams
  • Event Handling: Subscribe to and receive asynchronous events
  • Hidden Services: Create and manage ephemeral hidden services
  • Address Mapping: Map addresses for custom routing

§Conceptual Role

The Controller sits between your application and Tor’s control socket:

┌─────────────┐     ┌────────────┐     ┌─────────────┐
│ Application │ ──▶│ Controller │ ──▶│ Tor Process │
└─────────────┘     └────────────┘     └─────────────┘
                          │
                    Handles:
                    • Protocol formatting
                    • Response parsing
                    • Event buffering
                    • Error handling

§What This Module Does NOT Do

§Thread Safety

Controller is Send but not Sync. The controller maintains internal state (socket, event buffer) that requires exclusive access. For concurrent access from multiple tasks, wrap in Arc<Mutex<Controller>>:

use std::sync::Arc;
use tokio::sync::Mutex;
use stem_rs::controller::Controller;

let controller = Controller::from_port("127.0.0.1:9051".parse()?).await?;
let shared = Arc::new(Mutex::new(controller));

// Clone Arc for each task
let c1 = shared.clone();
tokio::spawn(async move {
    let mut ctrl = c1.lock().await;
    // Use controller...
});

§Example

Basic usage pattern:

use stem_rs::controller::Controller;
use stem_rs::Signal;

// Connect to Tor's control port
let mut controller = Controller::from_port("127.0.0.1:9051".parse()?).await?;

// Authenticate (auto-detects method)
controller.authenticate(None).await?;

// Query information
let version = controller.get_version().await?;
println!("Connected to Tor {}", version);

// Get active circuits
let circuits = controller.get_circuits().await?;
for circuit in circuits {
    println!("Circuit {}: {:?}", circuit.id, circuit.status);
}

// Request new identity
controller.signal(Signal::Newnym).await?;

§Security Considerations

  • Passwords are not stored after authentication
  • Cookie files are read with minimal permissions
  • SAFECOOKIE authentication uses secure random nonces
  • Input is validated to prevent protocol injection attacks

§See Also

  • socket: Low-level socket communication
  • auth: Authentication implementation details
  • events: Event types for subscription
  • Python Stem’s Controller class for equivalent functionality

Structs§

AddOnionResponse
Response from ADD_ONION command.
Circuit
Information about an active Tor circuit.
CircuitId
A unique identifier for a Tor circuit.
Controller
A high-level interface for interacting with Tor’s control protocol.
RelayInfo
Information about a relay in a circuit path.
Stream
Information about an active Tor stream.
StreamId
A unique identifier for a Tor stream.