# ssh2重构模块清单 **分析日期**: 2026-06-10 01:40 --- ## 一、现有模块分析 ### 需要重写的模块 | 模块 | 文件 | 代码行数 | 重写方式 | |------|------|----------|----------| | **SSH Server** | sftp/server.rs | 478行 | 完全重写(ssh2) | | **SFTP Handler** | sftp/handler.rs | 约500行 | 完全重写(ssh2) | | **SFTP Auth** | sftp/auth.rs | 37行 | 复用(bcrypt) | | **SFTP Config** | sftp/config.rs | 133行 | 复用 | | **SFTP FileTree** | sftp/filetree.rs | 141行 | 复用 | | **SCP Sender** | sftp/scp_sender.rs | 89行 | 移植到ssh2 | | **SCP Handler** | ssh2_mod/scp_handler.rs | 174行 | 移植到主模块 | | **rsync Receiver** | ssh2_mod/rsync_receiver.rs | 109行 | 移植到主模块 | | **rsync算法** | rsync/*.rs | 801行 | 复用 | --- ## 二、可复用代码 ### 100%复用(无需改动) | 模块 | 文件 | 说明 | |------|------|------| | **Auth系统** | sftp/auth.rs | bcrypt验证逻辑 | | **Config系统** | sftp/config.rs | SftpConfig结构 | | **FileTree映射** | sftp/filetree.rs | 路径映射逻辑 | | **rsync checksum** | rsync/checksum.rs | Rolling checksum算法 | | **rsync delta** | rsync/delta.rs | Delta算法 | | **rsync protocol** | rsync/protocol.rs | rsync协议常量 | | **SQLite数据库** | data/auth.sqlite | 用户认证数据 | --- ### 部分复用(需要适配) | 模块 | 文件 | 改动量 | |------|------|--------| | **SCP Sender** | scp_sender.rs | 约20行(适配ssh2::Channel) | | **SCP Handler** | scp_handler.rs | 约30行(适配ssh2::Channel) | | **rsync Handler** | rsync/handler.rs | 约50行(适配ssh2::Channel) | --- ## 三、需要完全重写的模块 ### SSH Server(约200行) **重写内容**: ```rust // ssh2_server.rs(新文件) use ssh2::Session; use std::net::{TcpListener, TcpStream}; pub struct Ssh2Server { config: Arc, } impl Ssh2Server { pub fn run(&self, port: u16) -> Result<()> { let listener = TcpListener::bind(("127.0.0.1", port))?; for stream in listener.incoming() { let stream = stream?; self.handle_connection(stream)?; } Ok(()) } fn handle_connection(&self, stream: TcpStream) -> Result<()> { let mut session = Session::new()?; session.set_tcp_stream(stream); session.handshake()?; // 认证 self.authenticate(&session)?; // 处理channel请求 self.handle_channels(&session)?; Ok(()) } } ``` --- ### SFTP Handler(约300行) **重写内容**: ```rust // sftp2_handler.rs(新文件) use ssh2::Channel; pub struct Sftp2Handler { user_id: String, config: Arc, } impl Sftp2Handler { pub fn handle_sftp(&self, channel: &mut Channel) -> Result<()> { // 14个SFTP操作 self.handle_init(channel)?; self.handle_open(channel)?; self.handle_read(channel)?; self.handle_write(channel)?; self.handle_close(channel)?; self.handle_mkdir(channel)?; self.handle_rmdir(channel)?; self.handle_remove(channel)?; self.handle_rename(channel)?; self.handle_opendir(channel)?; self.handle_readdir(channel)?; self.handle_realpath(channel)?; self.handle_stat(channel)?; self.handle_lstat(channel)?; Ok(()) } } ``` **关键改动**: - russh-sftp → 直接实现SFTP协议packet - 或使用ssh2::Channel::exec("sftp-server") --- ### SCP Handler(约200行) **重写内容**: ```rust // scp2_handler.rs(新文件) use ssh2::Channel; pub struct Scp2Handler { user_id: String, config: Arc, } impl Scp2Handler { pub fn handle_scp(&self, channel: &mut Channel, command: &str) -> Result<()> { if command.contains("-f") { self.handle_scp_sender(channel, command)?; } else if command.contains("-t") { self.handle_scp_receiver(channel, command)?; } else if command.contains("-r") { self.handle_scp_recursive(channel, command)?; } Ok(()) } fn handle_scp_sender(&self, channel: &mut Channel, command: &str) -> Result<()> { // scp -f:发送文件(write) let file_path = self.parse_path(command)?; let file_content = std::fs::read(&file_path)?; // 发送SCP header let header = self.build_scp_header(&file_path)?; channel.write_all(header.as_bytes())?; // 发送文件内容 channel.write_all(&file_content)?; // 发送结束标志 channel.write_all(&[0x00])?; channel.write_all("E\n".as_bytes())?; Ok(()) } fn handle_scp_receiver(&self, channel: &mut Channel, command: &str) -> Result<()> { // scp -t:接收文件(read) ⭐新增 channel.write_all(&[0x00])?; // 确认 // 读取SCP header let mut buf = vec![0u8; 8192]; let len = channel.read(&mut buf)?; let header = String::from_utf8_lossy(&buf[..len]); // 解析header获取文件名和大小 let (filename, size) = self.parse_scp_header(&header)?; // 读取文件内容 let mut file = File::create(&filename)?; let mut received = 0; while received < size { let len = channel.read(&mut buf)?; file.write_all(&buf[..len])?; received += len as u64; } Ok(()) } } ``` --- ### rsync Handler(约300行) **重写内容**: ```rust // rsync2_handler.rs(新文件) use ssh2::Channel; use crate::rsync::{ChecksumEngine, DeltaEngine}; pub struct Rsync2Handler { user_id: String, config: Arc, } impl Rsync2Handler { pub fn handle_rsync(&self, channel: &mut Channel, command: &str) -> Result<()> { if command.contains("--sender") { self.handle_rsync_sender(channel, command)?; } else if command.contains("--receiver") { self.handle_rsync_receiver(channel, command)?; } Ok(()) } fn handle_rsync_sender(&self, channel: &mut Channel, command: &str) -> Result<()> { // rsync sender(已有算法可移植) let file_path = self.parse_path(command)?; let checksums = ChecksumEngine::compute(&file_path)?; // 发送checksum channel.write_all(&checksums)?; // 接收delta请求 let mut buf = vec![0u8; 4096]; let len = channel.read(&mut buf)?; // ⭐ssh2支持read // 发送delta数据 let delta = DeltaEngine::compute(&file_path, &buf[..len])?; channel.write_all(&delta)?; Ok(()) } fn handle_rsync_receiver(&self, channel: &mut Channel, command: &str) -> Result<()> { // rsync receiver ⭐新增 let dest_path = self.parse_path(command)?; // 发送checksum请求 channel.write_all(&[RSYNC_CHECKSUM_REQUEST])?; // 接收checksum let mut checksums = vec![0u8; 4096]; channel.read_exact(&mut checksums)?; // ⭐ssh2支持read // 计算本地checksum let local_checksums = ChecksumEngine::compute(&dest_path)?; // 发送delta请求 let delta_request = self.build_delta_request(&checksums, &local_checksums)?; channel.write_all(&delta_request)?; // 接收delta数据 let mut delta_data = vec![0u8; 8192]; channel.read(&mut delta_data)?; // ⭐ssh2支持read // 应用delta DeltaEngine::apply(&dest_path, &delta_data)?; Ok(()) } } ``` --- ## 四、代码统计 ### 重写工作量 | 类别 | 代码行数 | 工作量 | |------|----------|--------| | **SSH Server** | 约200行 | Day 1 | | **SFTP Handler** | 约300行 | Day 2 | | **SCP Handler** | 约200行 | Day 3 | | **rsync Handler** | 约300行 | Day 4 | | **测试** | 约200行 | Day 5 | | **总计** | **约1200行** | **5天** | --- ### 可复用代码 | 类别 | 代码行数 | 复用率 | |------|----------|--------| | **Auth** | 37行 | 100% | | **Config** | 133行 | 100% | | **FileTree** | 141行 | 100% | | **rsync算法** | 801行 | 100% | | **总计** | **约1112行** | **100%复用** | --- ## 五、文件结构规划 ### 新文件结构 ``` markbase-core/src/ ├── ssh2_server/ # 新目录 │ ├── mod.rs # 模块导出 │ ├── server.rs # SSH Server核心(200行) │ ├── sftp_handler.rs # SFTP Handler(300行) │ ├── scp_handler.rs # SCP Handler(200行) │ ├── rsync_handler.rs # rsync Handler(300行) │ └── channel.rs # Channel管理(100行) │ ├── sftp/ # 保留部分 │ ├── auth.rs # 复用 ✅ │ ├── config.rs # 复用 ✅ │ ├── filetree.rs # 复用 ✅ │ └── server.rs # 删除 ❌ │ └── handler.rs # 删除 ❌ │ └── scp_sender.rs # 删除 ❌ │ ├── ssh2_mod/ # 合并到ssh2_server │ ├── scp_handler.rs # 合并 ⚠️ │ └── rsync_receiver.rs # 合并 ⚠️ │ └── rsync/ # 复用 ✅ ├── checksum.rs # 复用 ├── delta.rs # 复用 ├── protocol.rs # 复用 └── handler.rs # 需适配 ``` --- ## 六、迁移策略 ### 阶段性迁移 **Step 1**:创建ssh2_server目录 - 新建ssh2_server/mod.rs - 新建ssh2_server/server.rs **Step 2**:实现SSH Server核心 - Auth逻辑复用sftp/auth.rs - Config复用sftp/config.rs **Step 3**:实现SFTP Handler - 重写14个操作 - FileTree映射复用 **Step 4**:实现SCP Handler - 合并scp_sender.rs和scp_handler.rs - 完整sender + receiver **Step 5**:实现rsync Handler - 合并rsync算法 - 完整sender + receiver **Step 6**:删除旧russh代码 - 删除sftp/server.rs - 删除sftp/handler.rs - 删除ssh2_mod目录 --- ## 七、测试计划 ### 单元测试 | 测试项 | 文件 | |------|------| | **SSH连接测试** | tests/ssh2_connection_test.sh | | **Auth测试** | tests/auth_test.sh(复用) | | **SFTP测试** | tests/sftp_test.sh(适配) | | **SCP测试** | tests/scp_test.sh(新增) | | **rsync测试** | tests/rsync_test.sh(新增) | --- ### 功能测试 **SSH连接**: ```bash ssh -p 2023 warren@127.0.0.1 ``` **SFTP操作**: ```bash sftp -P 2023 warren@127.0.0.1 sftp> ls sftp> get file.txt sftp> put file.txt ``` **SCP操作**: ```bash # SCP下载(sender) scp -P 2023 warren@127.0.0.1:/path/file.txt /tmp/ # SCP上传(receiver)⭐新增 scp -P 2023 /tmp/file.txt warren@127.0.0.1:/path/ ``` **rsync操作**: ```bash # rsync下载(sender) rsync -av -e "ssh -p 2023" warren@127.0.0.1:/path/ /tmp/ # rsync上传(receiver)⭐新增 rsync -av -e "ssh -p 2023" /tmp/ warren@127.0.0.1:/path/ ``` --- **模块清单完成时间**: 2026-06-10 01:45 **版本**: 1.0