#file-transfer #reverse #resume #mode #broken #protocols #session

app yaftp

Yet another File Transfer Protocol support with resume broken transfer & reverse mode & largefile implementation by Rust

1 unstable release

0.1.2 Nov 25, 2021
0.1.1 Nov 24, 2021
0.1.0 Nov 24, 2021

#3 in #broken

MIT license

99KB
3K SLoC

yaftp Build Status ChatOnDiscord Crate

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