没有合适的资源?快使用搜索试试~ 我知道了~
SFTP 源码浅析1
需积分: 0 7 下载量 193 浏览量
2022-08-08
19:14:26
上传
评论
收藏 229KB DOCX 举报
温馨提示
试读
14页
图1.1:整体框架图在interactive_loop中,程序从控制台读取后续的操作命令,并解析执行此调度命令(见parse_dispatch_command函
资源详情
资源评论
资源推荐
SFTP 源码浅析
1. 整体框架
当在终端通过 sftp 命令连接目标主机时,sftp 客户端程序便随之启动。客户端首
先启动 ssh 程序连接目标主机完成身份认证等操作。此后客户端进入循环等待,
等待用户命令交互,完成相关的文件传输任务。直到用户运行 exit 命令使程序退
出。
在连接目标主机前,程序首先初始化日志系统,用以记录程序运行过程中的日志、
错误、以及调试信息。此外,还将解析连接命令中的 URI 以及其他参数,获取
目标主机的用户和主机名等信息。然后结合连接命令中的参数等信息构建参数列
表 args.list。该参数列表将作为参数,启动 ssh 程序连接目标主机。
客户端调用 connect_to_server 函数完成与目标主机的连接。在 connect_to_server
函数中,使用使用 socketpair 创建套接字,并重定向至输入输出流。然后 fork 一
个子进程,子进程中调用 execvp 函数覆盖子进程空间,并运行 ssh 程序连接目
标主机(以 args.list 为命令行参数)。ssh 程序中完成了身份认证等一系列动作。
目标主机上的守护进程 sshd 监听到这个连接后启动 sftp-server 进程响应客户端
的后续请求。
结构体 sftp_conn 用以描述客户端到服务端的 sftp 连接。在实际连接建立后,父
进程(即 sftp 客户端)将对该连接进行初始化,即初始化一个 sftp_conn 类型的
结构体 conn。此后客户端进入循环交互等待(interactive_loop),根据后续的文
件传输命令(get、put 等)完成相应的文件传输操作。此时,客户端存在 sftp 进
程和 ssh 进程,服务端存在 sshd 进程和 sftp-server 进程。如图 1.1 所示。
图 1.1:整体框架图
在 interactive_loop 中,程序从控制台读取后续的操作命令,并解析执行此调度命
令(见 parse_dispatch_command 函数),执行完成后等待输入下一条命令,这个
过程不断循环,直至 exit 命令使程序退出。
parse_dispatch_command 函数的函数名带有一些迷惑性,事实上函数不但对调度
命令进行了解析(parse),还根据命令的类型(实际上是类型号)调用对应的
函数进行执行。所谓解析,主要是从命令中获取操作的类型,如 put 操作或者 get
操作等;附加参数,如-a:断点续传、-r:操作文件夹;源文件(夹)地址和目
标文件(夹)地址(如果有的话)等。
在客户端,每一种操作都被拆解为若干步骤,这些步骤以请求(request)的形式
发送给服务端。网络另一边的服务端在收到请求后,根据请求的类型和内容作出
响应,或写入数据、或回送状态、或传输数据等。服务端的原则是仅对客户端的
请求作出响应,并且不对客户端的操作做任何假设。任务的执行逻辑等均由客户
端决定。比如,数据的传输对于客户端来说是连续进行的(客户端连续切分数
据),但在服务端的视角里,仅仅是根据客户端要求的偏移量和长度发送(或写
入)指定数据。以 put 操作为例,如图 1.2 所示。
图 1.2:put 操作流程图
客户端首先发送一个 OPEN 请求给服务端,要求服务端打开(创建)文件,服
务端执行操作后给客户端会送一个状态(status)。之后客户端不断读取数据并
发送给服务端,服务端收到数据后将其写入相应的位置。这里需要说明的是,客
户端并非是在收到服务端的确认后再逐一发送下一组数据(这种方式效率太
低)。实际上,客户端维持了一个发送窗口(窗口大小 64),连续发送若干组
数据并使用一个队列存储未确认的数据请求。当客户端数据发送完成后,便向服
务端发送 CLOSE 请求,令其关闭文件。任务完成后,客户端回到交互循环等待
状态。
2. sftp-server 设计与实现
2.1 sftp_server_main 的整体设计
客户端在建立连接时,将创建好的 socket 套接字重定向至输入输出流。一端往输
出流中写入数据,另一端便从输入流中读取数据,进而实现了数据的传输。当然,
这是一个粗略的说法。但在 sftp 进程和 sftp-server 进程中,数据的发送只需要将
数据写入输出流即可,接收数据与之相反。sftp-server_main 函数的核心代码:
struct sshbuf *iqueue;
struct sshbuf *oqueue;
int sftp_server_main(...){
for (;;) {
剩余13页未读,继续阅读
尹子先生
- 粉丝: 19
- 资源: 324
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0