diff --git a/data/rsync_1mb_verify.bin b/data/rsync_1mb_verify.bin new file mode 100644 index 0000000..db8e99d Binary files /dev/null and b/data/rsync_1mb_verify.bin differ diff --git a/data/scp_1mb_accumulation.bin b/data/scp_1mb_accumulation.bin new file mode 100644 index 0000000..db8e99d Binary files /dev/null and b/data/scp_1mb_accumulation.bin differ diff --git a/markbase-core/src/ssh_server/channel.rs b/markbase-core/src/ssh_server/channel.rs index a4d71b4..7122b0f 100644 --- a/markbase-core/src/ssh_server/channel.rs +++ b/markbase-core/src/ssh_server/channel.rs @@ -534,30 +534,56 @@ impl ChannelManager { return Ok(None); } - // Phase 7: 检查是否是SFTP channel + // Phase 7: 检查是否是SFTP channel(⭐⭐⭐⭐⭐ Phase 14.3: packet accumulation) if let Some(sftp_handler) = &mut channel.sftp_handler { info!("Processing SFTP request ({} bytes)", data.len()); - if data.len() < 5 { - warn!("SFTP data too short (less than 5 bytes)"); - return Ok(None); + // ⭐⭐⭐⭐⭐ Critical修复:累积SFTP packet数据 + channel.sftp_input_buffer.extend_from_slice(&data); + info!("SFTP buffer accumulated: {} bytes total", channel.sftp_input_buffer.len()); + + // 检查buffer是否有足够数据解析packet length + if channel.sftp_input_buffer.len() < 4 { + info!("SFTP buffer too short for length field, waiting for more data"); + return Ok(None); // 继续累积 } - let sftp_length = u32::from_be_bytes([data[0], data[1], data[2], data[3]]) as usize; + // 解析SFTP packet length(前4 bytes) + let sftp_length = u32::from_be_bytes([ + channel.sftp_input_buffer[0], + channel.sftp_input_buffer[1], + channel.sftp_input_buffer[2], + channel.sftp_input_buffer[3] + ]) as usize; info!("SFTP packet length field: {}", sftp_length); let expected_total = 4 + sftp_length; - if data.len() < expected_total { - warn!("SFTP packet incomplete: expected {} bytes, have {}", expected_total, data.len()); - return Ok(None); + if channel.sftp_input_buffer.len() < expected_total { + info!("SFTP packet incomplete: expected {} bytes, have {} bytes in buffer, waiting for more", + expected_total, channel.sftp_input_buffer.len()); + return Ok(None); // 继续累积 } - let sftp_packet = &data[4..expected_total]; + // ⭐⭐⭐⭐⭐ Buffer足够,解析完整SFTP packet + let sftp_packet = &channel.sftp_input_buffer[4..expected_total]; + info!("SFTP packet complete: {} bytes, processing", sftp_packet.len()); info!("SFTP packet content (first 20 bytes): {:?}", &sftp_packet[..std::cmp::min(20, sftp_packet.len())]); let response = sftp_handler.handle_request(sftp_packet)?; info!("SFTP response: {} bytes", response.len()); + // ⭐⭐⭐⭐⭐ 处理完后,清空buffer或保留剩余数据 + if channel.sftp_input_buffer.len() > expected_total { + // 有剩余数据(多个packets的情况) + let remaining = channel.sftp_input_buffer[expected_total..].to_vec(); + channel.sftp_input_buffer = remaining; + info!("SFTP buffer has remaining {} bytes after processing", channel.sftp_input_buffer.len()); + } else { + // 清空buffer + channel.sftp_input_buffer.clear(); + info!("SFTP buffer cleared after processing"); + } + // 构建SSH_MSG_CHANNEL_DATA返回SFTP响应(需要SSH string格式) return Ok(Some(self.build_channel_data(recipient_channel, &response)?)); } diff --git a/sftp_1mb_final.bin b/sftp_1mb_final.bin new file mode 100644 index 0000000..db8e99d Binary files /dev/null and b/sftp_1mb_final.bin differ