DHT 协议规范

BitTorrent DHT协议簇 技术文档

BitTorrent的分布式哈希表(DHT)是一个去中心化的对等网络,它允许客户端在没有中心Tracker服务器的情况下找到彼此。这个网络并非由单一协议构成,而是一个以核心协议为基础,由多个扩展协议(BEP, BitTorrent Enhancement Proposal)不断增强的协议簇。

核心协议:BEP-0005 - DHT Protocol

这是整个DHT网络的基石,几乎所有BT客户端都实现了这个协议。它定义了DHT的Kademlia网络结构、四种基本消息类型和节点发现机制。

1. 网络结构

  • 拓扑: 基于 Kademlia 算法。
  • ID空间: 160位的节点ID(Node ID)和信息哈希(Info-Hash),与SHA-1哈希长度一致。
  • 距离度量: 两个ID之间的距离通过异或(XOR)运算定义 (distance = id1 XOR id2)。这个结果被视为一个无符号整数。
  • 路由表: 每个节点维护一个路由表,由160个“K桶”(K-Buckets)组成,用于存储其他节点的信息。这种结构保证了对“近”的节点了解更详细,对“远”的节点了解相对稀疏。

2. 消息格式

  • 所有消息都使用 Bencode 编码,并通过 UDP 协议传输。
  • 消息分为三类,由顶层键 y 决定:
    • "y": "q": Query (查询/请求)
    • "y": "r": Response (响应)
    • "y": "e": Error (错误)

3. 四种基本查询 (q)

一个节点通过向其他节点发送这四种查询来与网络交互。

查询名 (q) 目的 关键参数 (a 字典) 关键响应 (r 字典)
ping 检查节点是否在线,并将自己加入对方路由表 id: 查询者ID id: 响应者ID
find_node 请求对方返回其路由表中离target最近的节点列表 id: 查询者ID, target: 目标ID id: 响应者ID, nodes: 紧凑编码的节点列表
get_peers 请求下载某个info_hash的peer列表 id: 查询者ID, info_hash: 目标资源哈希 values: peer列表, token: 宣告凭证
nodes: 更近的节点列表
announce_peer 宣告自己正在分享某个info_hash的资源 id, info_hash, port, token (必需) id: 响应者ID (确认)

主要扩展协议

以下是构建在BEP-5之上的、被广泛采用的扩展协议。

BEP-0032: IPv6 extension for DHT

  • 目的: 让DHT网络同时支持IPv4和IPv6,实现混合网络通信。
  • 核心机制:
    • find_node 响应和 get_peers 响应中,引入了一个新的可选字段 **nodes6**。
    • nodes: 继续用于存储紧凑编码的 IPv4 节点信息 (ID 20字节 + IP 4字节 + Port 2字节 = 26字节/节点)。
    • nodes6: 用于存储紧凑编码的 IPv6 节点信息 (ID 20字节 + IP 16字节 + Port 2字节 = 38字节/节点)。
    • 客户端可以根据自己的网络能力选择性地请求和处理这些字段。

BEP-0042: DHT Security Extension

  • 目的: 缓解DHT网络中的几种常见攻击,特别是针对节点ID生成的攻击。
  • 核心机制:
    • 强制节点ID与IP地址相关联。一个节点的ID的前几个字节必须与其公网IP地址的加盐哈希值相匹配。
    • 这使得攻击者难以在特定ID空间区域内“伪造”大量节点(Sybil攻击),因为他们无法轻易地获得大量符合ID生成规则的IP地址。
    • find_node 查询中增加一个 want 字段,值为 ["n4", "n6"],表示客户端期望收到的节点都符合此安全规范。

BEP-0044: Storing arbitrary data in the DHT

  • 目的: 扩展DHT的功能,使其不仅仅能存储peer列表,还能存储少量(小于1000字节)的任意数据。这为实现Mutable Torrents(可变种子)和去中心化应用奠定了基础。
  • 核心机制:
    • 引入两种新的查询:**put** 和 **get**。
    • put 请求:
      • token: 必须提供,从之前的 get 请求中获得。
      • v: 要存储的值 (Bencode编码,<1000字节)。
      • 签名机制: 为了验证数据所有权,put 请求必须包含公钥 (k) 和签名 (sig)。只有拥有与公钥对应的私钥的人才能成功写入。
      • 序列号 (seq): 一个递增的整数,用于版本控制,确保新的数据可以覆盖旧的数据。
    • get 请求:
      • id: 查询者ID。
      • target: 要获取的数据的哈希键 (SHA-1)。
      • 响应中会包含数据值 v、签名 sig、公钥 k、序列号 seq 以及一个用于后续 puttoken

BEP-0045: Multiple-address operation for the DHT

  • 目的: 让一个同时拥有IPv4和IPv6地址的节点,能被网络中的其他节点正确地发现和使用。
  • 核心机制:
    • 当一个节点通过IPv4联系你时,你不能假设它也有IPv6地址(反之亦然)。
    • 协议规定,客户端应该独立地在IPv4和IPv6网络栈上运行DHT实例,或者在同一个实例中能明确区分和验证不同协议族的地址。
    • 它澄清了在混合网络环境下,如何正确地响应和更新路由表。

BEP-0051: DHT Info-Hash Indexing

  • 目的: 允许DHT节点之间高效地交换info-hash样本,以加速新节点或爬虫对网络热门资源的发现速度。
  • 核心机制:
    • 引入一种新的查询:**sample_infohashes**。
    • 查询 (q):
      • id: 查询者ID。
      • target: 目标ID,用于指定采样的ID空间区域。
    • 响应 (r):
      • id: 响应者ID。
      • interval: 建议的下次采样间隔。
      • nodes: 靠近target的节点列表。
      • num: 响应者在其完整索引中拥有的总样本数。
      • samples: 核心字段。一个由多个20字节info-hash拼接而成的紧凑字符串。
    • 这个协议极大地提高了DHT爬虫的效率。

协议关系与总结

graph TD
    A[BEP-0005: 核心DHT协议] --> B[BEP-0032: IPv6支持];
    A --> C[BEP-0042: 安全扩展];
    A --> D[BEP-0044: 可变数据存储];
    A --> E[BEP-0045: 多地址操作];
    A --> F[BEP-0051: Info-Hash索引];

    subgraph 基础功能
        A
    end

    subgraph 网络扩展
        B
        E
    end

    subgraph 安全增强
        C
    end
    
    subgraph 功能扩展
        D
        F
    end

    style A fill:#f9f,stroke:#333,stroke-width:2px
  • BEP-5 是所有一切的起点。
  • BEP-32BEP-45 共同解决了在现代IPv4/IPv6混合网络中的运行问题。
  • BEP-42 致力于提升网络的安全性,防止被恶意利用。
  • BEP-44BEP-51 则是在核心功能之上进行的能力扩展,前者开启了DHT作为通用去中心化数据库的大门,后者则极大地优化了资源发现的效率。

一个现代的、功能完备的BT客户端或DHT爬虫,通常会实现BEP-5、BEP-32,并至少作为客户端使用BEP-51的功能。其他扩展则根据其具体需求选择性实现。


DHT 协议规范
https://mazepeng.com/2025/07/24/dht/DHT技术规范/
作者
马泽朋
发布于
2025年7月24日
许可协议