1 个不稳定版本
0.1.2 | 2021年11月25日 |
---|---|
0.1.1 |
|
0.1.0 |
|
#5 in #损坏
99KB
3K SLoC
yaftp

使用Rust实现的另一个文件传输协议。
支持恢复损坏的传输、反向模式和大文件。
功能
- Async-std
- 无不安全代码
- 轻量级(单个可执行文件)
- 会话级别的持久性
- 支持Linux/Windows/Mac/BSD
- 支持大文件
- 支持恢复损坏的传输
- 支持反向模式(穿越防火墙)
构建和运行
$>cargo build--release
安装
$>cargo install yaftp
用法
绑定模式
您可以运行yaftp服务器并监听8000端口
$> ./yaftp-l8000
然后连接到服务器并获得一个shell
$> ./yaftp-c127.0.0.1 8000
反向模式
首先监听一个端口等待从机连接并获取shell
$> ./yaftp-t8000
然后反向连接从机中的主站
$> ./yaftp-r127.0.0.1 8000
协议(v1)
数据类型
+--------+-------------------+------------------+
| TYPE | EXTYPE | LENGTH(bytes) |
+--------+-------------------+------------------+
| string | utf-8 | Variable |
+--------+-------------------+------------------+
| path | utf-8 | < 1024 |
+--------+-------------------+------------------+
| u8 | be_uchar_8bit | 1 |
+--------+-------------------+------------------+
| u16 | be_uword_16bit | 2 |
+--------+-------------------+------------------+
| u32 | be_ulong_32bit | 4 |
+--------+-------------------+------------------+
| u64 | be_ull_64bit | 8 |
+--------+-------------------+------------------+
握手请求
+-------+----------+---------------+
| VER | NMETHODS | METHODS |
+-------+----------+---------------+
| 1(u8) | 1(u8) | 1 to 255 (u8) |
+-------+----------+---------------+
首次,客户端将发送客户端版本和支持的方法。
在1.0版本中,仅支持10种方法。
+------+-----------+
| CMD | VALUE |
+------+-----------+
| ls | 0x01 |
+------+-----------+
| cwd | 0x02 |
+------+-----------+
| cp | 0x03 |
+------+-----------+
| mkd | 0x04 |
+------+-----------+
| mv | 0x05 |
+------+-----------+
| rm | 0x06 |
+------+-----------+
| put | 0x07 |
+------+-----------+
| get | 0x08 |
+------+-----------+
| info | 0x09 |
+------+-----------+
| hash | 0x0a |
+------+-----------+
握手回复
+-------+----------+---------------+
| VER | NMETHODS | METHODS |
+-------+----------+---------------+
| 1(u8) | 1(u8) | 1 to 255 (u8) |
+-------+----------+---------------+
客户端将回复服务器版本和支持的方法。
命令请求
+-------+--------+
| CMD | NARG |
+-------+--------+
| 1(u8) | 4(u32) |
+-------+--------+
客户端向服务器发送命令消息,告诉服务器命令类型、参数数量和下一个参数的大小。
如果命令有两个或更多参数,客户端将一直发送参数消息,直到最后一个。
+-----------------+---------------------+
| NEXT_ARG_SIZE | ARG |
+-----------------+---------------------+
| 8(u64) | Variable |
+-----------------+---------------------+
接下来,我们需要知道每个命令参数和类型。
命令参数
+---------+------+---------------------------------+-----------------------+-----------------------+
| Command | NArg | Arg1 | Arg2 | Arg3 |
+---------+------+---------------------------------+-----------------------+-----------------------+
| ls | 1 | path [string](max 1024) | | |
| cwd | 0 | | | |
| cp | 2 | source path [string] | target path [string] | |
| mkd | 1 | path [string] | | |
| mv | 2 | source path [string] | target path [string] | |
| rm | 1 | path [string] | | |
| put | 4 | path [string] | start_pos[u64] | data[stream] |
| get | 4 | path [string] | start_pos[u64] | |
| info | 1 | path [string](max 1024) | | |
| hash | 1 | path [string](max 1024) | end_pos[u64] | |
+---------+------+---------------------------------+-----------------------+-----------------------+
命令回复
服务器接收到命令参数后,将检查其有效性并回复一个代码和参数数量。
+-----------+-----------+
| RETCODE | NARG |
+-----------+-----------+
| 1(u8) | 4(u32) |
+-----------+-----------+
如果检查有效则返回0x00,否则返回1~255。
+-----------+-----------------------------+
| RETCODE | Reason |
+-----------+-----------------------------+
| 1 | NoSupportVersion |
+-----------+-----------------------------+
| 2 | NoSupportCommand |
+-----------+-----------------------------+
| 3 | NoPermission |
+-----------+-----------------------------+
| 4 | NotFound |
+-----------+-----------------------------+
| 5 | StartPosError |
+-----------+-----------------------------+
| 6 | EndPosError |
+-----------+-----------------------------+
| 7 | ArgumentSizeError |
+-----------+-----------------------------+
| 8 | ArgumentError |
+-----------+-----------------------------+
| 9 | ArgumentCountError |
+-----------+-----------------------------+
| 10 | ReadFolderFaild |
+-----------+-----------------------------+
| 11 | ReadCwdFaild |
+-----------+-----------------------------+
| 12 | UTF8FormatError |
+-----------+-----------------------------+
| 13 | ReadFileError |
+-----------+-----------------------------+
| 14 | WriteFileError |
+-----------+-----------------------------+
| 15 | CalcMd5Error |
+-----------+-----------------------------+
| 16 | UnknownNetwordError |
+-----------+-----------------------------+
| 17 | UnknownError |
+-----------+-----------------------------+
注意:yaftp协议是全双工的,因此根据命令,返回的数据可能需要在命令参数完全发送后才能返回。因此,返回的数据需要异步处理。
命令回复格式
命令回复与命令请求相同。
+-----------------+---------------------+
| NEXT_ARG_SIZE | ARG |
+-----------------+---------------------+
| 8(u64) | Variable |
+-----------------+---------------------+
ls - 0x01
+---------+-----------+-----------------------+
| Command | NArg | ArgN |
+---------+-----------+-----------------------+
| ls | 0 or N | row(string) |
+---------+-----------+-----------------------+
命令 ls
将返回一个表格。每行由 |
分隔。
cwd - 0x02
+---------+-----------+-----------------------+
| Command | NArg | Arg1 |
+---------+-----------+-----------------------+
| cwd | 0 or 1 | path(string) |
+---------+-----------+-----------------------+
命令 cwd
返回服务器的当前工作目录。
cp - 0x03
+---------+------+
| Command | NArg |
+---------|------|
| cp | 0 |
+---------+------+
命令 cp
返回一个代码告诉客户端是否成功。
mkd - 0x04
+---------+------+
| Command | NArg |
+---------+------+
| mkd | 0 |
+---------+------+
命令 mkd
返回一个代码告诉客户端是否成功。
mv - 0x05
+---------+------+
| Command | NArg |
+---------+------+
| mv | 0 |
+---------+------+
命令 mv
返回一个代码告诉客户端是否成功。
rm - 0x06
+---------+------+
| Command | NArg |
+---------+------+
| rm | 0 |
+---------+------+
命令 rm
返回一个代码告诉客户端是否成功。
put - 0x07
+---------+-----------+
| Command | NArg |
+---------+-----------+
| put | 0 |
+---------+-----------+
命令 put
只返回一个代码告诉客户端是否成功。
get - 0x08
+---------+-----------+-----------------------+
| Command | NArg | Arg1 |
+---------+-----------+-----------------------+
| get | 0 or 1 | data(stream) |
+---------+-----------+-----------------------+
命令 get
如果返回代码为 0,将发送客户端请求文件数据。
info - 0x09
+---------+-----------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| Command | NArg | Arg1 | Arg2 | Arg3 | Arg4 | Arg5 |
+---------+-----------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| info | 0 or 5 | u8 | u64 | u64 | u64 | path(string) |
+---------+-----------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
命令 info
如果返回代码为 0,将返回 arg1(文件类型:0 是文件夹,1 是文件,其他是其他类型),arg2(文件大小),arg3(文件最后修改时间戳),arg4(文件最后访问时间戳),arg5(绝对路径)。
hash - 0x0a
+---------+-----------+-----------------------+
| Command | NArg | Arg1 |
+---------+-----------+-----------------------+
| hash | 0 or 1 | md5_32(string) |
+---------+-----------+-----------------------+
命令 hash
如果返回代码为 0,将返回请求文件数据的 MD5 哈希。
最后
服务器将关闭连接会话。
依赖
~12–23MB
~344K SLoC