#文件传输 #反向 #恢复 #模式 #损坏 #协议 #会话

应用 yaftp

使用Rust实现的另一个文件传输协议,支持恢复损坏的传输、反向模式和大文件实现。

1 个不稳定版本

0.1.2 2021年11月25日
0.1.1 2021年11月24日
0.1.0 2021年11月24日

#5 in #损坏

MIT许可证

99KB
3K SLoC

yaftp 构建状态 ChatOnDiscord Crate

使用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