Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions .idea/rqbit.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ axum-extra = "0.12"
backon = "1.5"
base64 = "0.23"
bitvec = "1"
crypto-bigint = "0.7"
bstr = "1"
byteorder = "1"
bytes = "1"
Expand Down
58 changes: 58 additions & 0 deletions MSE-PR633-REFACTOR-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# MSE PR #633 重构(已实施):概要与决策记录

## 背景

rqbit PR #633 实现 MSE(消息流加密)。上游维护者 ikatson 提交 CHANGES_REQUESTED,本文件记录重构的完整梗概:维护者意见、已实施的改动、关键设计决策与验证结果。分支 `feat/mse-crypto-primitives`,单 commit `0402294c`(基于 `de2b107e`)。

## 一、维护者意见(CHANGES_REQUESTED)

主 review:**合并为单 commit**("It's not too big, so let's just shrink into one commit")+ 两大担忧:
1. **自写 crypto 太多**——应尽量用 crate(openssl 等,含硬件加速)
2. **spaghetti**——MSE 侵入 session/peer_connection 核心逻辑,建议抽象为 `connect_with_handshake` / `accept`

6 条 review comments:error.rs `MseForced` 去 SocketAddr、移除 Tcp-only 限制、去冗余行、RC4/DH 用 crate、session 抽象、uTP/socks 透明支持。

## 二、已实施的改动

### Phase 1 — 抽象层(解决 spaghetti)
- **出站**:`StreamConnector::connect_with_handshake()`(stream_connect.rs)——封装连接 + MSE 决策 + 握手发送,返回 `OutgoingHandshake { kind, read, write, mse_applied }`
- **入站**:`accept_with_handshake()` 自由函数 + `IncomingHandshake` 结构
- `session.rs`/`peer_connection.rs` 不再携带任何 MSE 细节(`IncomingOutcome`/`OutgoingOutcome`/`Sha1`/`AsyncReadExt` 全部收进 stream_connect)
- 移除 Tcp-only 限制:uTP/socks 透明支持 MSE
- `MseForced` 去 SocketAddr

### Phase 2 — 加密原语(解决自写 crypto)
- **DH-768 → `crypto-bigint`**:`Uint<12>` + `FixedMontyForm::pow`,删除手写 mod_reduce hack。MSE 固定 prime 硬编码(与 libtorrent/transmission/aria2 同值)。已验证外部 bigint 向量一致
- **RC4 → `rc4` crate**:
- 删除自实现 `mse/rc4.rs`(140 行)
- `Rc4Writer` 重写为**内循环方案**(参考 libtorrent `rc4_handler`):`poll_write` 加密整 buffer → 存 pending → 循环 flush,返回 `Ok(full_len)` 或 `Pending`,**绝不返回短写**(消除双加密 bug);Pending/短写密文缓存,重试不重复加密
- `Rc4Reader` 用 rc4 crate
- **PadB 扫描改 pattern-search**(libtorrent `read_pe_syncvc` / transmission `read_vc` 同款):独立实例算 VC 密文模式 → 字节搜索 → 解密实际 VC 验证,不再需要 clone
- SHA-1 用现有 `sha1w`(crate + 可选硬件加速后端)

### Phase 4 — squash
- `git reset --soft de2b107e` → 单 commit `0402294c`,21 文件 +1843/−32

## 三、关键设计决策

### RC4 保留自实现 vs 用 crate 的决策过程
1. 最初倾向保留自实现:RustCrypto `rc4` crate **无 `Clone`**,无法实现 `Rc4Writer` 短写保护(Pending 重试需试探状态)
2. 调研发现:libtorrent/transmission **都不用 clone**——用 **pattern-search**(搜索加密后的 VC 密文模式)而非"试探解密";`Rc4Writer` 短写用"加密与发送分离 + pending 缓冲"
3. 据此改用 rc4 crate:PadB 用 pattern-search,Rc4Writer 用内循环方案——**彻底绕开 clone 需求**

### 写错误处理(与三引擎一致)
libtorrent `disconnect(error, sock_write)`、transmission `call_error_callback`(非可重试)、aria2 `throw DL_RETRY_EX`(非 WOULDBLOCK)——**致命写错误一律断连**。rqbit 的 `poll_write` 对底层 `Poll::Pending` 返回 Pending(可重试,对应 EAGAIN),对 `Err` 传播(断连)。原测试 `write_error_does_not_advance_state`(错误后状态不推进)脱离真实场景,改为 `write_error_propagates`(错误传播 + sink 空)。

## 四、验证结果

- `cargo test -p librqbit --lib`:**45 passed / 0 failed / 5 ignored**
- stream:pending/short-write 状态保持、写错误传播
- mse:rc4 向量、dh768 外部向量、stream 包装、duplex 握手、明文嗅探回退、零长度 IA、分片前缀重放、fresh-redial、Disabled 单连接、Forced 失败、默认 Disabled 锁定
- `cargo check --all-targets`:0 error
- `cargo clippy`:新增改动 0 warning(剩余 5 个为基线既有 mod.rs cast/large-size 警告)

## 五、状态

- 单 commit `0402294c`(基于 `de2b107e`),工作区干净
- **未 push、未回复 PR**(按用户指示)
- 待办:回复维护者(含 pattern-search / 内循环方案说明)、force push
2 changes: 2 additions & 0 deletions crates/librqbit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ clone_to_owned.workspace = true
peer_binary_protocol.workspace = true
sha1w.workspace = true
dht.workspace = true
crypto-bigint.workspace = true
rc4 = "0.2"
librqbit-upnp.workspace = true
upnp-serve = { workspace = true, optional = true }

Expand Down
2 changes: 2 additions & 0 deletions crates/librqbit/examples/simulate_traffic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ impl TestHarness {
connect_timeout: Some(Duration::from_secs(1)),
read_write_timeout: Some(Duration::from_secs(32)),
keep_alive_interval: None,
..Default::default()
}),
}),
..Default::default()
Expand Down Expand Up @@ -274,6 +275,7 @@ impl TestHarness {
connect_timeout: Some(Duration::from_secs(1)),
read_write_timeout: Some(Duration::from_secs(32)),
keep_alive_interval: None,
..Default::default()
}),
}),
..Default::default()
Expand Down
2 changes: 2 additions & 0 deletions crates/librqbit/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub enum Error {
WrongInfoHash,
#[error("connecting to ourselves")]
ConnectingToOurselves,
#[error("MSE is forced, but the peer did not complete the MSE handshake")]
MseForced,

#[error("error writing handshake: {0:#}")]
WriteHandshake(#[source] std::io::Error),
Expand Down
2 changes: 2 additions & 0 deletions crates/librqbit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ mod ip_ranges;
pub mod limits;
mod listen;
mod merge_streams;
mod mse;
mod peer_connection;
mod peer_info_reader;
mod piece_tracker;
Expand Down Expand Up @@ -90,6 +91,7 @@ pub use create_torrent_file::{CreateTorrentOptions, CreateTorrentResult, create_
pub use dht;
pub use librqbit_core::spawn_utils::spawn as librqbit_spawn;
pub use listen::{ListenerMode, ListenerOptions};
pub use mse::MseMode;
pub use peer_connection::PeerConnectionOptions;
pub use session::{
AddTorrent, AddTorrentOptions, AddTorrentResponse, DhtSessionConfig, ListOnlyResponse,
Expand Down
Loading