protocol

package
v1.30.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2025 License: MPL-2.0 Imports: 30 Imported by: 93

Documentation

Overview

Package protocol implements the Block Exchange Protocol.

Index

Constants

View Source
const (
	CompressionMetadata = bep.Compression_COMPRESSION_METADATA
	CompressionNever    = bep.Compression_COMPRESSION_NEVER
	CompressionAlways   = bep.Compression_COMPRESSION_ALWAYS
)
View Source
const (
	FlagLocalUnsupported = 1 << 0 // The kind is unsupported, e.g. symlinks on Windows
	FlagLocalIgnored     = 1 << 1 // Matches local ignore patterns
	FlagLocalMustRescan  = 1 << 2 // Doesn't match content on disk, must be rechecked fully
	FlagLocalReceiveOnly = 1 << 3 // Change detected on receive only folder

	// Flags that should result in the Invalid bit on outgoing updates
	LocalInvalidFlags = FlagLocalUnsupported | FlagLocalIgnored | FlagLocalMustRescan | FlagLocalReceiveOnly

	// 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
)

FileInfo.LocalFlags flags

View Source
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
)
View Source
const (
	HelloMessageMagic   uint32 = 0x2EA7D90B
	Version13HelloMagic uint32 = 0x9F79BC40 // old
)
View Source
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
)
View Source
const (
	DeviceIDLength = 32
	// keep consistent with shortIDStringLength in gui/default/syncthing/app.js
	ShortIDStringLength = 7
)
View Source
const (
	// Shifts
	KiB = 10
	MiB = 20
	GiB = 30
)
View Source
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
)
View Source
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

View Source
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")
)
View Source
var (
	LocalDeviceID  = repeatedDeviceID(0xff)
	GlobalDeviceID = repeatedDeviceID(0xf8)
	EmptyDeviceID  = DeviceID{}
)
View Source
var (
	ErrGeneric    = errors.New("generic error")
	ErrNoSuchFile = errors.New("no such file")
	ErrInvalid    = errors.New("file is invalid")
)
View Source
var (
	ErrClosed  = errors.New("connection closed")
	ErrTimeout = errors.New("read timeout")
)
View Source
var BlockSizes []int

BlockSizes is the list of valid block sizes, from min to max

View Source
var BufferPool *bufferPool

Global pool to get buffers from. Initialized in init().

View Source
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 BlockSize

func BlockSize(fileSize int64) int

BlockSize returns the block size to use for the given file size

func BlocksHash added in v1.4.0

func BlocksHash(bs []BlockInfo) []byte

func DecryptBytes added in v1.12.0

func DecryptBytes(data []byte, key *[keySize]byte) ([]byte, error)

DecryptBytes returns the decrypted bytes, or an error if decryption failed.

func IsEncryptedParent added in v1.12.0

func IsEncryptedParent(pathComponents []string) bool

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 added in v0.13.6

func IsVersionMismatch(err error) bool

IsVersionMismatch returns true if the error is a reliable indication of a version mismatch that we might want to alert the user about.

func ModTimeEqual added in v1.2.2

func ModTimeEqual(a, b time.Time, modTimeWindow time.Duration) bool

func PasswordToken added in v1.12.0

func PasswordToken(keyGen *KeyGenerator, folderID, password string) []byte

func PermsEqual added in v0.14.46

func PermsEqual(a, b uint32) bool

func TotalInOut

func TotalInOut() (int64, int64)

func VectorHash added in v1.7.0

func VectorHash(v Vector) []byte

Types

type BlockInfo

type BlockInfo struct {
	Hash     []byte
	Offset   int64
	Size     int
	WeakHash uint32
}

func BlockInfoFromWire added in v1.29.0

func BlockInfoFromWire(w *bep.BlockInfo) BlockInfo

func (BlockInfo) IsEmpty added in v0.12.4

func (b BlockInfo) IsEmpty() bool

IsEmpty returns true if the block is a full block of zeroes.

func (BlockInfo) String

func (b BlockInfo) String() string

func (BlockInfo) ToWire added in v1.29.0

func (b BlockInfo) ToWire() *bep.BlockInfo

type ClusterConfig added in v0.14.0

type ClusterConfig struct {
	Folders   []Folder
	Secondary bool
}

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 added in v1.13.0

type ConnectionInfo interface {
	Type() string
	Transport() string
	IsLocal() bool
	RemoteAddr() net.Addr
	Priority() int
	String() string
	Crypto() string
	EstablishedAt() time.Time
	ConnectionID() string
}

type Counter

type Counter struct {
	ID    ShortID
	Value uint64
}

Counter represents a single counter in the version vector.

type Device

type Device struct {
	ID                       DeviceID
	Name                     string
	Addresses                []string
	Compression              Compression
	CertName                 string
	MaxSequence              int64
	Introducer               bool
	IndexID                  IndexID
	SkipIntroductionRemovals bool
	EncryptionPasswordToken  []byte
}

type DeviceID

type DeviceID [DeviceIDLength]byte

func DeviceIDFromBytes

func DeviceIDFromBytes(bs []byte) (DeviceID, error)

DeviceIDFromBytes converts a 32 byte slice to a DeviceID. A slice of the wrong length results in an error.

func DeviceIDFromString

func DeviceIDFromString(s string) (DeviceID, error)

DeviceIDFromString parses a device ID from a string. The string is expected to be in the canonical format, with check digits.

func NewDeviceID

func NewDeviceID(rawCert []byte) DeviceID

NewDeviceID generates a new device ID from SHA256 hash of the given piece of data (usually raw certificate bytes).

func (DeviceID) Compare

func (n DeviceID) Compare(other DeviceID) int

func (DeviceID) Equals

func (n DeviceID) Equals(other DeviceID) bool

func (DeviceID) GoString

func (n DeviceID) GoString() string

func (DeviceID) MarshalText

func (n DeviceID) MarshalText() ([]byte, error)

func (*DeviceID) MarshalTo added in v0.14.10

func (n *DeviceID) MarshalTo(bs []byte) (int, error)

func (*DeviceID) ProtoSize added in v0.14.10

func (*DeviceID) ProtoSize() int

func (DeviceID) Short

func (n DeviceID) Short() ShortID

Short returns an integer representing bits 0-63 of the device ID.

func (DeviceID) String

func (n DeviceID) String() string

String returns the canonical string representation of the device ID

func (*DeviceID) Unmarshal added in v0.14.10

func (n *DeviceID) Unmarshal(bs []byte) error

func (*DeviceID) UnmarshalText

func (n *DeviceID) UnmarshalText(bs []byte) error

type DownloadProgress added in v0.14.0

type DownloadProgress struct {
	Folder  string
	Updates []FileDownloadProgressUpdate
}

type ErrorCode added in v0.14.0

type ErrorCode = bep.ErrorCode

type FileDownloadProgressUpdate added in v0.13.0

type FileDownloadProgressUpdate struct {
	UpdateType   FileDownloadProgressUpdateType
	Name         string
	Version      Vector
	BlockIndexes []int
	BlockSize    int
}

type FileDownloadProgressUpdateType added in v0.14.0

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.
	LocalFlags uint32

	// 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
	RawInvalid    bool
	NoPermissions bool
	// contains filtered or unexported fields
}

func DecryptFileInfo added in v1.12.0

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 added in v1.29.0

func FileInfoFromDB(w *bep.FileInfo) FileInfo

func FileInfoFromDBTruncated added in v1.29.0

func FileInfoFromDBTruncated(w FileInfoWithoutBlocks) FileInfo

func FileInfoFromWire added in v1.29.0

func FileInfoFromWire(w *bep.FileInfo) FileInfo

func (FileInfo) BlockSize added in v0.14.48

func (f FileInfo) BlockSize() int

func (FileInfo) BlocksEqual added in v1.4.1

func (f FileInfo) BlocksEqual(other FileInfo) bool

BlocksEqual returns true when the two files have identical block lists.

func (FileInfo) FileBlocksHash added in v1.23.3

func (f FileInfo) FileBlocksHash() []byte

func (FileInfo) FileLocalFlags added in v0.14.50

func (f FileInfo) FileLocalFlags() uint32

func (FileInfo) FileModifiedBy added in v1.3.2

func (f FileInfo) FileModifiedBy() ShortID

func (FileInfo) FileName added in v0.14.0

func (f FileInfo) FileName() string

func (FileInfo) FilePermissions added in v1.3.2

func (f FileInfo) FilePermissions() uint32

func (FileInfo) FileSize added in v0.14.0

func (f FileInfo) FileSize() int64

func (FileInfo) FileType added in v1.3.2

func (f FileInfo) FileType() FileInfoType

func (FileInfo) FileVersion added in v0.14.49

func (f FileInfo) FileVersion() Vector

func (FileInfo) HasPermissionBits

func (f FileInfo) HasPermissionBits() bool

func (FileInfo) InodeChangeTime added in v1.22.0

func (f FileInfo) InodeChangeTime() time.Time

func (FileInfo) IsDeleted

func (f FileInfo) IsDeleted() bool

func (FileInfo) IsDirectory

func (f FileInfo) IsDirectory() bool

func (FileInfo) IsEquivalent added in v0.14.46

func (f FileInfo) IsEquivalent(other FileInfo, modTimeWindow time.Duration) bool

func (FileInfo) IsEquivalentOptional added in v0.14.50

func (f FileInfo) IsEquivalentOptional(other FileInfo, comp FileInfoComparison) bool

func (FileInfo) IsIgnored added in v0.14.49

func (f FileInfo) IsIgnored() bool

func (FileInfo) IsInvalid

func (f FileInfo) IsInvalid() bool

func (FileInfo) IsReceiveOnlyChanged added in v0.14.50

func (f FileInfo) IsReceiveOnlyChanged() bool
func (f FileInfo) IsSymlink() bool

func (FileInfo) IsUnsupported added in v0.14.50

func (f FileInfo) IsUnsupported() bool

func (FileInfo) ModTime added in v0.14.4

func (f FileInfo) ModTime() time.Time

func (FileInfo) MustRescan added in v0.14.49

func (f FileInfo) MustRescan() bool

func (FileInfo) PlatformData added in v1.22.0

func (f FileInfo) PlatformData() PlatformData

func (FileInfo) SequenceNo added in v0.14.43

func (f FileInfo) SequenceNo() int64

func (*FileInfo) SetDeleted added in v1.4.0

func (f *FileInfo) SetDeleted(by ShortID)

func (*FileInfo) SetIgnored added in v0.14.49

func (f *FileInfo) SetIgnored()

func (*FileInfo) SetMustRescan added in v0.14.49

func (f *FileInfo) SetMustRescan()

func (*FileInfo) SetUnsupported added in v0.14.49

func (f *FileInfo) SetUnsupported()

func (FileInfo) ShouldConflict added in v0.14.49

func (f FileInfo) ShouldConflict() bool

func (FileInfo) String

func (f FileInfo) String() string

func (*FileInfo) ToWire added in v1.29.0

func (f *FileInfo) ToWire(withInternalFields bool) *bep.FileInfo

func (*FileInfo) WinsConflict

func (f *FileInfo) WinsConflict(other FileInfo) bool

WinsConflict returns true if "f" is the one to choose when it is in conflict with "other".

type FileInfoComparison added in v1.21.0

type FileInfoComparison struct {
	ModTimeWindow   time.Duration
	IgnorePerms     bool
	IgnoreBlocks    bool
	IgnoreFlags     uint32
	IgnoreOwnership bool
	IgnoreXattrs    bool
}

type FileInfoType added in v0.14.0

type FileInfoType = bep.FileInfoType

type FileInfoWithoutBlocks added in v1.29.0

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 Folder

type Folder struct {
	ID                 string
	Label              string
	ReadOnly           bool
	IgnorePermissions  bool
	IgnoreDelete       bool
	DisableTempIndexes bool
	Paused             bool
	Devices            []Device
}

func (Folder) Description added in v0.14.12

func (f Folder) Description() string

type Hello added in v0.14.0

type Hello struct {
	DeviceName     string
	ClientName     string
	ClientVersion  string
	NumConnections int
	Timestamp      int64
}

func ExchangeHello added in v0.13.6

func ExchangeHello(c io.ReadWriter, h Hello) (Hello, error)

func (Hello) Magic added in v0.14.0

func (Hello) Magic() uint32

type Index added in v0.14.0

type Index struct {
	Folder       string
	Files        []FileInfo
	LastSequence int64
}

type IndexID added in v0.14.1

type IndexID uint64

func NewIndexID added in v0.14.1

func NewIndexID() IndexID

func (IndexID) Marshal added in v0.14.1

func (i IndexID) Marshal() ([]byte, error)

func (IndexID) String added in v0.14.1

func (i IndexID) String() string

func (*IndexID) Unmarshal added in v0.14.1

func (i *IndexID) Unmarshal(bs []byte) error

type IndexUpdate added in v0.14.0

type IndexUpdate struct {
	Folder       string
	Files        []FileInfo
	LastSequence int64
	PrevSequence int64
}

type KeyGenerator added in v1.23.3

type KeyGenerator struct {
	// contains filtered or unexported fields
}

func NewKeyGenerator added in v1.23.3

func NewKeyGenerator() *KeyGenerator

func (*KeyGenerator) FileKey added in v1.23.3

func (g *KeyGenerator) FileKey(filename string, folderKey *[keySize]byte) *[keySize]byte

func (*KeyGenerator) KeyFromPassword added in v1.23.3

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 Ordering

type Ordering int

Ordering represents the relationship between two Vectors.

const (
	Equal Ordering = iota
	Greater
	Lesser
	ConcurrentLesser
	ConcurrentGreater
)

type PlatformData added in v1.21.0

type PlatformData struct {
	Unix    *UnixData
	Windows *WindowsData
	Linux   *XattrData
	Darwin  *XattrData
	FreeBSD *XattrData
	NetBSD  *XattrData
}

func (*PlatformData) MergeWith added in v1.22.0

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 added in v1.22.0

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 added in v1.22.0

func (p *PlatformData) Xattrs() []Xattr

Xattrs is a convenience method to return the extended attributes of the file for the current platform.

type Request added in v0.14.0

type Request struct {
	ID            int
	Folder        string
	Name          string
	Offset        int64
	Size          int
	Hash          []byte
	FromTemporary bool
	WeakHash      uint32
	BlockNo       int
}

type RequestResponse added in v0.14.53

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 Response added in v0.14.0

type Response struct {
	ID   int
	Data []byte
	Code ErrorCode
}

type ShortID added in v0.12.16

type ShortID uint64

func (ShortID) String added in v0.12.16

func (s ShortID) String() string

type Statistics

type Statistics struct {
	At            time.Time `json:"at"`
	InBytesTotal  int64     `json:"inBytesTotal"`
	OutBytesTotal int64     `json:"outBytesTotal"`
	StartedAt     time.Time `json:"startedAt"`
}

type UnixData added in v1.21.0

type UnixData struct {
	// 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.
	OwnerName string
	GroupName string
	UID       int
	GID       int
}

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 VectorFromWire added in v1.29.0

func VectorFromWire(w *bep.Vector) Vector

func (Vector) Compare

func (v Vector) Compare(b Vector) Ordering

Compare returns the Ordering that describes a's relation to b.

func (Vector) Concurrent

func (v Vector) Concurrent(b Vector) bool

Concurrent returns true when the two vectors are concurrent.

func (Vector) Copy

func (v Vector) Copy() Vector

Copy returns an identical vector that is not shared with v.

func (Vector) Counter

func (v Vector) Counter(id ShortID) uint64

Counter returns the current value of the given counter ID.

func (Vector) DropOthers added in v0.14.46

func (v Vector) DropOthers(id ShortID) Vector

DropOthers removes all counters, keeping only the one with given id. If there is no such counter, an empty Vector is returned.

func (Vector) Equal

func (v Vector) Equal(b Vector) bool

Equal returns true when the two vectors are equivalent.

func (Vector) GreaterEqual

func (v Vector) GreaterEqual(b Vector) bool

GreaterEqual returns true when the two vectors are equivalent or v is Greater than b.

func (Vector) IsEmpty added in v1.10.0

func (v Vector) IsEmpty() bool

IsEmpty returns true when there are no counters.

func (Vector) LesserEqual

func (v Vector) LesserEqual(b Vector) bool

LesserEqual returns true when the two vectors are equivalent or v is Lesser than b.

func (Vector) Merge

func (v Vector) Merge(b Vector) Vector

Merge returns the vector containing the maximum indexes from v and b. If it is possible, the vector v is updated and returned. If it is not, a copy will be created, updated and returned.

func (*Vector) ToWire added in v1.29.0

func (v *Vector) ToWire() *bep.Vector

func (Vector) Update

func (v Vector) Update(id ShortID) Vector

Update returns a Vector with the index for the specific ID incremented by one. If it is possible, the vector v is updated and returned. If it is not, a copy will be created, updated and returned.

type WindowsData added in v1.21.0

type WindowsData = bep.WindowsData

type Xattr added in v1.22.0

type Xattr struct {
	Name  string
	Value []byte
}

type XattrData added in v1.22.0

type XattrData struct {
	Xattrs []Xattr
}

Directories

Path Synopsis
Code generated by counterfeiter.
Code generated by counterfeiter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL