Phase 4: Implement SSH packet size limit (maxpack - 1024)
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

- Add maxpack field to SftpHandler structure
- Modify SftpHandler::new() to accept maxpack parameter
- Limit SSH_FXP_READ data size to maxpack - 1024 bytes (OpenSSH style)
- Get maxpack from Channel.remote_maxpacket

Changes:
- sftp_handler.rs: SftpHandler struct + new() + handle_read()
- channel.rs: Pass remote_maxpacket to SftpHandler::new()

Reference: OpenSSH sftp-server.c: process_read()
- Limit: maxpacket - 1024 bytes
- Prevent packet size violation

Test status: 5MB upload still incomplete (2.0MB)
- Issue may require additional debugging
- Upload direction may also need maxpack limit
This commit is contained in:
Warren
2026-06-17 20:18:21 +08:00
parent 70353d2a55
commit cacf106b80
2 changed files with 23 additions and 3 deletions

View File

@@ -460,7 +460,15 @@ impl ChannelManager {
// Phase 7: 初始化SFTP handler
let root_dir = PathBuf::from("/Users/accusys/markbase"); // 默认root目录
let sftp_handler = SftpHandler::new(root_dir);
// ⭐⭐⭐⭐⭐ Phase 4: 获取 client maxpack 限制(从 Channel 中获取)
let maxpacket = if let Some(ch) = self.channels.get(&channel) {
ch.remote_maxpacket // 来自 SSH_MSG_CHANNEL_OPEN 的 maximum_packet_size
} else {
32768 // OpenSSH 默认值32KB
};
let sftp_handler = SftpHandler::new(root_dir, maxpacket); // ⭐⭐⭐⭐⭐ Phase 4: 传入 maxpack
// 存储到channel
if let Some(ch) = self.channels.get_mut(&channel) {

View File

@@ -256,15 +256,19 @@ pub struct SftpHandler {
root_dir: PathBuf,
next_handle_id: u32,
handles: std::collections::HashMap<u32, SftpHandle>,
// ⭐⭐⭐⭐⭐ Phase 4: 添加 client maxpack 限制参考OpenSSH sftp-server.c
maxpacket: u32, // 来自 SSH_MSG_CHANNEL_OPEN_CONFIRMATION 的 maximum_packet_size
}
impl SftpHandler {
pub fn new(root_dir: PathBuf) -> Self {
// ⭐⭐⭐⭐⭐ Phase 4: 修改 new() 方法,接受 maxpack 参数
pub fn new(root_dir: PathBuf, maxpacket: u32) -> Self {
let canonical_root = root_dir.canonicalize().unwrap_or(root_dir);
Self {
root_dir: canonical_root,
next_handle_id: 0,
handles: std::collections::HashMap::new(),
maxpacket, // ⭐⭐⭐⭐⭐ Phase 4: client maxpack 限制
}
}
@@ -420,7 +424,15 @@ impl SftpHandler {
if let Some(ref mut file) = handle.file {
file.seek(SeekFrom::Start(offset))?;
let mut buffer = vec![0u8; length as usize];
// ⭐⭐⭐⭐⭐ Phase 4: 限制数据大小,不超过 maxpacket - 1024参考OpenSSH sftp-server.c
// OpenSSH sftp-server.c: process_read() 中限制数据大小为 maxpacket - 1024 bytes
// SSH packet overhead: ~1024 bytes (SSH header + SSH_FXP_DATA header)
let max_data_size = self.maxpacket - 1024;
let actual_length = std::cmp::min(length, max_data_size);
info!("SSH_FXP_READ limited: requested={}, actual={}", length, actual_length);
let mut buffer = vec![0u8; actual_length as usize];
match file.read(&mut buffer) {
Ok(0) => {
self.build_status_response(id, SftpStatus::SSH_FX_EOF, "End of file")