Vanguards

Struct Vanguards 

Source
pub struct Vanguards { /* private fields */ }
Expand description

Main vanguards manager combining all protection components.

This struct provides a high-level interface for running vanguards protection on a Tor hidden service. It manages the complete lifecycle of protection, from initialization through event processing.

§Managed Components

The Vanguards struct orchestrates these protection components:

ComponentPurposeConfig Flag
Vanguard StateLayer 2/3 guard selectionenable_vanguards
BandguardsBandwidth attack detectionenable_bandguards
RendguardRendezvous point monitoringenable_rendguard
LogguardTor log monitoringenable_logguard
CBT VerifyCircuit timeout verificationenable_cbtverify
Path VerifyCircuit path verificationenable_pathverify

§Lifecycle

┌─────────────────┐
│  from_config()  │ ◄── Load config, create state
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│     run()       │ ◄── Connect to Tor, start event loop
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Event Loop     │ ◄── Process events until shutdown
│  (control.rs)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│    Cleanup      │ ◄── Save state, close connection
└─────────────────┘

§Thread Safety

Vanguards is Send but not Sync. For concurrent access:

use std::sync::Arc;
use tokio::sync::Mutex;
use vanguards_rs::{Config, Vanguards};

let vanguards = Vanguards::from_config(Config::default()).await?;
let shared = Arc::new(Mutex::new(vanguards));

§Example

§Basic Usage

use vanguards_rs::{Config, Vanguards};

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    // Create with default configuration
    let config = Config::default();
    let mut vanguards = Vanguards::from_config(config).await?;
     
    // Run the protection loop
    vanguards.run().await
}

§Inspecting State

use vanguards_rs::{Config, Vanguards};

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    let config = Config::default();
    let vanguards = Vanguards::from_config(config).await?;
     
    // Access current state
    let state = vanguards.state();
    println!("Layer2 guards: {}", state.layer2_guardset());
    println!("Layer3 guards: {}", state.layer3_guardset());
     
    // Access configuration
    let config = vanguards.config();
    println!("Vanguards enabled: {}", config.enable_vanguards);
    Ok(())
}

§Security Considerations

  • Passwords are cleared from memory after authentication
  • State files are written with restrictive permissions (0600 on Unix)
  • All external inputs are validated before use
  • Guard selections persist across restarts to prevent discovery attacks

§See Also

Implementations§

Source§

impl Vanguards

Source

pub fn new(_controller: Controller, config: Config) -> Result<Self>

Creates a new Vanguards instance from an existing controller and configuration.

This method is useful when you already have a connected and authenticated controller.

§Arguments
  • controller - An authenticated Tor controller
  • config - The vanguards configuration
§Errors

Returns an error if state loading fails.

§Example
use vanguards_rs::{Config, Vanguards};
use stem_rs::controller::Controller;

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    let mut controller = Controller::from_port("127.0.0.1:9051".parse().unwrap()).await?;
    controller.authenticate(None).await?;
     
    let config = Config::default();
    let vanguards = Vanguards::new(controller, config)?;
    Ok(())
}
Source

pub async fn from_config(config: Config) -> Result<Self>

Creates a new Vanguards instance by connecting to Tor.

This method handles connection, authentication, and state initialization. The password (if provided) is securely cleared from memory after use.

§Arguments
  • config - The vanguards configuration
§Errors

Returns an error if:

  • Connection to Tor fails
  • Authentication fails
  • State loading fails
§Example
use vanguards_rs::{Config, Vanguards};

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    let config = Config::default();
    let vanguards = Vanguards::from_config(config).await?;
    Ok(())
}
Source

pub async fn run(&mut self) -> Result<()>

Runs the main vanguards protection loop.

This method connects to Tor, authenticates, initializes protection components, and processes events until the connection is closed or an error occurs.

§Errors

Returns an error if the protection loop fails.

§Example
use vanguards_rs::{Config, Vanguards};

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    let config = Config::default();
    let mut vanguards = Vanguards::from_config(config).await?;
    vanguards.run().await
}
Source

pub fn state(&self) -> &VanguardState

Returns a reference to the current vanguard state.

§Example
use vanguards_rs::{Config, Vanguards};

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    let config = Config::default();
    let vanguards = Vanguards::from_config(config).await?;
     
    let state = vanguards.state();
    println!("Layer2 guards: {}", state.layer2_guardset());
    println!("Layer3 guards: {}", state.layer3_guardset());
    Ok(())
}
Source

pub fn config(&self) -> &Config

Returns a reference to the current configuration.

§Example
use vanguards_rs::{Config, Vanguards};

#[tokio::main]
async fn main() -> vanguards_rs::Result<()> {
    let config = Config::default();
    let vanguards = Vanguards::from_config(config).await?;
     
    let config = vanguards.config();
    println!("Vanguards enabled: {}", config.enable_vanguards);
    Ok(())
}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more