A file transfer protocol over TCP/IP. One single connection client -> server, optionally supports gzip compression and TLS encryption. No checksum check because TCP already does it.
<--------- 4 bytes --------->
+------+------+-------------+
| TYPE | VER | SIZE |
+------+------+-------------+
| DATA |
| ... |
+---------------------------+
struct block_header_t {
uint8_t type;
uint8_t version;
uint16_t size;
};
Current protocol version is 1.3 (0x13).
No data. Size = 0
In which case data:
<--------- 4 bytes --------->
+------+-------------+------+
# CMD | SIZE | 0 |
+------+-------------+------+
# [TEXT ARG] OR NULL |
+---------------------------+
struct command_header_t {
uint8_t cmd;
uint16_t size;
};
Text arguments are NUL terminated C-strings one after another.
Directly raw file data. Could be a whole file smaller than block size, or one of the blocks of the file. Block size is defined in the client and the server independently. THe maximum block size is 65535 (0xffff).
Same as 2.1.3 but the data is gzip compressed.
No data. Size = 0.
<--------- 4 bytes --------->
+------+-------------+------+
| STAT | [SIZE] | 0 |
+------+-------------+------+
| [DATA] |
+---------------------------+
struct status_header_t {
uint8_t stat;
uint16_t size;
};
Same as 2.1.3.
Same as 2.1.4.
From client
No arguments.
No action performed.
Returns: NS
Text argument first: Username.2
Text argument second: Password.3
Returns: LOGGED or ELOGIN
No arguments. Returns: PWDD or EANON
No arguments.
Returns: LSD or EANON
Text argument: The name or path of a directory.1
Returns: ACK on success, or EANON, ENODIR, EACCESS or ESYS on error.
Text argument: The name or path of file to get.1
Returns: ACK on success, or EANON, NOFILE, EACCESS or ESYS on error.
The client should now receive 0x02 DATA blocks from server.
Text argument: The name or path of file to put.1
Returns: ACK on success, or EANON, EACCESS or ESYS on error.
The client should now transmit (C)DATA blocks to server.
Text argument: File or directory path to remove. Returns: ACK on success, or EANON, ENOFILE, ENODIR, ENOACCESS or ESYS on error.
No arguments. Triggers TLS handshake.
Result: The server accept()s a TLS handshake.
Inmediately followed by a TLS connect() by the client.
1Subject to system MAX_PATH, 4096 in Linux.
2Subject to system max username lenth, 32 in Linux.
3Subject to system max password lenth, infinite in Linux.
From server
No data.
No data. Result of succesful command.
Data contains NUL terminated C-string of the current directory
Data contains a number of entries, each as:
<--------- 4 bytes --------->
+---------------------------+
| MODE |
+---------------------------+
| UID +
+---------------------------+
| GID |
+---------------------------+
| SIZE |
| |
+---------------------------+
| MOD TIME |
| |
+---------------------------+
| NAME |
....
| |
+---------------------------+
struct dir_entry_t {
mode_t mode; // uint32_t
uid_t uid; // uint32_t
gid_t gid; // uint32_t
size_t size; // uint64_t
time_t mtime; // uint64_t
char name[256]; // last char is NUL
}
Each entry is henceforth 324 bytes
No data.
No data. Triggered by data commands.
No data.
No data.
No data.
No data.
Initial protocol. Basic file transfer. No login, gzip or encryption.
Added COMPRESSED DATA block, and ENCRYPT command. Backwards compatible.
Added LOGIN and appropiate status. Not backwards compatible.
Added PWD and CLOSE commands, and PWDD and EANON status. Not backwards compatible. Use only this version.
Removed CLOSE cmd and LOGGED status, replaced with the new RM cmd and ACK for LOGIN.
CMD STAT ESTAT
0x00 NC 0x00 NS
0x01 LOGIN 0x01 ACK 0x04 ELOGIN
0x02 PWD 0x02 PWDD 0x05 EANON
0x03 LS 0x03 LSD 0x05 EANON
0x04 CD 0x01 ACK 0x05 EANON, 0x06 ENODIR, 0x08 EACCESS, 0x09 ESYS
0x05 GET 0x01 ACK 0x05 EANON, 0x07 ENOFILE, 0x08 EACCESS, 0x09 ESYS
0x06 PUT 0x01 ACK 0x05 EANON, 0x08 EACCESS, 0x09 ESYS
0x07 RM 0x01 ACK 0x05 EANON, 0x06 ENODIR, 0x07 ENOFILE, 0x08 EACCESS, 0x09 ESYS
0x08 ENCRYPT <accept TLS>