Phase 4: Implement SSH packet size limit (maxpack - 1024)
- 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:
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user