mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-18 02:55:16 +00:00
c6334e61aa
This adds the ability to have multiple concurrent connections to a single device. This is primarily useful when the network has multiple physical links for aggregated bandwidth. A single connection will never see a higher rate than a single link can give, but multiple connections are load-balanced over multiple links. It is also incidentally useful for older multi-core CPUs, where bandwidth could be limited by the TLS performance of a single CPU core -- using multiple connections achieves concurrency in the required crypto calculations... Co-authored-by: Simon Frei <freisim93@gmail.com> Co-authored-by: tomasz1986 <twilczynski@naver.com> Co-authored-by: bt90 <btom1990@googlemail.com>
259 lines
7.1 KiB
Protocol Buffer
259 lines
7.1 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
package protocol;
|
|
|
|
import "ext.proto";
|
|
import "repos/protobuf/gogoproto/gogo.proto";
|
|
|
|
// --- Pre-auth ---
|
|
|
|
message Hello {
|
|
string device_name = 1;
|
|
string client_name = 2;
|
|
string client_version = 3;
|
|
int32 num_connections = 4;
|
|
int64 timestamp = 5;
|
|
}
|
|
|
|
// --- Header ---
|
|
|
|
message Header {
|
|
MessageType type = 1;
|
|
MessageCompression compression = 2;
|
|
}
|
|
|
|
enum MessageType {
|
|
MESSAGE_TYPE_CLUSTER_CONFIG = 0;
|
|
MESSAGE_TYPE_INDEX = 1;
|
|
MESSAGE_TYPE_INDEX_UPDATE = 2;
|
|
MESSAGE_TYPE_REQUEST = 3;
|
|
MESSAGE_TYPE_RESPONSE = 4;
|
|
MESSAGE_TYPE_DOWNLOAD_PROGRESS = 5;
|
|
MESSAGE_TYPE_PING = 6;
|
|
MESSAGE_TYPE_CLOSE = 7;
|
|
}
|
|
|
|
enum MessageCompression {
|
|
MESSAGE_COMPRESSION_NONE = 0;
|
|
MESSAGE_COMPRESSION_LZ4 = 1 [(ext.enumgoname) = "MessageCompressionLZ4"];
|
|
}
|
|
|
|
// --- Actual messages ---
|
|
|
|
// Cluster Config
|
|
|
|
message ClusterConfig {
|
|
repeated Folder folders = 1;
|
|
bool secondary = 2;
|
|
}
|
|
|
|
message Folder {
|
|
string id = 1 [(ext.goname) = "ID"];
|
|
string label = 2;
|
|
bool read_only = 3;
|
|
bool ignore_permissions = 4;
|
|
bool ignore_delete = 5;
|
|
bool disable_temp_indexes = 6;
|
|
bool paused = 7;
|
|
|
|
repeated Device devices = 16;
|
|
}
|
|
|
|
message Device {
|
|
bytes id = 1 [(ext.goname) = "ID", (ext.device_id) = true];
|
|
string name = 2;
|
|
repeated string addresses = 3;
|
|
Compression compression = 4;
|
|
string cert_name = 5;
|
|
int64 max_sequence = 6;
|
|
bool introducer = 7;
|
|
uint64 index_id = 8 [(ext.goname) = "IndexID", (ext.gotype) = "IndexID"];
|
|
bool skip_introduction_removals = 9;
|
|
bytes encryption_password_token = 10;
|
|
}
|
|
|
|
enum Compression {
|
|
COMPRESSION_METADATA = 0;
|
|
COMPRESSION_NEVER = 1;
|
|
COMPRESSION_ALWAYS = 2;
|
|
}
|
|
|
|
// Index and Index Update
|
|
|
|
message Index {
|
|
string folder = 1;
|
|
repeated FileInfo files = 2;
|
|
}
|
|
|
|
message IndexUpdate {
|
|
string folder = 1;
|
|
repeated FileInfo files = 2;
|
|
}
|
|
|
|
message FileInfo {
|
|
option (gogoproto.goproto_stringer) = false;
|
|
|
|
// The field ordering here optimizes for struct size / alignment --
|
|
// large types come before smaller ones.
|
|
|
|
string name = 1;
|
|
int64 size = 3;
|
|
int64 modified_s = 5;
|
|
uint64 modified_by = 12 [(ext.gotype) = "ShortID"];
|
|
Vector version = 9;
|
|
int64 sequence = 10;
|
|
repeated BlockInfo blocks = 16;
|
|
string symlink_target = 17;
|
|
bytes blocks_hash = 18;
|
|
bytes encrypted = 19;
|
|
FileInfoType type = 2;
|
|
uint32 permissions = 4;
|
|
int32 modified_ns = 11;
|
|
int32 block_size = 13 [(ext.goname) = "RawBlockSize"];
|
|
PlatformData platform = 14;
|
|
|
|
// The local_flags fields stores flags that are relevant to the local
|
|
// host only. It is not part of the protocol, doesn't get sent or
|
|
// received (we make sure to zero it), nonetheless we need it on our
|
|
// struct and to be able to serialize it to/from the database.
|
|
uint32 local_flags = 1000;
|
|
|
|
// The version_hash is an implementation detail and not part of the wire
|
|
// format.
|
|
bytes version_hash = 1001;
|
|
|
|
// The time when the inode was last changed (i.e., permissions, xattrs
|
|
// etc changed). This is host-local, not sent over the wire.
|
|
int64 inode_change_ns = 1002;
|
|
|
|
// The size of the data appended to the encrypted file on disk. This is
|
|
// host-local, not sent over the wire.
|
|
int32 encryption_trailer_size = 1003;
|
|
|
|
bool deleted = 6;
|
|
bool invalid = 7 [(ext.goname) = "RawInvalid"];
|
|
bool no_permissions = 8;
|
|
}
|
|
|
|
enum FileInfoType {
|
|
FILE_INFO_TYPE_FILE = 0;
|
|
FILE_INFO_TYPE_DIRECTORY = 1;
|
|
FILE_INFO_TYPE_SYMLINK_FILE = 2 [deprecated = true];
|
|
FILE_INFO_TYPE_SYMLINK_DIRECTORY = 3 [deprecated = true];
|
|
FILE_INFO_TYPE_SYMLINK = 4;
|
|
}
|
|
|
|
message BlockInfo {
|
|
option (gogoproto.goproto_stringer) = false;
|
|
bytes hash = 3;
|
|
int64 offset = 1;
|
|
int32 size = 2;
|
|
uint32 weak_hash = 4;
|
|
}
|
|
|
|
message Vector {
|
|
repeated Counter counters = 1;
|
|
}
|
|
|
|
message Counter {
|
|
uint64 id = 1 [(ext.goname) = "ID", (ext.gotype) = "ShortID"];
|
|
uint64 value = 2;
|
|
}
|
|
|
|
message PlatformData {
|
|
UnixData unix = 1 [(gogoproto.nullable) = true];
|
|
WindowsData windows = 2 [(gogoproto.nullable) = true];
|
|
XattrData linux = 3 [(gogoproto.nullable) = true];
|
|
XattrData darwin = 4 [(gogoproto.nullable) = true];
|
|
XattrData freebsd = 5 [(gogoproto.nullable) = true, (ext.goname) = "FreeBSD"];
|
|
XattrData netbsd = 6 [(gogoproto.nullable) = true, (ext.goname) = "NetBSD"];
|
|
}
|
|
|
|
message UnixData {
|
|
// The owner name and group name are set when known (i.e., could be
|
|
// resolved on the source device), while the UID and GID are always set
|
|
// as they come directly from the stat() call.
|
|
string owner_name = 1;
|
|
string group_name = 2;
|
|
int32 uid = 3 [(ext.goname) = "UID"];
|
|
int32 gid = 4 [(ext.goname) = "GID"];
|
|
}
|
|
|
|
message WindowsData {
|
|
// Windows file objects have a single owner, which may be a user or a
|
|
// group. We keep the name of that account, and a flag to indicate what
|
|
// type it is.
|
|
string owner_name = 1;
|
|
bool owner_is_group = 2;
|
|
}
|
|
|
|
message XattrData {
|
|
repeated Xattr xattrs = 1;
|
|
}
|
|
|
|
message Xattr {
|
|
string name = 1;
|
|
bytes value = 2;
|
|
}
|
|
|
|
// Request
|
|
|
|
message Request {
|
|
int32 id = 1 [(ext.goname) = "ID"];
|
|
string folder = 2;
|
|
string name = 3;
|
|
int64 offset = 4;
|
|
int32 size = 5;
|
|
bytes hash = 6;
|
|
bool from_temporary = 7;
|
|
uint32 weak_hash = 8;
|
|
int32 block_no = 9;
|
|
}
|
|
|
|
// Response
|
|
|
|
message Response {
|
|
int32 id = 1 [(ext.goname) = "ID"];
|
|
bytes data = 2;
|
|
ErrorCode code = 3;
|
|
}
|
|
|
|
enum ErrorCode {
|
|
ERROR_CODE_NO_ERROR = 0;
|
|
ERROR_CODE_GENERIC = 1;
|
|
ERROR_CODE_NO_SUCH_FILE = 2;
|
|
ERROR_CODE_INVALID_FILE = 3;
|
|
}
|
|
|
|
// DownloadProgress
|
|
|
|
message DownloadProgress {
|
|
string folder = 1;
|
|
repeated FileDownloadProgressUpdate updates = 2;
|
|
}
|
|
|
|
message FileDownloadProgressUpdate {
|
|
FileDownloadProgressUpdateType update_type = 1;
|
|
string name = 2;
|
|
Vector version = 3;
|
|
repeated int32 block_indexes = 4 [packed=false];
|
|
int32 block_size = 5;
|
|
}
|
|
|
|
enum FileDownloadProgressUpdateType {
|
|
FILE_DOWNLOAD_PROGRESS_UPDATE_TYPE_APPEND = 0;
|
|
FILE_DOWNLOAD_PROGRESS_UPDATE_TYPE_FORGET = 1;
|
|
}
|
|
|
|
// Ping
|
|
|
|
message Ping {
|
|
}
|
|
|
|
// Close
|
|
|
|
message Close {
|
|
string reason = 1;
|
|
}
|
|
|