Documentation
¶
Index ¶
- Constants
- func BlockTransferWriteHeader(writer io.Writer, availability uint8, targetBlock BlockRange, blockSize uint64) (err error)
- func EncodeAnnouncement(sendUA, findSelf bool, findPeer []KeyHash, findValue []KeyHash, ...) (packetsRaw [][]byte)
- func EncodeGetBlock(senderPrivateKey *btcec.PrivateKey, data []byte, control uint8, ...) (packetRaw []byte, err error)
- func EncodeResponse(sendUA bool, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, ...) (packetsRaw [][]byte, err error)
- func EncodeTransfer(senderPrivateKey *btcec.PrivateKey, data []byte, ...) (packetRaw []byte, err error)
- func EncodeTraverse(senderPrivateKey *btcec.PrivateKey, embeddedPacketRaw []byte, ...) (packetRaw []byte, err error)
- func EncodeTraverseSetAddress(raw []byte, IPv4 net.IP, PortIPv4, PortIPv4ReportedExternal uint16, ...) (err error)
- func FileTransferReadHeader(reader io.Reader) (fileSize, transferSize uint64, err error)
- func FileTransferWriteHeader(writer io.Writer, fileSize, transferSize uint64) (err error)
- func HashData(data []byte) (hash []byte)
- func PacketEncrypt(senderPrivateKey *btcec.PrivateKey, receiverPublicKey *btcec.PublicKey, ...) (raw []byte, err error)
- func PacketLiteEncode(id uuid.UUID, data []byte) (raw []byte, err error)
- func PublicKey2NodeID(publicKey *btcec.PublicKey) (nodeID []byte)
- type BlockRange
- type EmbeddedFileData
- type Hash2Peer
- type InfoStore
- type KeyHash
- type LiteID
- type LiteRouter
- func (router *LiteRouter) All() (sessions []*LiteID)
- func (router *LiteRouter) IsPacketLite(raw []byte) (isLite bool, err error)
- func (router *LiteRouter) LookupLiteID(id uuid.UUID) (info *LiteID)
- func (router *LiteRouter) NewLiteID(data interface{}, timeout time.Duration, invalidateFunc func()) (info *LiteID)
- func (router *LiteRouter) PacketLiteDecode(raw []byte) (packet *PacketLiteRaw, err error)
- func (router *LiteRouter) RegisterLiteID(id uuid.UUID, data interface{}, timeout time.Duration, invalidateFunc func()) (info *LiteID)
- type MessageAnnouncement
- type MessageGetBlock
- type MessageRaw
- type MessageResponse
- type MessageTransfer
- type MessageTraverse
- type PacketLiteRaw
- type PacketRaw
- type PeerRecord
- type SequenceExpiry
- type SequenceManager
- func (manager *SequenceManager) ArbitrarySequence(publicKey *btcec.PublicKey, data interface{}) (info *SequenceExpiry)
- func (manager *SequenceManager) InvalidateSequence(publicKey *btcec.PublicKey, sequenceNumber uint32, bidirectional bool)
- func (manager *SequenceManager) NewSequence(publicKey *btcec.PublicKey, messageSequence *uint32, data interface{}) (info *SequenceExpiry)
- func (manager *SequenceManager) NewSequenceBi(publicKey *btcec.PublicKey, messageSequence *uint32, data interface{}, ...) (info *SequenceExpiry)
- func (manager *SequenceManager) RegisterSequenceBi(publicKey *btcec.PublicKey, sequenceNumber uint32, data interface{}, ...) (info *SequenceExpiry)
- func (manager *SequenceManager) ValidateSequence(publicKey *btcec.PublicKey, sequenceNumber uint32, ...) (sequenceInfo *SequenceExpiry, valid bool, rtt time.Duration)
- func (manager *SequenceManager) ValidateSequenceBi(publicKey *btcec.PublicKey, sequenceNumber uint32, isLast bool) (sequenceInfo *SequenceExpiry, valid bool, rtt time.Duration)
Constants ¶
const ( // Peer List Management CommandAnnouncement = 0 // Announcement CommandResponse = 1 // Response CommandPing = 2 // Keep-alive message (no payload). CommandPong = 3 // Response to ping (no payload). CommandLocalDiscovery = 4 // Local discovery CommandTraverse = 5 // Help establish a connection between 2 remote peers // Blockchain CommandGetBlock = 6 // Request blocks for specified peer. // File Discovery CommandTransfer = 8 // File transfer. // Debug CommandChat = 10 // Chat message [debug] )
Commands between peers
const ( FeatureIPv4Listen = 0 // Sender listens on IPv4 FeatureIPv6Listen = 1 // Sender listens on IPv6 FeatureFirewall = 2 // Sender indicates a potential firewall. This informs uncontacted peers that a Traverse message might be required to establish a connection. )
Features are sent as bit array in the Announcement message.
const ( ActionFindSelf = 0 // FIND_SELF Request closest neighbors to self ActionFindPeer = 1 // FIND_PEER Request closest neighbors to target peer ActionFindValue = 2 // FIND_VALUE Request data or closest peers ActionInfoStore = 3 // INFO_STORE Sender indicates storing provided data )
Actions between peers, sent via Announcement message. They correspond to the bit array index.
const ( GetBlockControlRequestStart = 0 // Request start transfer of blocks GetBlockControlNotAvailable = 1 // Requested blockchain not available (not found) GetBlockControlActive = 2 // Active block transfer GetBlockControlTerminate = 3 // Terminate GetBlockControlEmpty = 4 // Requested blockchain has 0 blocks )
const ( GetBlockStatusAvailable = 0 GetBlockStatusNotAvailable = 1 GetBlockStatusSizeExceed = 2 )
const ( TransferControlRequestStart = 0 // Request start transfer of file. Data at byte 34 is offset and limit to read, each 8 bytes. Limit may be 0 to indicate entire file. TransferControlNotAvailable = 1 // Requested file not available TransferControlActive = 2 // Active file transfer TransferControlTerminate = 3 // Terminate )
const (
ActionSequenceLast = 0 // SEQUENCE_LAST Last response to the announcement in the sequence
)
Actions in Response message
const EmbeddedFileSizeMax = udpMaxPacketSize - PacketLengthMin - announcementPayloadHeaderSize - 2 - 35
EmbeddedFileSizeMax is the maximum size of embedded files in response messages. Any file exceeding that must be shared via regular file transfer.
const HashSize = 32
HashSize is blake3 hash digest size = 256 bits
const PacketLengthMin = 12 + signatureSize
The minimum packet size is 12 bytes (minimum header size) + 65 bytes (signature)
const PacketLiteSizeMin = 16 + 2
Minimum packet size of lite packets.
const ProtocolVersion = 0
ProtocolVersion is the current protocol version
const TransferMaxEmbedSize = internetSafeMTU - PacketLengthMin - transferPayloadHeaderSize
TransferMaxEmbedSize is a recommended default upper size of embedded data inside the Transfer message, to be used as MaxPacketSize limit in the embedded protocol. This value is chosen as the lowest denominator of different environments (IPv4, IPv6, Ethernet, Internet) for safe transfer, not for highest performance. The caller may send bigger payloads but may risk that data packets are simply dropped and never arrive. A MTU negotiation or detection could pimp that.
const TransferMaxEmbedSizeLite = internetSafeMTU - PacketLiteSizeMin
Same as TransferMaxEmbedSize but for encoding via lite packets.
const (
TransferProtocolUDT = 0 // UDT via lite packets. No encryption.
)
Variables ¶
This section is empty.
Functions ¶
func BlockTransferWriteHeader ¶
func BlockTransferWriteHeader(writer io.Writer, availability uint8, targetBlock BlockRange, blockSize uint64) (err error)
BlockTransferWriteHeader starts writing the header for a block transfer.
func EncodeAnnouncement ¶
func EncodeAnnouncement(sendUA, findSelf bool, findPeer []KeyHash, findValue []KeyHash, files []InfoStore, features byte, blockchainHeight, blockchainVersion uint64, userAgent string) (packetsRaw [][]byte)
EncodeAnnouncement encodes an announcement message. It may return multiple messages if the input does not fit into one. findPeer is a list of node IDs (blake3 hash of peer ID compressed form) findValue is a list of hashes files is a list of files stored to inform about
func EncodeGetBlock ¶
func EncodeGetBlock(senderPrivateKey *btcec.PrivateKey, data []byte, control uint8, blockchainPublicKey *btcec.PublicKey, limitBlockCount, maxBlockSize uint64, targetBlocks []BlockRange, transferID uuid.UUID) (packetRaw []byte, err error)
EncodeGetBlock encodes a Get Block message. The embedded packet size must be smaller than TransferMaxEmbedSize.
func EncodeResponse ¶
func EncodeResponse(sendUA bool, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, hashesNotFound [][]byte, features byte, blockchainHeight, blockchainVersion uint64, userAgent string) (packetsRaw [][]byte, err error)
EncodeResponse encodes a response message hash2Peers will be modified.
func EncodeTransfer ¶
func EncodeTransfer(senderPrivateKey *btcec.PrivateKey, data []byte, control, transferProtocol uint8, hash []byte, offset, limit uint64, transferID uuid.UUID) (packetRaw []byte, err error)
EncodeTransfer encodes a transfer message. The embedded packet size must be smaller than TransferMaxEmbedSize.
func EncodeTraverse ¶
func EncodeTraverse(senderPrivateKey *btcec.PrivateKey, embeddedPacketRaw []byte, receiverEnd *btcec.PublicKey, relayPeer *btcec.PublicKey) (packetRaw []byte, err error)
EncodeTraverse encodes a traverse message
func EncodeTraverseSetAddress ¶
func EncodeTraverseSetAddress(raw []byte, IPv4 net.IP, PortIPv4, PortIPv4ReportedExternal uint16, IPv6 net.IP, PortIPv6, PortIPv6ReportedExternal uint16) (err error)
EncodeTraverseSetAddress sets the IP and Port in a traverse message that shall be forwarded to another peer
func FileTransferReadHeader ¶
FileTransferReadHeader starts reading the header for a file transfer. It will only read the header and keeps the connection open.
func FileTransferWriteHeader ¶
FileTransferWriteHeader starts writing the header for a file transfer.
func PacketEncrypt ¶
func PacketEncrypt(senderPrivateKey *btcec.PrivateKey, receiverPublicKey *btcec.PublicKey, packet *PacketRaw) (raw []byte, err error)
PacketEncrypt encrypts a packet using the provided senders private key and receivers compressed public key.
func PacketLiteEncode ¶
Encodes a lite packet.
func PublicKey2NodeID ¶
PublicKey2NodeID translates the Public Key into the node ID used in the Kademlia network. It is also referenced in various other places including blockchain data at runtime. The node ID identifies the owner.
Types ¶
type BlockRange ¶
BlockRange is a single start-count range.
func BlockTransferReadBlock ¶
func BlockTransferReadBlock(reader io.Reader, maxBlockSize uint64) (data []byte, targetBlock BlockRange, blockSize uint64, availability uint8, err error)
BlockTransferReadBlock reads the header and the block from the reader
type EmbeddedFileData ¶
EmbeddedFileData contains embedded data sent within a response
type Hash2Peer ¶
type Hash2Peer struct { ID KeyHash // Hash that was queried Closest []PeerRecord // Closest peers Storing []PeerRecord // Peers known to store the data identified by the hash IsLast bool // Whether it is the last records returned for the requested hash and no more results will follow }
Hash2Peer links a hash to peers who are known to store the data and to peers who are considered close to the hash
type InfoStore ¶
type InfoStore struct { ID KeyHash // Hash of the file Size uint64 // Size of the file Type uint8 // Type of the file: 0 = File, 1 = Header file containing list of parts }
InfoStore informs about files stored
type LiteID ¶
type LiteID struct { ID uuid.UUID // ID Data interface{} // Optional high-level data associated with the ID // contains filtered or unexported fields }
LiteID contains session information for a bidirectional transfer of data
type LiteRouter ¶
type LiteRouter struct { sync.Mutex // synchronized access to the IDs // contains filtered or unexported fields }
LiteRouter keeps track of accepted (expected) packet IDs.
func NewLiteRouter ¶
func NewLiteRouter() (router *LiteRouter)
Creates a new manager to keep track of accepted IDs.
func (*LiteRouter) All ¶
func (router *LiteRouter) All() (sessions []*LiteID)
Returns all lite sessions
func (*LiteRouter) IsPacketLite ¶
func (router *LiteRouter) IsPacketLite(raw []byte) (isLite bool, err error)
IsPacketLite identifies a lite packet based on its ID. If the ID is not recognized, it fails.
func (*LiteRouter) LookupLiteID ¶
func (router *LiteRouter) LookupLiteID(id uuid.UUID) (info *LiteID)
func (*LiteRouter) NewLiteID ¶
func (router *LiteRouter) NewLiteID(data interface{}, timeout time.Duration, invalidateFunc func()) (info *LiteID)
Returns a new lite ID to be used.
func (*LiteRouter) PacketLiteDecode ¶
func (router *LiteRouter) PacketLiteDecode(raw []byte) (packet *PacketLiteRaw, err error)
PacketLiteDecode a lite packet. It will identify the lite packet based on its ID. If the ID is not recognized (which is the case for regular Peernet packets), the function fails. It does not perform any decryption.
func (*LiteRouter) RegisterLiteID ¶
type MessageAnnouncement ¶
type MessageAnnouncement struct { *MessageRaw // Underlying raw message Protocol uint8 // Protocol version supported (low 4 bits). Features uint8 // Feature support Actions uint8 // Action bit array. See ActionX BlockchainHeight uint64 // Blockchain height BlockchainVersion uint64 // Blockchain version PortInternal uint16 // Internal port. Can be used to detect NATs. PortExternal uint16 // External port if known. 0 if not. Can be used for UPnP support. UserAgent string // User Agent. Format "Software/Version". Required in the initial announcement/bootstrap. UTF-8 encoded. Max length is 255 bytes. FindPeerKeys []KeyHash // FIND_PEER data FindDataKeys []KeyHash // FIND_VALUE data InfoStoreFiles []InfoStore // INFO_STORE data }
MessageAnnouncement is the decoded announcement message.
func DecodeAnnouncement ¶
func DecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err error)
DecodeAnnouncement decodes the incoming announcement message. Returns nil if invalid.
type MessageGetBlock ¶
type MessageGetBlock struct { *MessageRaw // Underlying raw message. Control uint8 // Control. See TransferControlX. BlockchainPublicKey *btcec.PublicKey // Peer ID of blockchain to transfer. // fields valid only for GetBlockControlRequestStart TransferID uuid.UUID // Transfer ID to identify lite packets. LimitBlockCount uint64 // Limit total count of blocks to transfer MaxBlockSize uint64 // Limit of bytes per block to transfer max. Blocks exceeding this limit will not be transferred. TargetBlocks []BlockRange // Target list of block ranges to transfer. // fields valid only for GetBlockControlActive Data []byte // Embedded protocol data. }
MessageGetBlock is the decoded Get Block message.
func DecodeGetBlock ¶
func DecodeGetBlock(msg *MessageRaw) (result *MessageGetBlock, err error)
DecodeGetBlock decodes a Get Block message
func (*MessageGetBlock) IsLast ¶
func (msg *MessageGetBlock) IsLast() bool
IsLast checks if the incoming message is the last one in this transfer.
type MessageRaw ¶
type MessageRaw struct { PacketRaw SenderPublicKey *btcec.PublicKey // Sender Public Key, ECDSA (secp256k1) 257-bit SequenceInfo *SequenceExpiry // Sequence }
MessageRaw is a high-level message between peers that has not been decoded
type MessageResponse ¶
type MessageResponse struct { *MessageRaw // Underlying raw message Protocol uint8 // Protocol version supported (low 4 bits). Features uint8 // Feature support (high 4 bits). Future use. Actions uint8 // Action bit array. See ActionX BlockchainHeight uint64 // Blockchain height BlockchainVersion uint64 // Blockchain version PortInternal uint16 // Internal port. Can be used to detect NATs. PortExternal uint16 // External port if known. 0 if not. Can be used for UPnP support. UserAgent string // User Agent. Format "Software/Version". Required in the initial announcement/bootstrap. UTF-8 encoded. Max length is 255 bytes. Hash2Peers []Hash2Peer // List of peers that know the requested hashes or at least are close to it FilesEmbed []EmbeddedFileData // Files that were embedded in the response HashesNotFound [][]byte // Hashes that were reported back as not found }
MessageResponse is the decoded response message.
func DecodeResponse ¶
func DecodeResponse(msg *MessageRaw) (result *MessageResponse, err error)
DecodeResponse decodes the incoming response message. Returns nil if invalid.
func (*MessageResponse) IsLast ¶
func (msg *MessageResponse) IsLast() bool
IsLast checks if the incoming message is the last expected response in this sequence.
type MessageTransfer ¶
type MessageTransfer struct { *MessageRaw // Underlying raw message. Control uint8 // Control. See TransferControlX. TransferProtocol uint8 // Embedded transfer protocol: 0 = UDT Hash []byte // Hash of the file to transfer. Offset uint64 // Offset to start reading at. Only TransferControlRequestStart. Limit uint64 // Limit (count of bytes) to read starting at the offset. Only TransferControlRequestStart. TransferID uuid.UUID // Transfer ID to identify lite packets. Data []byte // Embedded protocol data. Only TransferControlActive. }
MessageTransfer is the decoded transfer message. It is sent to initiate a file transfer, and to send data as part of a file transfer. The actual file data is encapsulated via UDT.
func DecodeTransfer ¶
func DecodeTransfer(msg *MessageRaw) (result *MessageTransfer, err error)
DecodeTransfer decodes a transfer message
func (*MessageTransfer) IsLast ¶
func (msg *MessageTransfer) IsLast() bool
IsLast checks if the incoming message is the last one in this transfer.
type MessageTraverse ¶
type MessageTraverse struct { *MessageRaw // Underlying raw message. TargetPeer *btcec.PublicKey // End receiver peer ID. AuthorizedRelayPeer *btcec.PublicKey // Peer ID that is authorized to relay this message to the end receiver. Expires time.Time // Expiration time when this forwarded message becomes invalid. EmbeddedPacketRaw []byte // Embedded packet. SignerPublicKey *btcec.PublicKey // Public key that signed this message, ECDSA (secp256k1) 257-bit IPv4 net.IP // IPv4 address of the original sender. Set by authorized relay. 0 if not set. PortIPv4 uint16 // Port (actual one used for connection) of the original sender. Set by authorized relay. PortIPv4ReportedExternal uint16 // External port as reported by the original sender. This is used in case of port forwarding (manual or automated). IPv6 net.IP // IPv6 address of the original sender. Set by authorized relay. 0 if not set. PortIPv6 uint16 // Port (actual one used for connection) of the original sender. Set by authorized relay. PortIPv6ReportedExternal uint16 // External port as reported by the original sender. This is used in case of port forwarding (manual or automated). }
MessageTraverse is the decoded traverse message. It is sent by an original sender to a relay, to a final receiver (targert peer).
func DecodeTraverse ¶
func DecodeTraverse(msg *MessageRaw) (result *MessageTraverse, err error)
DecodeTraverse decodes a traverse message. It does not verify if the receiver is authorized to read or forward this message. It validates the signature, but does not validate the signer.
type PacketLiteRaw ¶
type PacketLiteRaw struct { ID uuid.UUID // ID Payload []byte // Payload Session *LiteID // Session info }
PacketLiteRaw is a decrypted P2P lite packet
type PacketRaw ¶
type PacketRaw struct { Protocol uint8 // Protocol version = 0 Command uint8 // 0 = Announcement Sequence uint32 // Sequence number Payload []byte // Payload }
PacketRaw is a decrypted P2P message
func PacketDecrypt ¶
func PacketDecrypt(raw []byte, receiverPublicKey *btcec.PublicKey) (packet *PacketRaw, senderPublicKey *btcec.PublicKey, err error)
PacketDecrypt decrypts the packet, verifies its signature and returns a high-level version of the packet.
func (*PacketRaw) SetSelfReportedPorts ¶
SetSelfReportedPorts sets the fields Internal Port and External Port according to the connection details. This is important for the remote peer to make smart decisions whether this peer is behind a NAT/firewall and supports port forwarding/UPnP.
type PeerRecord ¶
type PeerRecord struct { PublicKey *btcec.PublicKey // Public Key NodeID []byte // Kademlia Node ID IPv4 net.IP // IPv4 address. 0 if not set. IPv4Port uint16 // Port (actual one used for connection) IPv4PortReportedInternal uint16 // Internal port as reported by that peer. This can be used to identify whether the peer is potentially behind a NAT. IPv4PortReportedExternal uint16 // External port as reported by that peer. This is used in case of port forwarding (manual or automated). IPv6 net.IP // IPv6 address. 0 if not set. IPv6Port uint16 // Port (actual one used for connection) IPv6PortReportedInternal uint16 // Internal port as reported by that peer. This can be used to identify whether the peer is potentially behind a NAT. IPv6PortReportedExternal uint16 // External port as reported by that peer. This is used in case of port forwarding (manual or automated). LastContact uint32 // Last contact in seconds LastContactT time.Time // Last contact time translated from seconds Features uint8 // Feature support. Same as in Announcement/Response message. }
PeerRecord informs about a peer
type SequenceExpiry ¶
type SequenceExpiry struct { SequenceNumber uint32 // Sequence number Data interface{} // Optional high-level data associated with the sequence // contains filtered or unexported fields }
SequenceExpiry contains the decoded sequence information of a message.
type SequenceManager ¶
type SequenceManager struct { ReplyTimeout int // The round-trip timeout for message sequences. sync.Mutex // synchronized access to the sequences // contains filtered or unexported fields }
SequenceManager stores all message sequence numbers that are valid at the moment
func NewSequenceManager ¶
func NewSequenceManager(ReplyTimeout int) (manager *SequenceManager)
NewSequenceManager creates a new sequence manager. The ReplyTimeout is in seconds. The expiration function is started immediately.
func (*SequenceManager) ArbitrarySequence ¶
func (manager *SequenceManager) ArbitrarySequence(publicKey *btcec.PublicKey, data interface{}) (info *SequenceExpiry)
ArbitrarySequence returns an arbitrary sequence to be used for uncontacted peers
func (*SequenceManager) InvalidateSequence ¶
func (manager *SequenceManager) InvalidateSequence(publicKey *btcec.PublicKey, sequenceNumber uint32, bidirectional bool)
InvalidateSequence invalidates the sequence number. It does not call invalidateFunc.
func (*SequenceManager) NewSequence ¶
func (manager *SequenceManager) NewSequence(publicKey *btcec.PublicKey, messageSequence *uint32, data interface{}) (info *SequenceExpiry)
NewSequence returns a new sequence and registers it. messageSequence must point to the variable holding the continuous next sequence number. Use only for Announcement and Ping messages.
func (*SequenceManager) NewSequenceBi ¶
func (manager *SequenceManager) NewSequenceBi(publicKey *btcec.PublicKey, messageSequence *uint32, data interface{}, timeout time.Duration, invalidateFunc func()) (info *SequenceExpiry)
NewSequenceBi returns a new bidirectional sequence and registers it. messageSequence must point to the variable holding the continuous next sequence number.
func (*SequenceManager) RegisterSequenceBi ¶
func (manager *SequenceManager) RegisterSequenceBi(publicKey *btcec.PublicKey, sequenceNumber uint32, data interface{}, timeout time.Duration, invalidateFunc func()) (info *SequenceExpiry)
RegisterSequenceBi registers a bidirectional sequence initiated by a remote peer. The caller must specify the timeout (which will be reset every time a new message appears in this sequence). This is needed for bidirectional responses to accept subsequent incoming messages from the remote peer.
func (*SequenceManager) ValidateSequence ¶
func (manager *SequenceManager) ValidateSequence(publicKey *btcec.PublicKey, sequenceNumber uint32, invalidate, extendValidity bool) (sequenceInfo *SequenceExpiry, valid bool, rtt time.Duration)
ValidateSequence validates the sequence number of an incoming message. It will set raw.sequence if valid.
func (*SequenceManager) ValidateSequenceBi ¶
func (manager *SequenceManager) ValidateSequenceBi(publicKey *btcec.PublicKey, sequenceNumber uint32, isLast bool) (sequenceInfo *SequenceExpiry, valid bool, rtt time.Duration)
ValidateSequenceBi validates the sequence number of an incoming message. It will set raw.sequence if valid.