imfile.io
imfile.io

A Free And Unlimited BT / HTTP / HTTPS / eD2k Download Software From Singapore

BitTorrent 的 UDP Tracker 协议

简介

为了在一个 BitTorrent 下载群体中找到其他的节点,一个客户端会向一个追踪器发出宣告自己的请求。这个请求使用 HTTP 协议,并包含一些参数,比如 info_hashkeypeer_idportdownloadedleftuploadedcompact 等。追踪器会返回一组节点(主机和端口)以及其他一些信息给客户端。这个请求和响应都非常简短。由于使用的是 TCP 协议,需要在发送请求前打开连接,在完成请求后关闭连接,这会引入额外的开销。

系统开销

使用 HTTP 协议会带来很大的系统开销,因为在以太网层、 IP 层、 TCP 层和 HTTP 层都会有开销,并且一个请求加上响应包含 50 个节点需要使用大约 10 个数据包,总共使用的字节数约为 1206 。通过使用基于 UDP 的协议可以显著减少这种开销,本文提出的协议只需 4 个数据包和约 618 个字节,将流量减少了 50% 。虽然对于客户端来说每小时节省 1KB 并不重要,但对于为百万节点提供服务的 Tracker 来说,减少流量的 50% 非常重要。此外,基于 UDP 的二进制协议不需要复杂的解析器和连接处理,降低了 Tracker 代码的复杂性并提高了其性能。

UDP 连接 / 欺骗攻击

在理想情况下,只需要两个数据包就可以完成通信。在使用 UDP 协议时,由于 UDP 协议是无连接的,因此可能会存在伪造源地址的情况。因此,tracker 必须采取措施来确保不会出现欺骗行为。为了避免这种情况发生,Tracker(一个网络中用来协调客户端与其他 peer 之间数据共享的服务器程序)采取一些措施。

当客户端向 tracker 发送一个请求时,tracker 会生成一个随机数(connection_id),并将其发送给客户端。客户端再次向 tracker 发送请求时,需要带上这个 connection_id,以便 tracker 可以验证请求的来源是否合法。如果客户端伪造了源地址,则不可能收到 tracker 发回的 connection_id,从而请求会被 tracker 拒绝。

为了确保 connection_id 不被客户端猜测到,tracker 可以采用类似于 TCP 握手和 syn-cookie 的方法,在服务器端存储 connection_id,并仅在特定情况下才返回给客户端使用。一个 connection_id 可以用于多个请求,并且客户端可以在接收到 connection_id 后的一分钟内使用它。 tracker 应该在发出 connection_id 后的两分钟内接受它,并验证来自客户端的请求是否匹配这个 connection_id 。

超时

UDP 是一种不保证数据包可靠传输的协议,这意味着如果在传输过程中丢失了数据包,UDP 不会自动重传。相反,使用 UDP 的应用程序需要负责处理丢失的数据包,并在必要时进行重传。

为了处理丢失的数据包,客户端应该在发送请求后等待服务器的响应。如果在 15 * 2 ^ n 秒后没有收到响应,则客户端应该重新发送请求。重新发送请求的时间间隔从 15 秒开始,每次尝试都会加倍,最多尝试 8 次,即 3840 秒。

需要注意的是,如果连接 ID 已经过期,在重新发送请求之前需要重新请求新的连接 ID 。这确保了请求将被正确地认证并由服务器进行处理。

样例

常规广播:

t = 0: connect requestt = 1: connect responset = 2: announce requestt = 3: announce response

连接超时:

t = 0: connect requestt = 15: connect requestt = 45: connect requestt = 105: connect requestetc

广播超时:

t = 0:t = 0: connect requestt = 1: connect responset = 2: announce requestt = 17: announce requestt = 47: announce requestt = 107: connect request (because connection ID expired)t = 227: connect requestetc

多重请求:

t = 0: connect requestt = 1: connect responset = 2: announce requestt = 3: announce responset = 4: announce requestt = 5: announce responset = 60: announce requestt = 61: announce responset = 62: connect requestt = 63: connect responset = 64: announce requestt = 64: scrape requestt = 64: scrape requestt = 64: announce requestt = 65: announce responset = 66: announce responset = 67: scrape responset = 68: scrape response

UDP Tracker 协议

所有数值(例如整数或浮点数)在发送时都应该按照网络字节顺序(大端序)进行编码。此外,不应该预期每个数据包都具有确定的大小。因为将来可能会通过添加新功能来增加数据包的大小。

连接

Before announcing or scraping, you have to obtain a connection ID.

  1. Choose a random transaction ID.

  2. Fill the connect request structure.

  3. Send the packet.

对于进行”announcing” 或 “scraping” 操作之前,需要先获取一个连接 ID 的过程。步骤如下:

  1. 随机生成一个 Transaction ID 作为唯一标识符。

  2. 填充连接请求结构体。

  3. 发送请求数据包。

连接请求:

Offset  Size            Name            Value0       64-bit integer  protocol_id     0x41727101980 // magic constant8       32-bit integer  action          0 // connect12      32-bit integer  transaction_id16
  1. 接收数据包。

  2. 检查它的长度是否至少为 16 字节。

  3. 检查接收到的数据包中的 Transaction ID 是否与之前发送请求时选择的 ID 一致。

  4. 检查数据包中的操作是否为”connect” 。

  5. 将数据包中的 Connection ID 存储到本地,并用于后续操作。

连接响应:

Offset  Size            Name            Value0       32-bit integer  action          0 // connect4       32-bit integer  transaction_id8       64-bit integer  connection_id16

广播

  1. 从系统中随机选择一个 Transaction ID 。

  2. 填入一个广播请求结构。

  3. 发送数据包。

IPv4 广播请求:

Offset  Size    Name    Value0       64-bit integer  connection_id8       32-bit integer  action          1 // announce12      32-bit integer  transaction_id16      20-byte string  info_hash36      20-byte string  peer_id56      64-bit integer  downloaded64      64-bit integer  left72      64-bit integer  uploaded80      32-bit integer  event           0 // 0: none; 1: completed; 2: started; 3: stopped84      32-bit integer  IP address      0 // default88      32-bit integer  key92      32-bit integer  num_want        -1 // default96      16-bit integer  port98
  1. 接收数据包。

  2. 检查数据包的长度是否至少为 20 字节。

  3. 检查数据包中的交易 ID 是否与之前选择的交易 ID 相等,以确保接收到的是之前发送的通告请求的响应。

  4. 检查数据包中的操作是否为 “announce” 。

  5. 进行时间间隔检查。如果与上次广播请求时间不足一定时间间隔(interval 秒),则不再进行广播请求;否则,可以继续进行广播请求或等待事件触发后再次请求。

大多数 Tracker 只在某些特定情况下才会考虑 IP 地址字段。

IPv4 广播请求:

Offset      Size            Name            Value0           32-bit integer  action          1 // announce4           32-bit integer  transaction_id8           32-bit integer  interval12          32-bit integer  leechers16          32-bit integer  seeders20 + 6 * n  32-bit integer  IP address24 + 6 * n  16-bit integer  TCP port20 + 6 * N

IPv6

IPv6 和 IPv4 在协议结构上的区别以及如何在使用中进行适配。其中,IPv6 和 IPv4 的消息格式基本相同,但是在回应消息中,<IP地址、TCP端口>对的步进大小从 6 字节变成了 18 字节。此外,在请求消息中,IP 地址字段仍然是 32 位宽度,不能用于 IPv6,并且始终应该设置为 0 。

同时,该段落还提到了适配的方式:根据 UDP 包的地址族来确定所使用的格式,即来自 IPv4 地址的数据包使用 IPv4 格式,来自 IPv6 地址的数据包使用 IPv6 格式。最后,对于将主机名解析为 IPv4 和 IPv6 并向两个传输使用相同密钥的客户端,需要确保跟踪器能够准确地匹配两个通告,以实现准确统计。

抓取

最多可以同时获取约 74 个种子文件的信息。无法使用此协议完成完整的数据抓取。

  1. 随机选择一个 Transaction ID 。

  2. 填充抓取请求结构。

  3. 发送数据包。

抓取请求:

Offset          Size            Name            Value0               64-bit integer  connection_id8               32-bit integer  action          2 // scrape12              32-bit integer  transaction_id16 + 20 * n     20-byte string  info_hash16 + 20 * N
  1. 接受数据包。

  2. 检查数据包的长度是否至少为 8 字节。

  3. 检查该数据包中的 Transaction ID 是否与之前你选择的相同。

  4. 检查数据包中的操作是否为 “scrape” 。

抓取响应:

Offset      Size            Name            Value0           32-bit integer  action          2 // scrape4           32-bit integer  transaction_id8 + 12 * n  32-bit integer  seeders12 + 12 * n 32-bit integer  completed16 + 12 * n 32-bit integer  leechers8 + 12 * N

如果 tracker 遇到错误,可能会发送一个错误数据包。

  1. 接受数据包。

  2. 检查数据包的长度是否至少为 8 字节。

  3. 检查该数据包中的 Transaction ID 是否与之前你选择的相同。

错误

错误响应:

Offset  Size            Name            Value0       32-bit integer  action          3 // error4       32-bit integer  transaction_id8       string  message

现有实例

IMFile,Azureus,libtorrent,opentracker,XBT Client 和 XBT Tracker 支持该协议。

插件

为了保持协议的兼容性,一般不会在协议中包含扩展位或版本字段。客户端和 Tracker 也不应该假定数据包的大小。这样做可以在不破坏兼容性的情况下添加额外的字段。换句话说,通过避免固定数据包长度和格式,协议可以更容易地进行扩展和更新,并且可以保持向后兼容性。

总结

UDP Tracker Protocol for BitTorrent 是一种用于点对点文件共享协议 BitTorrent 中的追踪器通信协议。它是基于 UDP 协议的,相较于 HTTP 协议,可以更快地传输数据,同时也具有更好的扩展性和高效性。

通过 UDP Tracker Protocol,BitTorrent 客户端可以向追踪器发送请求,获取连接到种子的其他用户列表。这些用户可以帮助下载者提供文件块,提高下载速度。此外,追踪器还可以提供有关特定种子的统计信息,如上传和下载速度、剩余时间等。

尽管 UDP Tracker Protocol 具有许多优点,但由于其本质上是无状态的,因此在某些情况下可能会遇到一些问题,例如有时会丢失请求或响应。为了解决这些问题,很多 BitTorrent 客户端还支持 HTTP Tracker Protocol,同时使用两种不同的追踪器通信协议以提高可靠性。

参考链接

CC BY-NC-ND 4.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…

发布评论