Rust Tor协议版本处理库tor-protover的使用,支持Tor网络协议版本协商与兼容性检查

tor-protover

Tor协议版本处理库的实现。

概述

Tor系统由多个"子协议"组成,这些子协议有各自独立的版本控制。tor-protover crate实现了对这些子协议版本的解析和处理,以便不同的Tor实例知道它们支持协议的哪些部分。

子协议版本也用于确定连接网络所需的协议版本(或只是推荐的协议版本)。

更多细节请参考tor-spec.txt第9节。

这个crate是Arti项目的一部分,该项目旨在用Rust实现Tor。除非你在编写Tor实现或需要检查Tor网络细粒度细节的程序,否则这个crate不太可能有广泛的兴趣。

设计说明

我们在arti中给tor-protover提供了自己的crate,因为它需要被多个不相互依赖的高级crate使用。(例如,tor-proto需要知道可以与给定中继一起使用的子协议变体,而tor-netdoc需要从目录文档中解析子协议版本列表。最终,arti-client需要将其支持的协议列表与共识中要求的列表进行核对。)

许可证:MIT OR Apache-2.0

示例代码

use tor_protover::{Protover, ProtoverError};

fn main() -> Result<(), ProtoverError> {
    // 创建一个新的协议版本对象
    let supported = Protover::default()
        .enable("Link", 1)?
        .enable("Link", 2)?
        .enable("LinkAuth", 1)?
        .enable("Relay", 1)?
        .enable("Relay", 2)?
        .enable("DirCache", 1)?;
    
    // 检查是否支持特定协议版本
    if supported.supports("Link", 2) {
        println!("支持Link协议版本2");
    }
    
    // 解析协议版本字符串
    let required = Protover::from_str("Link=1-2 LinkAuth=1 Relay=1-2")?;
    
    // 检查是否支持所有需要的协议
    if supported.supports_all(&required) {
        println!("支持所有需要的协议版本");
    } else {
        println!("缺少一些需要的协议版本");
    }
    
    // 获取支持的协议字符串表示
    println!("支持的协议: {}", supported.to_string());
    
    Ok(())
}

完整示例demo

use tor_protover::{Protover, ProtoverError};

fn protocol_negotiation() -> Result<(), ProtoverError> {
    // 客户端支持的协议版本
    let client_protos = Protover::default()
        .enable("Link", 1)?
        .enable("Link", 2)?
        .enable("LinkAuth", 1)?
        .enable("Relay", 1)?
        .enable("Relay", 2)?
        .enable("DirCache", 1)?;
    
    // 服务器支持的协议版本
    let server_protos = Protover::default()
        .enable("Link", 1)?
        .enable("LinkAuth", 1)?
        .enable("Relay", 1)?
        .enable("DirCache", 1)?;
    
    // 协商双方都支持的协议
    let negotiated = client_protos.intersection(&server_protos);
    
    println!("协商结果: {}", negotiated.to_string());
    
    // 检查是否满足最低要求
    let minimum_required = Protover::from_str("Link=1 LinkAuth=1 Relay=1")?;
    if negotiated.supports_all(&minimum_required) {
        println!("满足最低协议要求");
    } else {
        println!("不满足最低协议要求");
    }
    
    Ok(())
}

fn main() {
    if let Err(e) = protocol_negotiation() {
        eprintln!("协议协商错误: {}", e);
    }
}

这个示例展示了如何使用tor-protover进行Tor协议版本的协商和兼容性检查。你可以根据实际需要调整支持的协议版本和检查逻辑。


1 回复

Rust Tor协议版本处理库tor-protover使用指南

tor-protover是Rust中用于处理Tor协议版本协商和兼容性检查的库,它支持Tor网络中的协议版本协商功能。

功能概述

  • 解析和验证Tor协议版本字符串
  • 检查协议版本兼容性
  • 支持Tor协议版本协商
  • 提供协议版本比较功能

基本使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
tor-protover = "0.1.0"

解析协议版本

use tor-protover::Protocols;

fn main() {
    // 解析协议版本字符串
    let protocols = Protocols::parse("Link=1-3 LinkAuth=1").unwrap();
    
    // 检查是否支持特定协议版本
    if protocols.supports_known_subver("Link", 3) {
        println!("支持Link协议版本3");
    }
}

协议版本协商

use tor-protover::{Protocols, ProtoKind};

fn negotiate_protocols() {
    let my_protocols = Protocols::parse("Link=1-3 LinkAuth=1").unwrap();
    let their_protocols = Protocols::parse("Link=2-4 LinkAuth=1").unwrap();
    
    // 协商共同支持的协议版本
    let negotiated = my_protocols.intersection(&their_protocols);
    
    if negotiated.supports(ProtoKind::Link, 3) {
        println!("双方都支持Link协议版本3");
    }
}

检查协议兼容性

use tor-protover::Protocols;

fn check_compatibility() {
    let required = Protocols::parse("Link=3 LinkAuth=1").unwrap();
    let offered = Protocols::parse("Link=1-4 LinkAuth=1-2").unwrap();
    
    if offered.supports_all(&required) {
        println!("提供的协议满足要求");
    } else {
        println!("协议不兼容");
    }
}

高级用法

构建协议版本集合

use tor-protover::{Protocols, ProtoKind};

fn build_protocols() {
    let mut protocols = Protocols::default();
    
    // 添加支持的协议范围
    protocols.add(ProtoKind::Link, 1..=4);
    protocols.add(ProtoKind::LinkAuth, 1);
    
    // 移除不支持的协议版本
    protocols.remove(ProtoKind::Link, 1);
    
    println!("支持的协议: {}", protocols);
}

协议版本比较

use tor-protover::Protocols;

fn compare_protocols() {
    let v1 = Protocols::parse("Link=1-3").unwrap();
    let v2 = Protocols::parse("Link=2-4").unwrap();
    
    // 检查是否v1完全包含在v2中
    if v1.is_subset(&v2) {
        println!("v1是v2的子集");
    }
}

实际应用示例

use tor-protover::{Protocols, ProtoKind};

fn handle_protocol_negotiation(their_versions: &str) -> Result<Protocols, &'static str> {
    // 我们支持的协议版本
    let our_protocols = Protocols::parse("Link=1-3 LinkAuth=1 Relay=2").unwrap();
    
    // 解析对方提供的协议版本
    let their_protocols = match Protocols::parse(their_versions) {
        Ok(p) => p,
        Err(_) => return Err("无效的协议版本字符串"),
    };
    
    // 协商共同支持的协议
    let negotiated = our_protocols.intersection(&their_protocols);
    
    // 检查是否满足最低要求
    let required = Protocols::parse("Link=2 LinkAuth=1").unwrap();
    if !negotiated.supports_all(&required) {
        return Err("无法满足最低协议要求");
    }
    
    Ok(negotiated)
}

完整示例代码

use tor-protover::{Protocols, ProtoKind};

fn main() {
    // 示例1:基础协议解析
    let protocols = Protocols::parse("Link=1-3 LinkAuth=1 Relay=2").unwrap();
    println!("解析结果: {}", protocols);

    // 示例2:协议版本协商
    let client_protocols = Protocols::parse("Link=1-3 LinkAuth=1").unwrap();
    let relay_protocols = Protocols::parse("Link=2-4 LinkAuth=1").unwrap();
    let negotiated = client_protocols.intersection(&relay_protocols);
    println!("协商结果: {}", negotiated);

    // 示例3:构建自定义协议集合
    let mut custom_protocols = Protocols::default();
    custom_protocols.add(ProtoKind::Link, 1..=3);
    custom_protocols.add(ProtoKind::LinkAuth, 1);
    println!("自定义协议: {}", custom_protocols);

    // 示例4:完整的协议协商函数
    match handle_protocol_negotiation("Link=2-4 LinkAuth=1 Relay=1-2") {
        Ok(p) => println!("成功协商: {}", p),
        Err(e) => println!("协商失败: {}", e),
    }
}

fn handle_protocol_negotiation(their_versions: &str) -> Result<Protocols, &'static str> {
    let our_protocols = Protocols::parse("Link=1-3 LinkAuth=1 Relay=2").unwrap();
    let their_protocols = Protocols::parse(their_versions)?;
    
    let negotiated = our_protocols.intersection(&their_protocols);
    
    let required = Protocols::parse("Link=2 LinkAuth=1").unwrap();
    if negotiated.supports_all(&required) {
        Ok(negotiated)
    } else {
        Err("协议不满足最低要求")
    }
}

注意事项

  1. 协议版本字符串格式必须符合Tor规范
  2. 解析失败时会返回错误
  3. 协议版本号必须是正整数
  4. 使用前应检查Tor协议规范以了解当前支持的协议版本

tor-protover库为Tor网络应用的开发提供了方便的协议版本处理功能,特别是在实现Tor客户端或中继时需要处理协议协商的情况下非常有用。

回到顶部