Files
utun2/src/member_files/protocol.h
T

73 lines
3.8 KiB
C

/* Файловый протокол участников CHAT-группы. Все числа на проводе little-endian.
* Группа и подписанный отправитель приходят от router; owner — UID каталога.
* version — непрозрачный снимок объекта, upload — случайный ID временного файла.
* Нулевая version в BEGIN означает создание; замена требует version из STAT.
* LIST: cursor — число уже выданных записей; version фиксирует снимок каталога.
* READ/WRITE: offset и size задают диапазон; WRITE.data_len обязан равняться size.
* COMMIT/MKDIR/RENAME/REMOVE: RESPONSE BUSY.cursor — срок до освобождения квитанции в0.1мс;
* 0 означает обычный повтор через5с. Общий клиентский срок120с не продлевается.
* Данные LIST — последовательность entry: name_len:2,type:1,size:8,mtime:8,version:16,name.
* Токены меняются при перезапуске сервера. Никаких ABI-зависимых структур в wire. */
#ifndef MEMBER_FILES_PROTOCOL_H
#define MEMBER_FILES_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MF_BLOCK_SIZE 8192
#define MF_PROTOCOL_VERSION 4
#define MF_PATH_MAX 1024
#define MF_NAME_MAX 255
#define MF_WIRE_HEADER 125
#define MF_WIRE_MAX (MF_WIRE_HEADER + 2 * MF_PATH_MAX + MF_BLOCK_SIZE)
#define MF_ENTRY_HEADER 35
#define MF_QUOTA_BYTES 40 /* used/limit/reserved в байтах, files/directories; пять u64 LE */
#define MF_AVATAR_MAX_BYTES (1024 * 1024)
#define MF_AVATAR_ORIGINAL_MAX_BYTES (32 * 1024 * 1024)
#define MF_AVATAR_MANIFEST_MAX_BYTES 4096
int mf_avatar_file_valid(const char* file);
int mf_avatar_manifest_valid(const char* file);
uint64_t mf_avatar_file_limit(const char* file);
#define MF_IDLE_TB 100000ULL /* 10 секунд */
#define MF_REPLAY_TB 1200000ULL /* Окно повторов запроса/успешной квитанции:120с. */
#define MF_REQUEST 1
#define MF_RESPONSE 2
#define MF_FILE 1
#define MF_DIRECTORY 2
/* MF_REMOVE — системный макрос Win32; для удаления файла/каталога используем отдельное имя. */
enum mf_command {
MF_LIST = 1, MF_STAT, MF_READ, MF_BEGIN_WRITE, MF_WRITE, MF_COMMIT, MF_ABORT, MF_MKDIR, MF_RENAME, MF_REMOVE_PATH,
MF_STREAM_WRITE, MF_STREAM_READ, MF_STREAM_DATA, MF_STREAM_END, MF_STREAM_CANCEL, MF_QUOTA
};
enum mf_status {
MF_OK, MF_ACCESS_DENIED, MF_NOT_FOUND, MF_INVALID_PATH, MF_INVALID_RANGE, MF_EXISTS,
MF_BUSY, MF_STALE, MF_NO_SPACE, MF_IO_ERROR, MF_BAD_PACKET, MF_HASH_MISMATCH, MF_CANCELLED, MF_TIMEOUT, MF_DIRECTORY_NOT_EMPTY
};
struct mf_message {
uint8_t kind, command, type, more;
uint16_t status;
uint64_t request_id, owner, offset, size, cursor, mtime;
uint8_t version[16], upload[16], hash[32];
char path[MF_PATH_MAX + 1], target[MF_PATH_MAX + 1];
uint32_t data_len;
uint8_t data[MF_BLOCK_SIZE];
};
uint64_t mf_get64(const uint8_t* p);
void mf_put64(uint8_t* p, uint64_t value);
int mf_zero(const uint8_t* p, size_t n);
/* Проверка UTF-8 и переносимых компонентов. Пустой путь допустим только для корня. */
int mf_path_valid(const char* path, int root_allowed);
int mf_encode(const struct mf_message* message, uint8_t* wire, size_t capacity);
int mf_decode(const uint8_t* wire, size_t length, struct mf_message* message);
const char* mf_status_text(int status);
const char* mf_command_text(int command);
#ifdef __cplusplus
}
#endif
#endif