Skip to content

Commit

Permalink
feat: 常规更新
Browse files Browse the repository at this point in the history
  • Loading branch information
Cloaks committed Nov 15, 2024
1 parent bd03695 commit 65167c7
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
85 changes: 84 additions & 1 deletion docs/blog/posts/2024/11/13.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,87 @@ e

![](images/image-2.png)

这种机制使我们能够在进行过程中验证每个部分的完整性。它使 BitTorrent 能够抵御意外损坏或故意 torrent 中毒。除非攻击者能够通过原像攻击破坏 SHA-1,否则我们将准确获得我们所要求的内容。
这种机制使我们能够在进行过程中验证每个部分的完整性。它使 BitTorrent 能够抵御意外损坏或故意 torrent 中毒。除非攻击者能够通过原像攻击破坏 SHA-1,否则我们将准确获得我们所要求的内容。

编写一个 Bencode 解析器真的很有趣,但解析不是我们今天的重点。但我发现 Fredrik Lundh 的 50 行解析器特别具有启发性。对于这个项目,我使用了 github.com/jackpal/bencode-go:

```go title="bencode.go"
import (
"github.com/jackpal/bencode-go"
)

type bencodeInfo struct {
Pieces string `bencode:"pieces"`
PieceLength int `bencode:"piece length"`
Length int `bencode:"length"`
Name string `bencode:"name"`
}

type bencodeTorrent struct {
Announce string `bencode:"announce"`
Info bencodeInfo `bencode:"info"`
}

// Open parses a torrent file
func Open(r io.Reader) (*bencodeTorrent, error) {
bto := bencodeTorrent{}
err := bencode.Unmarshal(r, &bto)
if err != nil {
return nil, err
}
return &bto, nil
}
```

因为我喜欢保持结构相对平坦,并且喜欢将应用程序结构与序列化结构分开,所以我导出了一个不同的、更平坦的结构,名为 TorrentFile,并编写了一些辅助函数来在两者之间进行转换。

值得注意的是,我将片段(以前是字符串)分割成哈希值片段(每个 [20] 字节),以便稍后可以轻松访问各个哈希值。我还计算了整个编码信息字典(包含名称、大小和片段哈希值的字典)的 SHA-1 哈希值。我们将其称为 infohash,当我们与跟踪器和对等点对话时,它唯一地标识文件。稍后会详细介绍这一点。

![](images/image-3.png)

```go
type TorrentFile struct {
Announce string
InfoHash [20]byte
PieceHashes [][20]byte
PieceLength int
Length int
Name string
}

func (bto bencodeTorrent) toTorrentFile() (TorrentFile, error) {
//
}
```

## 从跟踪器检索对等点

现在我们有了有关文件及其跟踪器的信息,让我们与跟踪器交谈以宣布我们作为对等点的存在并检索其他对等点的列表。我们只需要向 .torrent 文件中提供的公告 URL 发出 GET 请求,并带有一些查询参数:

```go
func (t *TorrentFile) buildTrackerURL(peerID [20]byte, port uint16) (string, error) {
base, err := url.Parse(t.Announce)
if err != nil {
return "", err
}
params := url.Values{
"info_hash": []string{string(t.InfoHash[:])},
"peer_id": []string{string(peerID[:])},
"port": []string{strconv.Itoa(int(Port))},
"uploaded": []string{"0"},
"downloaded": []string{"0"},
"compact": []string{"1"},
"left": []string{strconv.Itoa(t.Length)},
}
base.RawQuery = params.Encode()
return base.String(), nil
}
```

重要的:

* info_hash:标识我们尝试下载的文件。这是我们之前根据编码后的信息字典计算出的信息哈希值。跟踪器将使用它来确定要向我们展示哪些对等点。

* peer_id:一个 20 字节的名称,用于向跟踪器和对等点标识我们自己。我们将为此生成 20 个随机字节。真正的 BitTorrent 客户端具有类似 -TR2940-k8hj0wgej6ch 的 ID,用于标识客户端软件和版本 - 在本例中,TR2940 代表 Transmission 客户端 2.94。

![](images/image-4.png)
Binary file added docs/blog/posts/2024/11/images/image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/blog/posts/2024/11/images/image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 65167c7

Please sign in to comment.