Documentation
¶
Overview ¶
Package protocol implements the Block Exchange Protocol.
Index ¶
- Constants
- Variables
- func BlockSize(fileSize int64) int
- func BlocksHash(bs []BlockInfo) []byte
- func DecryptBytes(data []byte, key *[keySize]byte) ([]byte, error)
- func IsEncryptedParent(pathComponents []string) bool
- func IsVersionMismatch(err error) bool
- func ModTimeEqual(a, b time.Time, modTimeWindow time.Duration) bool
- func PasswordToken(keyGen *KeyGenerator, folderID, password string) []byte
- func PermsEqual(a, b uint32) bool
- func TotalInOut() (int64, int64)
- func VectorHash(v Vector) []byte
- type BlockInfo
- type ClusterConfig
- type Compression
- type Connection
- type ConnectionInfo
- type Counter
- type Device
- type DeviceID
- func (n DeviceID) Compare(other DeviceID) int
- func (n DeviceID) Equals(other DeviceID) bool
- func (n DeviceID) GoString() string
- func (n DeviceID) MarshalText() ([]byte, error)
- func (n *DeviceID) MarshalTo(bs []byte) (int, error)
- func (*DeviceID) ProtoSize() int
- func (n DeviceID) Short() ShortID
- func (n DeviceID) String() string
- func (n *DeviceID) Unmarshal(bs []byte) error
- func (n *DeviceID) UnmarshalText(bs []byte) error
- type DownloadProgress
- type ErrorCode
- type FileDownloadProgressUpdate
- type FileDownloadProgressUpdateType
- type FileInfo
- func (f FileInfo) BlockSize() int
- func (f FileInfo) BlocksEqual(other FileInfo) bool
- func (f FileInfo) FileBlocksHash() []byte
- func (f FileInfo) FileLocalFlags() FlagLocal
- func (f FileInfo) FileModifiedBy() ShortID
- func (f FileInfo) FileName() string
- func (f FileInfo) FilePermissions() uint32
- func (f FileInfo) FileSize() int64
- func (f FileInfo) FileType() FileInfoType
- func (f FileInfo) FileVersion() Vector
- func (f FileInfo) HasPermissionBits() bool
- func (f FileInfo) InodeChangeTime() time.Time
- func (f FileInfo) IsDeleted() bool
- func (f FileInfo) IsDirectory() bool
- func (f FileInfo) IsEquivalent(other FileInfo, modTimeWindow time.Duration) bool
- func (f FileInfo) IsEquivalentOptional(other FileInfo, comp FileInfoComparison) bool
- func (f FileInfo) IsIgnored() bool
- func (f FileInfo) IsInvalid() bool
- func (f FileInfo) IsReceiveOnlyChanged() bool
- func (f FileInfo) IsSymlink() bool
- func (f FileInfo) IsUnsupported() bool
- func (f FileInfo) ModTime() time.Time
- func (f FileInfo) MustRescan() bool
- func (f FileInfo) PlatformData() PlatformData
- func (f FileInfo) SequenceNo() int64
- func (f *FileInfo) SetDeleted(by ShortID)
- func (f *FileInfo) SetIgnored()
- func (f *FileInfo) SetMustRescan()
- func (f *FileInfo) SetUnsupported()
- func (f FileInfo) ShouldConflict() bool
- func (f FileInfo) String() string
- func (f *FileInfo) ToWire(withInternalFields bool) *bep.FileInfo
- func (f *FileInfo) WinsConflict(other FileInfo) bool
- type FileInfoComparison
- type FileInfoType
- type FileInfoWithoutBlocks
- type FlagLocal
- type Folder
- type Hello
- type Index
- type IndexID
- type IndexUpdate
- type KeyGenerator
- type Model
- type Ordering
- type PlatformData
- type Request
- type RequestResponse
- type Response
- type ShortID
- type Statistics
- type UnixData
- type Vector
- func (v Vector) Compare(b Vector) Ordering
- func (v Vector) Concurrent(b Vector) bool
- func (v Vector) Copy() Vector
- func (v Vector) Counter(id ShortID) uint64
- func (v Vector) DropOthers(id ShortID) Vector
- func (v Vector) Equal(b Vector) bool
- func (v Vector) GreaterEqual(b Vector) bool
- func (v Vector) IsEmpty() bool
- func (v Vector) LesserEqual(b Vector) bool
- func (v Vector) Merge(b Vector) Vector
- func (v *Vector) String() string
- func (v *Vector) ToWire() *bep.Vector
- func (v Vector) Update(id ShortID) Vector
- type WindowsData
- type Xattr
- type XattrData
Constants ¶
const ( CompressionMetadata = bep.Compression_COMPRESSION_METADATA CompressionNever = bep.Compression_COMPRESSION_NEVER CompressionAlways = bep.Compression_COMPRESSION_ALWAYS )
const ( FileDownloadProgressUpdateTypeAppend = bep.FileDownloadProgressUpdateType_FILE_DOWNLOAD_PROGRESS_UPDATE_TYPE_APPEND FileDownloadProgressUpdateTypeForget = bep.FileDownloadProgressUpdateType_FILE_DOWNLOAD_PROGRESS_UPDATE_TYPE_FORGET )
const ( FileInfoTypeFile = bep.FileInfoType_FILE_INFO_TYPE_FILE FileInfoTypeDirectory = bep.FileInfoType_FILE_INFO_TYPE_DIRECTORY FileInfoTypeSymlinkFile = bep.FileInfoType_FILE_INFO_TYPE_SYMLINK_FILE FileInfoTypeSymlinkDirectory = bep.FileInfoType_FILE_INFO_TYPE_SYMLINK_DIRECTORY FileInfoTypeSymlink = bep.FileInfoType_FILE_INFO_TYPE_SYMLINK )
const ( HelloMessageMagic uint32 = 0x2EA7D90B Version13HelloMagic uint32 = 0x9F79BC40 // old )
const ( ErrorCodeNoError = bep.ErrorCode_ERROR_CODE_NO_ERROR ErrorCodeGeneric = bep.ErrorCode_ERROR_CODE_GENERIC ErrorCodeNoSuchFile = bep.ErrorCode_ERROR_CODE_NO_SUCH_FILE ErrorCodeInvalidFile = bep.ErrorCode_ERROR_CODE_INVALID_FILE )
const ( DeviceIDLength = 32 // keep consistent with shortIDStringLength in gui/default/syncthing/app.js ShortIDStringLength = 7 )
const ( // Shifts KiB = 10 MiB = 20 GiB = 30 )
const ( // MaxMessageLen is the largest message size allowed on the wire. (500 MB) MaxMessageLen = 500 * 1000 * 1000 // MinBlockSize is the minimum block size allowed MinBlockSize = 128 << KiB // MaxBlockSize is the maximum block size allowed MaxBlockSize = 16 << MiB // DesiredPerFileBlocks is the number of blocks we aim for per file DesiredPerFileBlocks = 2000 SyntheticDirectorySize = 128 )
const ( // PingSendInterval is how often we make sure to send a message, by // triggering pings if necessary. PingSendInterval = 90 * time.Second // ReceiveTimeout is the longest we'll wait for a message from the other // side before closing the connection. ReceiveTimeout = 300 * time.Second )
Variables ¶
var ( // ErrTooOldVersion is returned by ExchangeHello when the other side // speaks an older, incompatible version of the protocol. ErrTooOldVersion = errors.New("the remote device speaks an older version of the protocol not compatible with this version") // ErrUnknownMagic is returned by ExchangeHello when the other side // speaks something entirely unknown. ErrUnknownMagic = errors.New("the remote device speaks an unknown (newer?) version of the protocol") )
var ( LocalDeviceID = repeatedDeviceID(0xff) GlobalDeviceID = repeatedDeviceID(0xf8) EmptyDeviceID = DeviceID{} )
var ( ErrGeneric = errors.New("generic error") ErrNoSuchFile = errors.New("no such file") ErrInvalid = errors.New("file is invalid") )
var ( ErrClosed = errors.New("connection closed") ErrTimeout = errors.New("read timeout") )
var BlockSizes []int
BlockSizes is the list of valid block sizes, from min to max
var BufferPool *bufferPool
Global pool to get buffers from. Initialized in init().
var CloseTimeout = 10 * time.Second
CloseTimeout is the longest we'll wait when trying to send the close message before just closing the connection. Should not be modified in production code, just for testing.
Functions ¶
func BlocksHash ¶
func DecryptBytes ¶
DecryptBytes returns the decrypted bytes, or an error if decryption failed.
func IsEncryptedParent ¶
IsEncryptedParent returns true if the path points at a parent directory of encrypted data, i.e. is not a "real" directory. This is determined by checking for a sentinel string in the path.
func IsVersionMismatch ¶
IsVersionMismatch returns true if the error is a reliable indication of a version mismatch that we might want to alert the user about.
func PasswordToken ¶
func PasswordToken(keyGen *KeyGenerator, folderID, password string) []byte
func PermsEqual ¶
func TotalInOut ¶
func VectorHash ¶
Types ¶
type BlockInfo ¶
func BlockInfoFromWire ¶
type ClusterConfig ¶
type Compression ¶
type Compression = bep.Compression
type Connection ¶
type Connection interface {
// Send an Index message to the peer device. The message in the
// parameter may be altered by the connection and should not be used
// further by the caller.
Index(ctx context.Context, idx *Index) error
// Send an Index Update message to the peer device. The message in the
// parameter may be altered by the connection and should not be used
// further by the caller.
IndexUpdate(ctx context.Context, idxUp *IndexUpdate) error
// Send a Request message to the peer device. The message in the
// parameter may be altered by the connection and should not be used
// further by the caller.
Request(ctx context.Context, req *Request) ([]byte, error)
// Send a Cluster Configuration message to the peer device. The message
// in the parameter may be altered by the connection and should not be
// used further by the caller.
// For any folder that must be encrypted for the connected device, the
// password must be provided.
ClusterConfig(config *ClusterConfig, passwords map[string]string)
// Send a Download Progress message to the peer device. The message in
// the parameter may be altered by the connection and should not be used
// further by the caller.
DownloadProgress(ctx context.Context, dp *DownloadProgress)
Start()
Close(err error)
DeviceID() DeviceID
Statistics() Statistics
Closed() <-chan struct{}
ConnectionInfo
}
func NewConnection ¶
func NewConnection(deviceID DeviceID, reader io.Reader, writer io.Writer, closer io.Closer, model Model, connInfo ConnectionInfo, compress Compression, keyGen *KeyGenerator) Connection
type ConnectionInfo ¶
type DeviceID ¶
type DeviceID [DeviceIDLength]byte
func DeviceIDFromBytes ¶
DeviceIDFromBytes converts a 32 byte slice to a DeviceID. A slice of the wrong length results in an error.
func DeviceIDFromString ¶
DeviceIDFromString parses a device ID from a string. The string is expected to be in the canonical format, with check digits.
func NewDeviceID ¶
NewDeviceID generates a new device ID from SHA256 hash of the given piece of data (usually raw certificate bytes).
func (DeviceID) MarshalText ¶
func (*DeviceID) UnmarshalText ¶
type DownloadProgress ¶
type DownloadProgress struct {
Folder string
Updates []FileDownloadProgressUpdate
}
type FileDownloadProgressUpdate ¶
type FileDownloadProgressUpdate struct {
UpdateType FileDownloadProgressUpdateType
Name string
Version Vector
BlockIndexes []int
BlockSize int
}
type FileDownloadProgressUpdateType ¶
type FileDownloadProgressUpdateType = bep.FileDownloadProgressUpdateType
type FileInfo ¶
type FileInfo struct {
Name string
Size int64
ModifiedS int64
ModifiedBy ShortID
Version Vector
Sequence int64
Blocks []BlockInfo
SymlinkTarget []byte
BlocksHash []byte
Encrypted []byte
Platform PlatformData
Type FileInfoType
Permissions uint32
ModifiedNs int32
RawBlockSize int32
// 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.
// It does carry the info to decide if the file is invalid, which is part of
// the protocol.
LocalFlags FlagLocal
// The version_hash is an implementation detail and not part of the wire
// format.
VersionHash []byte
// The time when the inode was last changed (i.e., permissions, xattrs
// etc changed). This is host-local, not sent over the wire.
InodeChangeNs int64
// The size of the data appended to the encrypted file on disk. This is
// host-local, not sent over the wire.
EncryptionTrailerSize int
Deleted bool
NoPermissions bool
// contains filtered or unexported fields
}
func DecryptFileInfo ¶
func DecryptFileInfo(keyGen *KeyGenerator, fi FileInfo, folderKey *[keySize]byte) (FileInfo, error)
DecryptFileInfo extracts the encrypted portion of a FileInfo, decrypts it and returns that.
func FileInfoFromDB ¶
func FileInfoFromDBTruncated ¶
func FileInfoFromDBTruncated(w FileInfoWithoutBlocks) FileInfo
func FileInfoFromWire ¶
func (FileInfo) BlocksEqual ¶
BlocksEqual returns true when the two files have identical block lists.
func (FileInfo) FileBlocksHash ¶
func (FileInfo) FileLocalFlags ¶
func (FileInfo) FileModifiedBy ¶
func (FileInfo) FilePermissions ¶
func (FileInfo) FileType ¶
func (f FileInfo) FileType() FileInfoType
func (FileInfo) FileVersion ¶
func (FileInfo) HasPermissionBits ¶
func (FileInfo) InodeChangeTime ¶
func (FileInfo) IsDirectory ¶
func (FileInfo) IsEquivalent ¶
func (FileInfo) IsEquivalentOptional ¶
func (f FileInfo) IsEquivalentOptional(other FileInfo, comp FileInfoComparison) bool
func (FileInfo) IsReceiveOnlyChanged ¶
func (FileInfo) IsUnsupported ¶
func (FileInfo) MustRescan ¶
func (FileInfo) PlatformData ¶
func (f FileInfo) PlatformData() PlatformData
func (FileInfo) SequenceNo ¶
func (*FileInfo) SetDeleted ¶
func (*FileInfo) SetIgnored ¶
func (f *FileInfo) SetIgnored()
func (*FileInfo) SetMustRescan ¶
func (f *FileInfo) SetMustRescan()
func (*FileInfo) SetUnsupported ¶
func (f *FileInfo) SetUnsupported()
func (FileInfo) ShouldConflict ¶
func (*FileInfo) WinsConflict ¶
WinsConflict returns true if "f" is the one to choose when it is in conflict with "other".
type FileInfoComparison ¶
type FileInfoType ¶
type FileInfoType = bep.FileInfoType
type FileInfoWithoutBlocks ¶
type FileInfoWithoutBlocks interface {
GetName() string
GetSize() int64
GetModifiedS() int64
GetModifiedBy() uint64
GetVersion() *bep.Vector
GetSequence() int64
// GetBlocks() []*bep.BlockInfo // not included
GetSymlinkTarget() []byte
GetBlocksHash() []byte
GetEncrypted() []byte
GetType() FileInfoType
GetPermissions() uint32
GetModifiedNs() int32
GetBlockSize() int32
GetPlatform() *bep.PlatformData
GetLocalFlags() uint32
GetVersionHash() []byte
GetInodeChangeNs() int64
GetEncryptionTrailerSize() int32
GetDeleted() bool
GetInvalid() bool
GetNoPermissions() bool
}
type FlagLocal ¶
type FlagLocal uint32
const ( FlagLocalUnsupported FlagLocal = 1 << 0 // 1: The kind is unsupported, e.g. symlinks on Windows FlagLocalIgnored FlagLocal = 1 << 1 // 2: Matches local ignore patterns FlagLocalMustRescan FlagLocal = 1 << 2 // 4: Doesn't match content on disk, must be rechecked fully FlagLocalReceiveOnly FlagLocal = 1 << 3 // 8: Change detected on receive only folder FlagLocalGlobal FlagLocal = 1 << 4 // 16: This is the global file version FlagLocalNeeded FlagLocal = 1 << 5 // 32: We need this file FlagLocalRemoteInvalid FlagLocal = 1 << 6 // 64: The remote marked this as invalid // Flags that should result in the Invalid bit on outgoing updates (or had it on ingoing ones) LocalInvalidFlags = FlagLocalUnsupported | FlagLocalIgnored | FlagLocalMustRescan | FlagLocalReceiveOnly | FlagLocalRemoteInvalid // Flags that should result in a file being in conflict with its // successor, due to us not having an up to date picture of its state on // disk. LocalConflictFlags = FlagLocalUnsupported | FlagLocalIgnored | FlagLocalReceiveOnly LocalAllFlags = FlagLocalUnsupported | FlagLocalIgnored | FlagLocalMustRescan | FlagLocalReceiveOnly | FlagLocalGlobal | FlagLocalNeeded | FlagLocalRemoteInvalid )
FileInfo.LocalFlags flags
type Folder ¶
type Folder struct {
ID string
Label string
ReadOnly bool
IgnorePermissions bool
IgnoreDelete bool
DisableTempIndexes bool
Paused bool
Devices []Device
}
func (Folder) Description ¶
type Hello ¶
type Hello struct {
DeviceName string
ClientName string
ClientVersion string
NumConnections int
Timestamp int64
}
func ExchangeHello ¶
func ExchangeHello(c io.ReadWriter, h Hello) (Hello, error)
type IndexUpdate ¶
type KeyGenerator ¶
type KeyGenerator struct {
// contains filtered or unexported fields
}
func NewKeyGenerator ¶
func NewKeyGenerator() *KeyGenerator
func (*KeyGenerator) FileKey ¶
func (g *KeyGenerator) FileKey(filename string, folderKey *[keySize]byte) *[keySize]byte
func (*KeyGenerator) KeyFromPassword ¶
func (g *KeyGenerator) KeyFromPassword(folderID, password string) *[keySize]byte
KeyFromPassword uses key derivation to generate a stronger key from a probably weak password.
type Model ¶
type Model interface {
// An index was received from the peer device
Index(conn Connection, idx *Index) error
// An index update was received from the peer device
IndexUpdate(conn Connection, idxUp *IndexUpdate) error
// A request was made by the peer device
Request(conn Connection, req *Request) (RequestResponse, error)
// A cluster configuration message was received
ClusterConfig(conn Connection, config *ClusterConfig) error
// The peer device closed the connection or an error occurred
Closed(conn Connection, err error)
// The peer device sent progress updates for the files it is currently downloading
DownloadProgress(conn Connection, p *DownloadProgress) error
}
type PlatformData ¶
type PlatformData struct {
Unix *UnixData
Windows *WindowsData
Linux *XattrData
Darwin *XattrData
FreeBSD *XattrData
NetBSD *XattrData
}
func (*PlatformData) MergeWith ¶
func (p *PlatformData) MergeWith(other *PlatformData)
MergeWith copies platform data from other, for platforms where it's not already set on p.
func (*PlatformData) SetXattrs ¶
func (p *PlatformData) SetXattrs(xattrs []Xattr)
SetXattrs is a convenience method to set the extended attributes of the file for the current platform.
func (*PlatformData) Xattrs ¶
func (p *PlatformData) Xattrs() []Xattr
Xattrs is a convenience method to return the extended attributes of the file for the current platform.
type RequestResponse ¶
type RequestResponse interface {
Data() []byte
Close() // Must always be called once the byte slice is no longer in use
Wait() // Blocks until Close is called
}
type Statistics ¶
type Vector ¶
type Vector struct {
Counters []Counter
}
The Vector type represents a version vector. The zero value is a usable version vector. The vector has slice semantics and some operations on it are "append-like" in that they may return the same vector modified, or v new allocated Vector with the modified contents.
func VectorFromString ¶
func VectorFromWire ¶
func (Vector) Concurrent ¶
Concurrent returns true when the two vectors are concurrent.
func (Vector) DropOthers ¶
DropOthers removes all counters, keeping only the one with given id. If there is no such counter, an empty Vector is returned.
func (Vector) GreaterEqual ¶
GreaterEqual returns true when the two vectors are equivalent or v is Greater than b.
func (Vector) LesserEqual ¶
LesserEqual returns true when the two vectors are equivalent or v is Lesser than b.
type WindowsData ¶
type WindowsData = bep.WindowsData