# AnyTLS 代码架构与协议实现详解

本文档详细解析 AnyTLS 的代码结构与核心协议实现细节。

## 1. 总体架构

AnyTLS 是一个基于 TLS 1.3 的隧道代理工具，旨在将 SOCKS5 流量封装在标准的 TLS 连接中。其核心设计理念是**多路复用 (Multiplexing)**，即在一条物理 TLS 连接（Session）上承载多个逻辑数据流（Stream）。

### 核心组件
*   **Client (`bin/client`)**: 本地 SOCKS5 服务器，负责接收用户请求，通过 TLS 连接转发给 Server。
*   **Server (`bin/server`)**: 远程 TLS 服务器，负责解包 TLS 流量并转发到目标网站。
*   **Session (`proxy/session/inner.rs`)**: 管理一条物理 TLS 连接，负责帧（Frame）的读写、分发和心跳维护。
*   **Stream (`proxy/session/stream.rs`)**: 代表一个逻辑连接（如一次网页请求），提供类似 `TcpStream` 的读写接口。
*   **Pipe (`proxy/pipe`)**: 用于 Stream 与 Session 之间的高效异步数据缓冲通道。

---

## 2. 客户端流程 (`bin/client/main.rs`)

### 2.1 入口与初始化
*   程序启动后监听本地 SOCKS5 端口（默认 1080）。
*   初始化 `Client` 结构体 (`proxy/session/client.rs`)，配置连接池参数（空闲超时、最小空闲数等）。
*   **TLS 配置**: 使用 `rustls`，并配置了一个“危险”的证书验证器 `AllowAnyCertVerifier`，允许连接自签名证书的服务器。

### 2.2 SOCKS5 握手
当浏览器发起连接时：
1.  `handle_connection` 处理标准的 SOCKS5 握手（无需认证）。
2.  解析目标地址（IPv4/IPv6/Domain）。
3.  **建立隧道**: 调用 `client.create_stream()` 获取一个虚拟流 (`Stream`)。
4.  **发送目标地址**: 将 SOCKS5 请求中的目标地址直接写入 `Stream`。
5.  **数据转发**: 启动两个异步任务 (`c2p`, `p2c`) 在本地 TCP 连接和虚拟 `Stream` 之间双向拷贝数据。

### 2.3 连接池管理 (`proxy/session/client.rs`)
这是客户端的核心优化逻辑：
*   **复用策略**:
    1.  优先从 `idle_sessions` 池中获取空闲会话。
    2.  其次尝试复用活跃但负载较低（Stream 数 < 3）的会话。
    3.  最后才建立新的 TLS 连接。
*   **空闲回收**: `spawn_idle_waiter` 监控会话状态，当会话所有流关闭后，将其放回空闲池以备下次秒开。

---

## 3. 服务端流程 (`bin/server/main.rs`)

### 3.1 监听与接收
*   监听 TCP 端口（默认 8443）。
*   使用 `mkcert` 动态生成自签名证书。
*   **TCP 优化**: 开启 `TCP_NODELAY` 和 `TCP_KEEPALIVE`，确保低延迟和死链检测。

### 3.2 握手与鉴权
1.  **TLS 握手**: 建立标准 TLS 1.3 连接。
2.  **应用层鉴权**:
    *   读取前 34 字节：32 字节密码哈希 (SHA256) + 2 字节 Padding 长度。
    *   验证密码，失败则断开。
    *   读取并丢弃指定长度的 Padding 数据（用于混淆流量特征）。
3.  **会话创建**: 创建 `Session::new_server`，并传入回调函数处理新流。

### 3.3 目标连接
当 Session 收到新流请求 (`CMD_SYN`)：
1.  触发回调，读取流中的第一个数据包（包含 SOCKS5 目标地址）。
2.  `TcpStream::connect` 连接目标网站。
3.  **数据转发**: 在目标 TCP 连接和虚拟 `Stream` 之间双向拷贝数据。

---

## 4. 核心协议实现 (`proxy/session`)

### 4.1 帧结构 (`frame.rs`)
所有数据在 TLS 隧道中都被封装为“帧”：
```
+------+------+--------+------+
| CMD  | SID  | LEN    | DATA |
+------+------+--------+------+
| 1B   | 4B   | 2B     | Var  |
+------+------+--------+------+
```
*   **CMD (1B)**: 命令类型 (SYN, PSH, FIN, HEART_REQUEST 等)。
*   **SID (4B)**: 流 ID，用于区分不同的请求。
*   **LEN (2B)**: 数据载荷长度。
*   **DATA**: 实际数据。

### 4.2 会话管理 (`inner.rs`)
`Session` 是协议的心脏，负责多路复用：
*   **读循环 (`recv_loop`)**:
    *   从 TLS 连接读取字节流。
    *   解析帧头，提取 `CMD` 和 `SID`。
    *   **分发**:
        *   `CMD_PSH`: 找到对应的 `Stream`，将数据写入其 `Pipe`。
        *   `CMD_SYN`: (服务端) 创建新 `Stream` 并触发回调。
        *   `CMD_FIN`: 关闭对应 `Stream` 的写入端。
        *   `CMD_HEART_*`: 处理心跳，保持连接活跃。
*   **写操作**:
    *   使用 `mpsc::channel` 接收各 `Stream` 发来的帧。
    *   通过 `tokio::io::split` 分离出的 `WriteHalf` 写入 TLS 连接。
    *   **关键优化**: 每次写入后强制 `flush()`，配合 `TCP_NODELAY` 消除缓冲延迟。

### 4.3 流抽象 (`stream.rs`)
`Stream` 模拟了标准的 `AsyncRead` / `AsyncWrite` 接口：
*   **写数据**: 将数据封装为 `CMD_PSH` 帧，通过 `frame_tx` 发送给 Session。
*   **读数据**: 从内部的 `PipeReader` 读取由 Session 分发来的数据。
*   **关闭**: 发送 `CMD_FIN` 帧。为防止死锁，发送操作在后台异步任务中执行。

### 4.4 管道机制 (`proxy/pipe/io_pipe.rs`)
为了解决异步读写中的死锁和数据竞争，实现了一个自定义的 `Pipe`：
*   **结构**: 包含一个 `mpsc` 通道（用于数据传输）和一个字节缓冲区（用于暂存未读完的数据）。
*   **死锁解决**:
    *   `read` 操作在等待数据时**不持有锁**。
    *   利用 `mpsc` 的关闭特性（Sender Drop -> Receiver Return None）来优雅地处理 EOF，确保所有缓冲数据被读完后再返回结束信号。

---

## 5. 关键技术细节总结

1.  **并发模型**: 使用 Tokio 的异步任务 (`tokio::spawn`) 处理每个连接和流，实现高并发。
2.  **死锁预防**:
    *   Session 的读写分离 (`split`)。
    *   Stream 发送控制帧（如 FIN）时的异步化。
    *   Pipe 读取时的锁释放机制。
3.  **性能优化**:
    *   **连接复用**: 减少 TLS 握手开销。
    *   **Zero Copy**: 在可能的情况下尽量减少内存拷贝（虽然 Frame 封装不可避免会有一次拷贝）。
    *   **即时发送**: 强制 Flush 避免 Nagle 算法和 TLS 缓冲带来的延迟。
4.  **健壮性**:
    *   **Keepalive**: 应用层心跳 + TCP 层 Keepalive 双重保障，快速检测死链。
    *   **优雅关闭**: 确保 Session 和 Stream 的状态在网络异常时能正确同步，防止僵尸连接。

---

## 6. 核心数据流向总结

以下图表展示了从用户发起请求到目标网站接收数据的完整流向：

```mermaid
sequenceDiagram
    participant User as User (Browser)
    participant C_Main as Client (Main)
    participant C_Stream as Client Stream
    participant C_Session as Client Session
    participant Network as TLS Network
    participant S_Session as Server Session
    participant S_Stream as Server Stream
    participant S_Main as Server (Main)
    participant Target as Target Website

    Note over User, C_Main: SOCKS5 协议
    User->>C_Main: 发送数据 (Plain)
    
    Note over C_Main, C_Stream: 写入虚拟流
    C_Main->>C_Stream: stream.write(data)
    
    Note over C_Stream, C_Session: 封装为帧 (Frame)
    C_Stream->>C_Session: frame_tx.send(CMD_PSH)
    
    Note over C_Session, Network: 加密并发送
    C_Session->>Network: TLS Write + Flush
    
    Note over Network, S_Session: 接收并解密
    Network->>S_Session: TLS Read
    
    Note over S_Session, S_Stream: 解析帧并分发
    S_Session->>S_Stream: stream.push_data(data) (写入 Pipe)
    
    Note over S_Stream, S_Main: 读取虚拟流
    S_Main->>S_Stream: stream.read(buf) (从 Pipe 读取)
    
    Note over S_Main, Target: 转发到目标
    S_Main->>Target: TCP Write
```

---

## 7. 多路复用 (Multiplexing) 原理

AnyTLS 使用单条 TLS 连接承载多个逻辑流（Stream），极大地减少了握手延迟并提高了传输效率。

```mermaid
graph LR
    subgraph Client_Side [Client Side]
        UA[User A] -->|Data| SA[Stream 1]
        UB[User B] -->|Data| SB[Stream 2]
        UC[User C] -->|Data| SC[Stream 3]
        
        SA -.->|Frame: ID=1| Mux["Client Session<br/>(Multiplexer)"]
        SB -.->|Frame: ID=2| Mux
        SC -.->|Frame: ID=3| Mux
    end

    Mux ==>|"TLS Tunnel<br/>Frames: [ID=1][ID=2][ID=1][ID=3]..."| Demux["Server Session<br/>(Demultiplexer)"]

    subgraph Server_Side [Server Side]
        Demux -.->|Frame: ID=1| SSA[Stream 1]
        Demux -.->|Frame: ID=2| SSB[Stream 2]
        Demux -.->|Frame: ID=3| SSC[Stream 3]
        
        SSA -->|Data| TA[Target A]
        SSB -->|Data| TB[Target B]
        SSC -->|Data| TC[Target C]
    end
    
    style Mux fill:#f96,stroke:#333,stroke-width:2px
    style Demux fill:#f96,stroke:#333,stroke-width:2px
```
