775 lines
27 KiB
ReStructuredText
775 lines
27 KiB
ReStructuredText
.. _bep-v1:
|
|
|
|
Block Exchange Protocol v1
|
|
==========================
|
|
|
|
Introduction and Definitions
|
|
----------------------------
|
|
|
|
BEP is used between two or more *devices* thus forming a *cluster*. Each
|
|
device has one or more *folders* of files described by the *local
|
|
model*, containing metadata and block hashes. The local model is sent to
|
|
the other devices in the cluster. The union of all files in the local
|
|
models, with files selected for highest change version, forms the
|
|
*global model*. Each device strives to get its folders in sync with the
|
|
global model by requesting missing or outdated blocks from the other
|
|
devices in the cluster.
|
|
|
|
File data is described and transferred in units of *blocks*, each being
|
|
128 KiB (131072 bytes) in size.
|
|
|
|
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
|
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
|
document are to be interpreted as described in RFC 2119.
|
|
|
|
Transport and Authentication
|
|
----------------------------
|
|
|
|
BEP is deployed as the highest level in a protocol stack, with the lower
|
|
level protocols providing encryption and authentication.
|
|
|
|
::
|
|
|
|
+-----------------------------+
|
|
| Block Exchange Protocol |
|
|
|-----------------------------|
|
|
| Encryption & Auth (TLS 1.2) |
|
|
|-----------------------------|
|
|
| Reliable Transport |
|
|
|-----------------------------|
|
|
v ... v
|
|
|
|
The encryption and authentication layer SHALL use TLS 1.2 or a higher
|
|
revision. A strong cipher suite SHALL be used, with "strong cipher
|
|
suite" being defined as being without known weaknesses and providing
|
|
Perfect Forward Secrecy (PFS). Examples of strong cipher suites are
|
|
given at the end of this document. This is not to be taken as an
|
|
exhaustive list of allowed cipher suites but represents best practices
|
|
at the time of writing.
|
|
|
|
The exact nature of the authentication is up to the application, however
|
|
it SHALL be based on the TLS certificate presented at the start of the
|
|
connection. Possibilities include certificates signed by a common
|
|
trusted CA, preshared certificates, preshared certificate fingerprints
|
|
or certificate pinning combined with some out of band first
|
|
verification. The reference implementation uses preshared certificate
|
|
fingerprints (SHA-256) referred to as "Device IDs".
|
|
|
|
There is no required order or synchronization among BEP messages except
|
|
as noted per message type - any message type may be sent at any time and
|
|
the sender need not await a response to one message before sending
|
|
another.
|
|
|
|
The underlying transport protocol MUST guarantee reliable packet delivery.
|
|
|
|
In this document, in diagrams and text, "bit 0" refers to the *most
|
|
significant* bit of a word; "bit 15" is thus the least significant bit of a
|
|
16 bit word (int16) and "bit 31" is the least significant bit of a 32 bit
|
|
word (int32). Non protocol buffer integers are always represented in network
|
|
byte order (i.e., big endian) and are signed unless stated otherwise, but
|
|
when describing message lengths negative values do not make sense and the
|
|
most significant bit MUST be zero.
|
|
|
|
The protocol buffer schemas in this document are in ``proto3`` syntax. This
|
|
means, among other things, that all fields are optional and will assume
|
|
their default value when missing. This does not nececessarily mean that a
|
|
message is *valid* with all fields empty - for example, an index entry for a
|
|
file that does not have a name is not useful and MAY be rejected by the
|
|
implementation. However the folder label is for human consumption only so an
|
|
empty label should be accepted - the implementation will have to choose some
|
|
way to represent the folder, perhaps by using the ID in it's place or
|
|
automatically generating a label.
|
|
|
|
Pre-authentication messages
|
|
---------------------------
|
|
|
|
AFTER establishing a connection, but BEFORE performing any authentication,
|
|
devices MUST exchange Hello messages.
|
|
|
|
Hello messages are used to carry additional information about the peer,
|
|
which might be of interest to the user even if the peer is not permitted to
|
|
communicate due to failing authentication. Note that the certificate based
|
|
authentication may be considered part of the TLS handshake that precedes the
|
|
Hello message exchange, but even in the case that a connection is rejected a
|
|
Hello message must be sent before the connection is terminated.
|
|
|
|
Hello messages MUST be prefixed with an int32 containing the magic number
|
|
**0x2EA7D90B**, followed by an int16 representing the size of the message,
|
|
followed by the contents of the Hello message itself.
|
|
|
|
.. code-block:: none
|
|
|
|
0 1
|
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Magic |
|
|
| (32 bits) |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Length |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
/ /
|
|
\ Hello \
|
|
/ /
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
The Hello message itself is in protocol buffer format with the following schema:
|
|
|
|
.. code-block:: proto
|
|
|
|
message Hello {
|
|
string device_name = 1;
|
|
string client_name = 2;
|
|
string client_version = 3;
|
|
}
|
|
|
|
Fields (Hello message)
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The **device_name** is a human readable (configured or auto detected) device
|
|
name or host name, for the remote device.
|
|
|
|
The **client_name** and **client_version** identifies the implementation. The
|
|
values SHOULD be simple strings identifying the implementation name, as a
|
|
user would expect to see it, and the version string in the same manner. An
|
|
example client name is "syncthing" and an example client version is "v0.7.2".
|
|
The client version field SHOULD follow the patterns laid out in the `Semantic
|
|
Versioning <http://semver.org/>`__ standard.
|
|
|
|
Immediately after exchanging Hello messages, the connection MUST be dropped
|
|
if the remote device does not pass authentication.
|
|
|
|
Post-authentication Messages
|
|
----------------------------
|
|
|
|
Every message post authentication is made up of several parts:
|
|
|
|
- A header length word
|
|
- A **Header**
|
|
- A message length word
|
|
- A **Message**
|
|
|
|
.. code-block:: none
|
|
|
|
0 1
|
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Header Length |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
/ /
|
|
\ Header \
|
|
/ /
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Message Length |
|
|
| (32 bits) |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
/ /
|
|
\ Message \
|
|
/ /
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
The header length word is 16 bits. It indicates the length of the following
|
|
**Header** message. The Header is in protocol buffer format. The Header
|
|
describes the type and compression status of the following message.
|
|
|
|
The message is preceded by the 32 bit message length word and is one of the
|
|
concrete BEP messages described below, identified by the **type** field of
|
|
the Header.
|
|
|
|
As always, the length words are in network byte order (big endian).
|
|
|
|
.. code-block:: proto
|
|
|
|
message Header {
|
|
MessageType type = 1;
|
|
MessageCompression compression = 2;
|
|
}
|
|
|
|
enum MessageType {
|
|
CLUSTER_CONFIG = 0;
|
|
INDEX = 1;
|
|
INDEX_UPDATE = 2;
|
|
REQUEST = 3;
|
|
RESPONSE = 4;
|
|
DOWNLOAD_PROGRESS = 5;
|
|
PING = 6;
|
|
CLOSE = 7;
|
|
}
|
|
|
|
enum MessageCompression {
|
|
NONE = 0;
|
|
LZ4 = 1;
|
|
}
|
|
|
|
When the **compression** field is **NONE**, the message is directly in
|
|
protocol buffer format.
|
|
|
|
When the compression field is **LZ4**, the message consists of a 32 bit
|
|
integer describing the uncompressed message length followed by a single LZ4
|
|
block. After decompressing the LZ4 block it should be interpreted as a
|
|
protocol buffer message just as in the uncompressed case.
|
|
|
|
Message Subtypes
|
|
----------------
|
|
|
|
Cluster Config
|
|
^^^^^^^^^^^^^^
|
|
|
|
.. Documentation note: the structure of a message section is always:
|
|
1. A short description of the message
|
|
2. Protocol buffer schema of the message
|
|
3. Description of the fields in the message.
|
|
|
|
This informational message provides information about the cluster
|
|
configuration as it pertains to the current connection. A Cluster Config
|
|
message MUST be the first post authentication message sent on a BEP
|
|
connection. Additional Cluster Config messages MUST NOT be sent after the
|
|
initial exchange.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
message ClusterConfig {
|
|
repeated Folder folders = 1;
|
|
}
|
|
|
|
message Folder {
|
|
string id = 1;
|
|
string label = 2;
|
|
bool read_only = 3;
|
|
bool ignore_permissions = 4;
|
|
bool ignore_delete = 5;
|
|
bool disable_temp_indexes = 6;
|
|
|
|
repeated Device devices = 16;
|
|
}
|
|
|
|
message Device {
|
|
bytes id = 1;
|
|
string name = 2;
|
|
repeated string addresses = 3;
|
|
Compression compression = 4;
|
|
string cert_name = 5;
|
|
int64 max_local_version = 6;
|
|
bool introducer = 7;
|
|
}
|
|
|
|
enum Compression {
|
|
METADATA = 0;
|
|
NEVER = 1;
|
|
ALWAYS = 2;
|
|
}
|
|
|
|
Fields (Cluster Config Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. Documentation note: the first time a field is mentioned it is put in
|
|
**bold text**. We use the space separated names in running text and
|
|
snake_case in the protocol buffer schema.
|
|
|
|
The **folders** field contains the list of folders that will be synchronized
|
|
over the current connection.
|
|
|
|
Fields (Folder Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The **id** field contains the folder ID, which is the unique identifier of
|
|
the folder.
|
|
|
|
The **label** field contains the folder label, the human readable name of
|
|
the folder.
|
|
|
|
The **read only** field is set for folders that the device will accept no
|
|
updates from the network for.
|
|
|
|
The **ignore permissions** field is set for folders that the device will not
|
|
accept or announce file permissions for.
|
|
|
|
The **ignore delete** field is set for folders that the device will ignore
|
|
deletes for.
|
|
|
|
The **disable temp indexes** field is set for folders that will not dispatch
|
|
and do not wish to receive progress updates about partially downloaded files
|
|
via Download Progress messages.
|
|
|
|
The **devices** field is a list of devices participating in sharing this
|
|
folder.
|
|
|
|
Fields (Device Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The device **id** field is a 32 byte number that uniquely identifies the
|
|
device. For instance, the reference implementation uses the SHA-256 of the
|
|
device X.509 certificate.
|
|
|
|
The **name** field is a human readable name assigned to the described device
|
|
by the sending device. It MAY be empty and it need not be unique.
|
|
|
|
The list of **addresses** is that used by the sending device to connect to
|
|
the described device.
|
|
|
|
The **compression** field indicates the compression mode in use for this
|
|
device and folder. The following values are valid:
|
|
|
|
:0: Compress metadata. This enables compression of metadata messages such as Index.
|
|
:1: Compression disabled. No compression is used on any message.
|
|
:2: Compress always. Metadata messages as well as Response messages are compressed.
|
|
|
|
The **cert name** field indicates the expected certificate name for this
|
|
device. It is commonly blank, indicating to use the implementation default.
|
|
|
|
The **max local version** field contains the highest local file
|
|
version number of the files already known to be in the index sent by
|
|
this device. If nothing is known about the index of a given device, this
|
|
field MUST be set to zero. When receiving a Cluster Config message with
|
|
a non-zero Max Local Version for the local device ID, a device MAY elect
|
|
to send an Index Update message containing only files with higher local
|
|
version numbers in place of the initial Index message.
|
|
|
|
The **introducer** field is set for devices that are trusted as cluster
|
|
introducers.
|
|
|
|
Index and Index Update
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The Index and Index Update messages define the contents of the senders
|
|
folder. An Index message represents the full contents of the folder and
|
|
thus supersedes any previous index. An Index Update amends an existing
|
|
index with new information, not affecting any entries not included in
|
|
the message. An Index Update MAY NOT be sent unless preceded by an
|
|
Index, unless a non-zero Max Local Version has been announced for the
|
|
given folder by the peer device.
|
|
|
|
The Index and Index Update messages are currently identical in format,
|
|
although this is not guaranteed to be the case in the future.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
message Index {
|
|
string folder = 1;
|
|
repeated FileInfo files = 2;
|
|
}
|
|
|
|
message IndexUpdate {
|
|
string folder = 1;
|
|
repeated FileInfo files = 2;
|
|
}
|
|
|
|
message FileInfo {
|
|
string name = 1;
|
|
FileInfoType type = 2;
|
|
int64 size = 3;
|
|
uint32 permissions = 4;
|
|
int64 modified = 5;
|
|
bool deleted = 6;
|
|
bool invalid = 7;
|
|
bool no_permissions = 8;
|
|
Vector version = 9;
|
|
int64 local_version = 10;
|
|
|
|
repeated BlockInfo Blocks = 16;
|
|
}
|
|
|
|
enum FileInfoType {
|
|
FILE = 0;
|
|
DIRECTORY = 1;
|
|
SYMLINK_FILE = 2;
|
|
SYMLINK_DIRECTORY = 3;
|
|
SYMLINK_UNKNOWN = 4;
|
|
}
|
|
|
|
message BlockInfo {
|
|
int64 offset = 1;
|
|
int32 size = 2;
|
|
bytes hash = 3;
|
|
}
|
|
|
|
message Vector {
|
|
repeated Counter counters = 1;
|
|
}
|
|
|
|
message Counter {
|
|
uint64 id = 1;
|
|
uint64 value = 2;
|
|
}
|
|
|
|
Fields (Index Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The **folder** field identifies the folder that the index message pertains to.
|
|
|
|
The **files** field is a list of files making up the index information.
|
|
|
|
Fields (FileInfo Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The **name** is the file name path relative to the folder root. Like all
|
|
strings in BEP, the Name is always in UTF-8 NFC regardless of operating
|
|
system or file system specific conventions. The name field uses the slash
|
|
character ("/") as path separator, regardless of the implementation's
|
|
operating system conventions. The combination of folder and name uniquely
|
|
identifies each file in a cluster.
|
|
|
|
The **type** field contains the type of the described item. The type is one
|
|
of **file (0)**, **directory (1)**, **symlink to file (2)**, **symlink to
|
|
directory (3)**, or **symlink to unknown target (4)**. The distinction
|
|
between the various types of symlinks is not required on all operating
|
|
systems - the implementation SHOULD nonetheless indicate the target type
|
|
when possible.
|
|
|
|
The **size** field contains the size of the file, in bytes. For directories
|
|
the size is zero. For symlinks the size is the length of the target name.
|
|
|
|
The **permissions** field holds the common Unix permission bits. An
|
|
implementation MAY ignore or interpret these as is suitable on the host
|
|
operating system.
|
|
|
|
The **modified** time is expressed as the number of seconds since the Unix
|
|
Epoch (1970-01-01 00:00:00 UTC).
|
|
|
|
The **deleted** field is set when the file has been deleted. The block list
|
|
SHALL be of length zero and the modification time indicates the time of
|
|
deletion or, if the time of deletion is not reliably determinable, the last
|
|
known modification time.
|
|
|
|
The **invalid** field is set when the file is invalid and unavailable for
|
|
synchronization. A peer MAY set this bit to indicate that it can temporarily
|
|
not serve data for the file.
|
|
|
|
The **no permissions** field is set when there is no permission information
|
|
for the file. This is the case when it originates on a file system which
|
|
does not support permissions. Changes to only permission bits SHOULD be
|
|
disregarded on files with this bit set. The permissions bits MUST be set to
|
|
the octal value 0666.
|
|
|
|
The **version** field is a version vector describing the updates performed
|
|
to a file by all members in the cluster. Each counter in the version vector
|
|
is an ID-Value tuple. The ID is the first 64 bits of the device ID. The
|
|
Value is a simple incrementing counter, starting at zero. The combination of
|
|
Folder, Name and Version uniquely identifies the contents of a file at a
|
|
given point in time.
|
|
|
|
The **local version** field is the value of a device local monotonic clock
|
|
at the time of last local database update to a file. The clock ticks on
|
|
every local database update.
|
|
|
|
The **blocks** list contains the size and hash for each block in the file.
|
|
Each block represents a 128 KiB slice of the file, except for the last block
|
|
which may represent a smaller amount of data.
|
|
|
|
Request
|
|
^^^^^^^
|
|
|
|
The Request message expresses the desire to receive a data block
|
|
corresponding to a part of a certain file in the peer's folder.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
message Request {
|
|
int32 id = 1;
|
|
string folder = 2;
|
|
string name = 3;
|
|
int64 offset = 4;
|
|
int32 size = 5;
|
|
bytes hash = 6;
|
|
bool from_temporary = 7;
|
|
}
|
|
|
|
Fields
|
|
~~~~~~
|
|
|
|
The **id** is the request identifier. It will be matched in the
|
|
corresponding **Request** message. Each outstanding request must have a
|
|
unique ID.
|
|
|
|
The **folder** and **name** fields are as documented for the Index message.
|
|
The **offset** and **size** fields specify the region of the file to be
|
|
transferred. This SHOULD equate to exactly one block as seen in an Index
|
|
message.
|
|
|
|
The *hash* field MAY be set to the expected hash value of the block. If set,
|
|
the other device SHOULD ensure that the transmitted block matches the
|
|
requested hash. The other device MAY reuse a block from a different file and
|
|
offset having the same size and hash, if one exists.
|
|
|
|
The **from temporary** field is set to indicate that the read should be
|
|
performed from the temporary file (converting name to it's temporary form)
|
|
and falling back to the non temporary file if any error occurs. Knowledge of
|
|
contents of temporary files comes from DownloadProgress messages.
|
|
|
|
Response
|
|
^^^^^^^^
|
|
|
|
The Response message is sent in response to a Request message.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
message Response {
|
|
int32 id = 1;
|
|
bytes data = 2;
|
|
ErrorCode code = 3;
|
|
}
|
|
|
|
enum ErrorCode {
|
|
NO_ERROR = 0;
|
|
GENERIC = 1;
|
|
NO_SUCH_FILE = 2;
|
|
INVALID_FILE = 3;
|
|
}
|
|
|
|
Fields
|
|
~~~~~~
|
|
|
|
The **id** field is the request identifier. It must match the ID of the
|
|
**Request** that is being responded to.
|
|
|
|
The **data** field contains either the requested data block or is empty if
|
|
the requested block is not available.
|
|
|
|
The **code** field contains an error code describing the reason a Request
|
|
could not be fulfilled, in the case where zero length data was returned. The
|
|
following values are defined:
|
|
|
|
:0: No Error (data should be present)
|
|
|
|
:1: Generic Error
|
|
|
|
:2: No Such File (the requested file does not exist, or the offset is
|
|
outside the acceptable range for the file)
|
|
|
|
:3: Invalid (file exists but has invalid bit set or is otherwise
|
|
unavailable)
|
|
|
|
DownloadProgress
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
The DownloadProgress message is used to notify remote devices about partial
|
|
availability of files. By default, these messages are sent every 5 seconds,
|
|
and only in the cases where progress or state changes have been detected.
|
|
Each DownloadProgress message is addressed to a specific folder and MUST
|
|
contain zero or more FileDownloadProgressUpdate messages.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
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;
|
|
}
|
|
|
|
enum FileDownloadProgressUpdateType {
|
|
APPEND = 0;
|
|
FORGET = 1;
|
|
}
|
|
|
|
Fields (DownloadProgress Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The **folder** field represents the ID of the folder for which the update is
|
|
being provided.
|
|
|
|
The **updates** field is a list of progress update messages.
|
|
|
|
Fields (FileDownloadProgressUpdate Message)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The **update type** indicates whether the update is of type **append (0)**
|
|
(new blocks are available) or **forget (1)** (the file transfer has
|
|
completed or failed).
|
|
|
|
The **name** field defines the file name from the global index for which
|
|
this update is being sent.
|
|
|
|
The **version** message defines the version of the file for which this
|
|
update is being sent.
|
|
|
|
The **block indexes** field is a list of positive integers, where each
|
|
integer represents the index of the block in the FileInfo message Blocks
|
|
array that has become available for download.
|
|
|
|
For example an integer with value 3 represents that the data defined in the
|
|
fourth BlockInfo message of the FileInfo message of that file is now
|
|
available. Please note that matching should be done on **name** AND
|
|
**version**. Furthermore, each update received is incremental, for example
|
|
the initial update message might contain indexes 0, 1, 2, an update 5
|
|
seconds later might contain indexes 3, 4, 5 which should be appended to the
|
|
original list, which implies that blocks 0-5 are currently available.
|
|
|
|
Block indexes MAY be added in any order. An implementation MUST NOT assume
|
|
that block indexes are added in any specific order.
|
|
|
|
The **forget** field being set implies that previously advertised file is no
|
|
longer available, therefore the list of block indexes should be truncated.
|
|
|
|
Messages with the **forget** field set MUST NOT have any block indexes.
|
|
|
|
Any update message which is being sent for a different **version** of the
|
|
same file name must be preceded with an update message for the old version
|
|
of that file with the **forget** field set.
|
|
|
|
As a safeguard on the receiving side, the value of **version** changing
|
|
between update messages implies that the file has changed and that any
|
|
indexes previously advertised are no longer available. The list of available
|
|
block indexes MUST be replaced (rather than appended) with the indexes
|
|
specified in this message.
|
|
|
|
Ping
|
|
^^^^
|
|
|
|
The Ping message is used to determine that a connection is alive, and to
|
|
keep connections alive through state tracking network elements such as
|
|
firewalls and NAT gateways. A Ping message is sent every 90 seconds, if no
|
|
other message has been sent in the preceding 90 seconds.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
message Ping {
|
|
}
|
|
|
|
|
|
Close
|
|
^^^^^
|
|
|
|
The Close message MAY be sent to indicate that the connection will be torn
|
|
down due to an error condition. A Close message MUST NOT be followed by
|
|
further messages.
|
|
|
|
Protocol Buffer Schema
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. code-block:: proto
|
|
|
|
message Close {
|
|
string reason = 1;
|
|
}
|
|
|
|
Fields
|
|
~~~~~~
|
|
|
|
The **reason** field contains a human readable description of the error
|
|
condition.
|
|
|
|
Sharing Modes
|
|
-------------
|
|
|
|
Trusted
|
|
^^^^^^^
|
|
|
|
Trusted mode is the default sharing mode. Updates are exchanged in both
|
|
directions.
|
|
|
|
::
|
|
|
|
+------------+ Updates /---------\
|
|
| | -----------> / \
|
|
| Device | | Cluster |
|
|
| | <----------- \ /
|
|
+------------+ Updates \---------/
|
|
|
|
Read Only
|
|
^^^^^^^^^
|
|
|
|
In read only mode, a device does not apply any updates from the cluster, but
|
|
publishes changes of its local folder to the cluster as usual. The local
|
|
folder can be seen as a "master copy" that is never affected by the actions
|
|
of other cluster devices.
|
|
|
|
::
|
|
|
|
+------------+ Updates /---------\
|
|
| | -----------> / \
|
|
| Device | | Cluster |
|
|
| | \ /
|
|
+------------+ \---------/
|
|
|
|
Message Limits
|
|
--------------
|
|
|
|
An implementation MAY impose reasonable limits on the length of messages and
|
|
message fields to aid robustness in the face of corruption or broken
|
|
implementations. An implementation should strive to keep messages short
|
|
and to the point, favouring more and smaller messages over fewer and larger.
|
|
For example, favour a smaller Index message followed by one or more Index
|
|
Update messages rather than sending a very large Index message.
|
|
|
|
The Syncthing implementation imposes a hard limit of 500,000,000 bytes on
|
|
all messages. Attempting to send or receive a larger message will result in
|
|
a connection close. This size was chosen to accomodate Index messages
|
|
containing a large block list. It's intended that the limit may be further
|
|
reduced in a future protocol update supporting variable block sizes (and
|
|
thus shorter block lists for large files).
|
|
|
|
Example Exchange
|
|
----------------
|
|
|
|
=== ======================= ======================
|
|
# A B
|
|
=== ======================= ======================
|
|
1 ClusterConfiguration-> <-ClusterConfiguration
|
|
2 Index-> <-Index
|
|
3 IndexUpdate-> <-IndexUpdate
|
|
4 IndexUpdate->
|
|
5 Request->
|
|
6 Request->
|
|
7 Request->
|
|
8 Request->
|
|
9 <-Response
|
|
10 <-Response
|
|
11 <-Response
|
|
12 <-Response
|
|
13 Index Update->
|
|
...
|
|
14 <-Ping
|
|
15 Ping->
|
|
=== ======================= ======================
|
|
|
|
The connection is established and at 1. both peers send ClusterConfiguration
|
|
messages and then Index records. The Index records are received and both
|
|
peers recompute their knowledge of the data in the cluster. In this example,
|
|
peer A has four missing or outdated blocks. At 5 through 8 peer A sends
|
|
requests for these blocks. The requests are received by peer B, who
|
|
retrieves the data from the folder and transmits Response records (9 through
|
|
12). Device A updates their folder contents and transmits an Index Update
|
|
message (13). Both peers enter idle state after 13. At some later time 14,
|
|
the ping timer on device B expires and a Ping message is sent. The same
|
|
process occurs for device A at 15.
|
|
|
|
Examples of Strong Cipher Suites
|
|
--------------------------------
|
|
|
|
====== =========================== ==================================
|
|
ID Name Description
|
|
====== =========================== ==================================
|
|
0x009F DHE-RSA-AES256-GCM-SHA384 TLSv1.2 DH RSA AESGCM(256) AEAD
|
|
0x006B DHE-RSA-AES256-SHA256 TLSv1.2 DH RSA AES(256) SHA256
|
|
0xC030 ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 ECDH RSA AESGCM(256) AEAD
|
|
0xC028 ECDHE-RSA-AES256-SHA384 TLSv1.2 ECDH RSA AES(256) SHA384
|
|
0x009E DHE-RSA-AES128-GCM-SHA256 TLSv1.2 DH RSA AESGCM(128) AEAD
|
|
0x0067 DHE-RSA-AES128-SHA256 TLSv1.2 DH RSA AES(128) SHA256
|
|
0xC02F ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 ECDH RSA AESGCM(128) AEAD
|
|
0xC027 ECDHE-RSA-AES128-SHA256 TLSv1.2 ECDH RSA AES(128) SHA256
|
|
====== =========================== ==================================
|
|
|