Rust的Tor网络连接管理库tor-circmgr的使用:高效处理Tor电路创建与维护

Rust的Tor网络连接管理库tor-circmgr的使用:高效处理Tor电路创建与维护

概述

tor-circmgr是Arti项目的一部分,Arti是一个用Rust实现Tor的项目。在Tor中,电路(circuit)是通过多个中继建立的加密多跳隧道。这个库的长期目标是管理客户端的电路集合,它应该:

  1. 根据客户端需求构建电路
  2. 预构建电路以预期需求
  3. 如果现有电路能满足请求,就复用现有电路而不是新建

编译时特性

  • specific-relay: 支持通过特定提供的连接指令连接到中继,而不是使用Tor网络目录中的信息
  • full: 启用所有上述特性

实验性和不稳定特性

这些API不遵循语义版本控制保证:

  • experimental-api: 在公共接口中添加非稳定API
  • experimental: 启用所有实验性特性

许可证

MIT OR Apache-2.0

示例代码

以下是使用tor-circmgr创建和管理Tor电路的完整示例:

use tor_circmgr::{CircMgr, TargetPort};
use tor_rtcompat::PreferredRuntime;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
    // 创建默认的运行时
    let runtime = PreferredRuntime::current()?;
    
    // 创建电路管理器
    let circ_mgr = CircMgr::new(runtime)?;
    
    // 定义目标端口(例如80用于HTTP)
    let target_port = TargetPort::new(80);
    
    // 获取一个适合连接到目标端口的新电路
    let circuit = circ_mgr.get_or_create_launch(target_port).await?;
    
    // 使用电路进行网络请求...
    // (这里省略实际的使用代码)
    
    Ok(())
}

更完整的示例,包括错误处理和实际使用:

use tor_circmgr::{CircMgr, TargetPort, StreamParameters};
use tor_rtcompat::PreferredRuntime;
use anyhow::{Context, Result};

#[tokio::main]
async fn main() -> Result<()> {
    // 初始化日志
    tracing_subscriber::fmt::init();
    
    // 创建运行时
    let runtime = PreferredRuntime::current()
        .context("Failed to create runtime")?;
    
    // 创建电路管理器
    let circ_mgr = CircMgr::new(runtime.clone())
        .context("Failed to create circuit manager")?;
    
    // 目标端口和流参数
    let target_port = TargetPort::new(443); // HTTPS
    let stream_params = StreamParameters::default();
    
    // 获取或创建电路
    let circuit = circ_mgr.get_or_create_launch(target_port)
        .await
        .context("Failed to create circuit")?;
    
    // 创建数据流
    let mut stream = circuit
        .begin_stream(&stream_params)
        .await
        .context("Failed to create stream")?;
    
    // 在这里可以使用stream进行网络通信...
    // 例如发送HTTP请求等
    
    Ok(())
}

完整示例demo

以下是一个更完整的示例,包含HTTP请求功能:

use tor_circmgr::{CircMgr, TargetPort, StreamParameters};
use tor_rtcompat::PreferredRuntime;
use anyhow::{Context, Result};
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::main]
async fn main() -> Result<()> {
    // 初始化日志
    tracing_subscriber::fmt::init();
    
    // 创建运行时
    let runtime = PreferredRuntime::current()
        .context("Failed to create runtime")?;
    
    // 创建电路管理器
    let circ_mgr = CircMgr::new(runtime.clone())
        .context("Failed to create circuit manager")?;
    
    // 目标端口和流参数
    let target_port = TargetPort::new(80); // HTTP
    let stream_params = StreamParameters::default();
    
    // 获取或创建电路
    let circuit = circ_mgr.get_or_create_launch(target_port)
        .await
        .context("Failed to create circuit")?;
    
    // 创建数据流
    let mut stream = circuit
        .begin_stream(&stream_params)
        .await
        .context("Failed to create stream")?;
    
    // 发送HTTP请求
    let request = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n";
    stream.write_all(request.as_bytes())
        .await
        .context("Failed to write request")?;
    
    // 读取响应
    let mut response = Vec::new();
    stream.read_to_end(&mut response)
        .await
        .context("Failed to read response")?;
    
    // 打印响应
    println!("Response: {}", String::from_utf8_lossy(&response));
    
    Ok(())
}

安装

在项目目录中运行以下Cargo命令:

cargo add tor-circmgr

或者在Cargo.toml中添加:

tor-circmgr = "0.32.0"

1 回复

Rust的Tor网络连接管理库tor-circmgr的使用:高效处理Tor电路创建与维护

以下是基于提供内容整理的完整示例demo,展示了tor-circmgr库的基本和高级用法:

完整示例代码

use tor_circmgr::{CircBuildConfig, CircMgr, CircEvent, DirInfo, TargetPort};
use tor_proto::circuit::IpVersionPreference;
use tor_rtcompat::{PreferredRuntime, Runtime};
use futures::StreamExt;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 创建Tokio运行时
    let runtime = PreferredRuntime::current()?;
    
    // 2. 获取Tor网络目录信息
    let dir_info = DirInfo::from_cache_only();
    
    // 3. 创建电路管理器实例
    let circmgr = CircMgr::new(runtime.clone(), dir_info).await?;
    
    // 4. 监听电路事件(高级用法)
    let mut events = circmgr.events();
    tokio::spawn(async move {
        while let Some(event) = events.next().await {
            match event {
                CircEvent::CircuitCreated(_) => println!("[事件] 新电路已创建"),
                CircEvent::CircuitFailed(_, reason) => println!("[事件] 电路失败: {:?}", reason),
                CircEvent::CircuitClosed(_) => println!("[事件] 电路已关闭"),
                _ => {}
            }
        }
    });
    
    // 5. 自定义电路配置(高级用法)
    let config = CircBuildConfig {
        exit_ports: vec![TargetPort::ipv4(443)],  // 指定目标端口443
        ip_version: IpVersionPreference::Ipv6Preferred,  // 优先使用IPv6
        overall_timeout: Duration::from_secs(60),  // 总超时60秒
        ..Default::default()
    };
    
    // 6. 获取或创建电路(基本用法)
    match circmgr.get_or_launch(config).await {
        Ok(circuit) => {
            println!("成功建立Tor电路:");
            println!("- 电路ID: {:?}", circuit.unique_id());
            println!("- 出口节点: {:?}", circuit.exit_relay());
            
            // 模拟使用电路...
            tokio::time::sleep(Duration::from_secs(2)).await;
            
            // 7. 资源清理(最佳实践)
            println!("关闭所有电路...");
            circmgr.close_all_circuits().await;
        },
        Err(e) => {
            eprintln!("无法建立电路: {}", e);
            
            // 错误恢复逻辑
            if e.to_string().contains("timeout") {
                println!("超时错误,建议增加超时时间或检查网络连接");
            }
        }
    }
    
    Ok(())
}

代码说明

  1. 运行时创建:使用PreferredRuntime创建Tokio运行时环境
  2. 目录信息:从缓存获取Tor网络目录信息
  3. 电路管理器:核心组件,负责电路生命周期管理
  4. 事件监听:异步监听电路创建、失败等事件
  5. 自定义配置
    • 指定目标端口443(HTTPS)
    • 优先使用IPv6连接
    • 设置60秒超时
  6. 电路获取:核心方法get_or_launch获取可用电路
  7. 资源清理:使用完毕后主动关闭所有电路

Cargo.toml 配置

[dependencies]
tor-circmgr = "0.10"
tor-rtcompat = "0.10"
tokio = { version = "1.0", features = ["full"] }
futures = "0.3"

这个完整示例展示了:

  1. 基本的电路创建流程
  2. 高级的自定义配置
  3. 事件监听机制
  4. 错误处理和资源清理
  5. 符合最佳实践的使用方式
回到顶部