1 unstable release
0.1.2 | Nov 25, 2021 |
---|---|
0.1.1 |
|
0.1.0 |
|
#3 in #broken
99KB
3K
SLoC
yaftp
Yet another File Transfer Protocol implementation by Rust.
Support with resume broken transfer & reverse mode & largefile.
Features
- Async-std
- No unsafe code
- Lightweight(Single executable)
- Per something per session
- Linux/Windows/Mac/BSD support
- Support large file
- Support Resume broken transfer
- Support reverse mode(cross firewall)
Build & Run
$> cargo build --release
Installation
$> cargo install yaftp
Usage
Bind Mode
You can run a yaftp server and listen port at 8000
$> ./yaftp -l 8000
then connect to server and get a shell
$> ./yaftp -c 127.0.0.1 8000
Reverse Mode
First listen a port waiting for slave connected and get shell
$> ./yaftp -t 8000
then reverse connect to master in slave
$> ./yaftp -r 127.0.0.1 8000
Protocol(v1)
Data Type
+--------+-------------------+------------------+
| 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 |
+--------+-------------------+------------------+
Handshake Request
+-------+----------+---------------+
| VER | NMETHODS | METHODS |
+-------+----------+---------------+
| 1(u8) | 1(u8) | 1 to 255 (u8) |
+-------+----------+---------------+
fisrt , client will send client version and support methods .
In version 1.0 , only support 10 methods.
+------+-----------+
| CMD | VALUE |
+------+-----------+
| ls | 0x01 |
+------+-----------+
| cwd | 0x02 |
+------+-----------+
| cp | 0x03 |
+------+-----------+
| mkd | 0x04 |
+------+-----------+
| mv | 0x05 |
+------+-----------+
| rm | 0x06 |
+------+-----------+
| put | 0x07 |
+------+-----------+
| get | 0x08 |
+------+-----------+
| info | 0x09 |
+------+-----------+
| hash | 0x0a |
+------+-----------+
Handshake Reply
+-------+----------+---------------+
| VER | NMETHODS | METHODS |
+-------+----------+---------------+
| 1(u8) | 1(u8) | 1 to 255 (u8) |
+-------+----------+---------------+
client will reply to server version and support methods.
Command Request
+-------+--------+
| CMD | NARG |
+-------+--------+
| 1(u8) | 4(u32) |
+-------+--------+
client send command message to server , tell server command type , arguments count , and next argument size.
if command has two arguments and above, client will keep send argument message until last one.
+-----------------+---------------------+
| NEXT_ARG_SIZE | ARG |
+-----------------+---------------------+
| 8(u64) | Variable |
+-----------------+---------------------+
next , we need know every command argument and type.
Command Arguments
+---------+------+---------------------------------+-----------------------+-----------------------+
| 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] | |
+---------+------+---------------------------------+-----------------------+-----------------------+
Command Reply
server received command arguments will check if valid and reply a code and arguments count.
+-----------+-----------+
| RETCODE | NARG |
+-----------+-----------+
| 1(u8) | 4(u32) |
+-----------+-----------+
if check vaild return 0x00 , else return 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 |
+-----------+-----------------------------+
Note : The yaftp protocol is full-duplex, so depending on the command, the returned data may not be returned until the command parameters are completely sent. Therefore, the returned data needs to be processed asynchronously.
Command Reply Format
command reply same with command request .
+-----------------+---------------------+
| NEXT_ARG_SIZE | ARG |
+-----------------+---------------------+
| 8(u64) | Variable |
+-----------------+---------------------+
ls - 0x01
+---------+-----------+-----------------------+
| Command | NArg | ArgN |
+---------+-----------+-----------------------+
| ls | 0 or N | row(string) |
+---------+-----------+-----------------------+
command ls
will return a table. every row split by |
.
cwd - 0x02
+---------+-----------+-----------------------+
| Command | NArg | Arg1 |
+---------+-----------+-----------------------+
| cwd | 0 or 1 | path(string) |
+---------+-----------+-----------------------+
command cwd
return server current work directory.
cp - 0x03
+---------+------+
| Command | NArg |
+---------|------|
| cp | 0 |
+---------+------+
command cp
return a code tell client if success.
mkd - 0x04
+---------+------+
| Command | NArg |
+---------+------+
| mkd | 0 |
+---------+------+
command mkd
return a code tell client if success.
mv - 0x05
+---------+------+
| Command | NArg |
+---------+------+
| mv | 0 |
+---------+------+
command mv
return a code tell client if success.
rm - 0x06
+---------+------+
| Command | NArg |
+---------+------+
| rm | 0 |
+---------+------+
command rm
return a code tell client if success.
put - 0x07
+---------+-----------+
| Command | NArg |
+---------+-----------+
| put | 0 |
+---------+-----------+
command put
just return a code tell client if success.
get - 0x08
+---------+-----------+-----------------------+
| Command | NArg | Arg1 |
+---------+-----------+-----------------------+
| get | 0 or 1 | data(stream) |
+---------+-----------+-----------------------+
command get
if retcode eq 0 will send client request file data.
info - 0x09
+---------+-----------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| Command | NArg | Arg1 | Arg2 | Arg3 | Arg4 | Arg5 |
+---------+-----------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| info | 0 or 5 | u8 | u64 | u64 | u64 | path(string) |
+---------+-----------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
command info
if retcode eq 0 will return arg1 (filetype : 0 is folder , 1 is file , other is others) , arg2(filesize) , arg3 (file last modify timestamp) , arg4 (file last accessed timestamp) , arg5 (absolute path).
hash - 0x0a
+---------+-----------+-----------------------+
| Command | NArg | Arg1 |
+---------+-----------+-----------------------+
| hash | 0 or 1 | md5_32(string) |
+---------+-----------+-----------------------+
command hash
if retcode eq 0 will return request file data md5 hash.
Finally
Server will close the connection session.
Dependencies
~12–24MB
~359K SLoC