Rust匿名网络库tor-dirclient的使用,实现Tor目录协议的高效客户端通信
Rust匿名网络库tor-dirclient的使用,实现Tor目录协议的高效客户端通信
概述
tor-dirclient实现了Tor的最小目录客户端。Tor通过隧道化的HTTP/1.0请求在其电路上进行目录请求。对于大多数对象,Tor使用单跳隧道。Tor还使用一些特殊和临时HTTP头来选择特定功能,如请求差异、压缩或多个文档。
这个crate提供了通过Tor电路下载Tor目录资源的API。
特性
xz
- 启用XZ压缩。这可能会消耗较多内存和CPU,但可以节省大量带宽。(默认开启)zstd
- 启用ZSTD压缩。(默认开启)routerdesc
- 添加对下载路由器描述符的支持
使用示例
use tor_dirclient::{DirClient, Error};
use tor_rtcompat::{PreferredRuntime, Runtime};
async fn download_consensus() -> Result<(), Error> {
// 创建运行时
let runtime = PreferredRuntime::create()?;
// 创建目录客户端
let client = DirClient::new(runtime);
// 下载共识文档
let consensus = client.download_consensus().await?;
println!("下载的共识文档大小: {} bytes", consensus.len());
Ok(())
}
#[tokio::main]
async fn main() {
if let Err(e) = download_consensus().await {
eprintln!("发生错误: {}", e);
}
}
完整示例代码
下面是一个更完整的示例,展示了如何使用tor-dirclient下载网络状态文档:
use tor_dirclient::{DirClient, Error};
use tor_rtcompat::{PreferredRuntime, Runtime};
use std::time::Duration;
async fn download_network_status() -> Result<(), Error> {
// 创建运行时
let runtime = PreferredRuntime::create()?;
// 配置客户端参数
let config = tor_dirclient::Config {
request_timeout: Duration::from_secs(30),
request_attempts: 3,
..Default::default()
};
// 创建目录客户端
let client = DirClient::with_config(runtime, config);
// 下载网络状态文档
let status = client.download_networkstatus().await?;
println!("成功下载网络状态文档");
println!("文档签名: {:?}", status.signatures());
println!("路由器数量: {}", status.routers().count());
Ok(())
}
#[tokio::main]
async fn main() {
match download_network_status().await {
Ok(_) => println!("操作成功完成"),
Err(e) => eprintln!("发生错误: {}", e),
}
}
完整示例demo
以下是一个综合示例,演示了如何同时下载共识文档和网络状态文档:
use tor_dirclient::{DirClient, Error};
use tor_rtcompat::{PreferredRuntime, Runtime};
use std::time::Duration;
async fn download_tor_documents() -> Result<(), Error> {
// 创建运行时
let runtime = PreferredRuntime::create()?;
// 配置客户端参数
let config = tor_dirclient::Config {
request_timeout: Duration::from_secs(30),
request_attempts: 3,
..Default::default()
};
// 创建目录客户端
let client = DirClient::with_config(runtime, config);
// 下载共识文档
let consensus = client.download_consensus().await?;
println!("共识文档大小: {} bytes", consensus.len());
// 下载网络状态文档
let status = client.download_networkstatus().await?;
println!("网络状态文档包含 {} 个路由器", status.routers().count());
Ok(())
}
#[tokio::main]
async fn main() {
match download_tor_documents().await {
Ok(_) => println!("所有文档下载完成"),
Err(e) => eprintln!("下载过程中出错: {}", e),
}
}
注意事项
-
使用前需要在Cargo.toml中添加依赖:
[dependencies] tor-dirclient = "0.32.0" tokio = { version = "1", features = ["full"] }
-
此库是Arti项目的一部分,Arti是一个用Rust实现Tor的项目
-
默认启用了xz和zstd压缩功能,如需禁用可在Cargo.toml中指定:
tor-dirclient = { version = "0.32.0", default-features = false, features = [] }
-
许可证:MIT OR Apache-2.0
1 回复
Rust匿名网络库tor-dirclient的使用指南
完整示例demo
基于内容中提供的示例,下面是一个完整的示例demo,展示了如何使用tor-dirclient
从Tor网络获取信息并进行处理:
use tor_dirclient::{DirClient, DirClientConfig, request::RouterDescriptorRequest};
use tor_rtcompat::PreferredRuntime;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 创建运行时
let runtime = PreferredRuntime::create()?;
// 2. 配置客户端
let config = DirClientConfig::default()
.request_timeout(Duration::from_secs(30))
.cache_path(Some("./tor-cache".into()));
// 3. 创建目录客户端实例
let client = DirClient::builder(runtime)
.config(config)
.build()
.await?;
// 4. 获取共识文档
match client.get_consensus().await {
Ok(consensus) => {
println!("=== 共识文档信息 ===");
println!("版本: {}", consensus.lifetime().valid_after());
println!("包含 {} 个中继", consensus.relays().count());
}
Err(e) => eprintln!("获取共识文档失败: {}", e),
}
// 5. 获取网络状态文档
match client.get_networkstatus().await {
Ok(status) => {
println!("\n=== 网络状态 ===");
println!("有效中继数: {}", status.relays().count());
}
Err(e) => eprintln!("获取网络状态失败: {}", e),
}
// 6. 获取特定路由器描述符
let request = RouterDescriptorRequest::builder()
.family(vec!["$ABCD1234ABCD1234ABCD1234ABCD1234ABCD1234".parse()?])
.build()?;
match client.router_descriptors(request).await {
Ok(descriptors) => {
println!("\n=== 路由器描述符 ===");
println!("获取到 {} 个描述符", descriptors.len());
if let Some(desc) = descriptors.first() {
println!("第一个描述符ID: {}", desc.id());
}
}
Err(e) => eprintln!("获取路由器描述符失败: {}", e),
}
Ok(())
}
代码说明
-
运行时创建:使用
PreferredRuntime
创建异步运行时环境。 -
客户端配置:
- 设置请求超时为30秒
- 指定缓存目录为"./tor-cache"
-
客户端构建:使用配置好的参数构建
DirClient
实例。 -
获取共识文档:
- 打印共识文档的基本信息
- 包含错误处理逻辑
-
获取网络状态:
- 显示网络中的中继数量
- 单独的错误处理块
-
特定描述符请求:
- 构建特定路由器描述符请求
- 打印获取到的描述符信息
- 展示如何访问描述符的具体属性
这个完整示例演示了tor-dirclient
的主要功能,包括:
- 客户端初始化和配置
- 基本目录信息获取
- 特定请求构造
- 全面的错误处理
- 数据结构访问
使用时请确保已在Cargo.toml中添加了正确的依赖项,并遵守Tor网络的使用政策。