core

package module
v0.0.0-...-a16b13a Latest Latest
Warning

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

Go to latest
Published: Jan 18, 2024 License: MIT Imports: 31 Imported by: 0

README

Peernet Core

The core library which is needed for any Peernet application. It provides connectivity to the network and all basic functions. For details about Peernet see https://peernet.org/.

Current version: Alpha 6

Use

package main

import (
    "fmt"

    "github.com/PeernetOfficial/core"
)

func main() {
  	backend, status, err := core.Init("Your application/1.0", "Config.yaml", nil, nil)
    if status != core.ExitSuccess {
        fmt.Printf("Error %d initializing backend: %s\n", status, err.Error())
        return
    }

    backend.Connect()

    // Use the backend functions for example to search for files or download them.
    // The webapi package exports some high-level functions that can be used directly (without calling the HTTP API).
}

Encryption and Hashing functions

  • Salsa20 is used for encrypting the packets.
  • secp256k1 is used to generate the peer IDs (public keys).
  • blake3 is used for hashing the packets when signing and as hashing algorithm for the DHT.

Dependencies

Go 1.16 or higher is required. All dependencies are automatically downloaded via Go modules.

Configuration

Peernet follows a "zeroconf" approach, meaning there is no manual configuration required. However, in certain cases such as providing root peers that shall listen on a fixed IP and port, it is desirable to create a config file. See inline documentation in the file Config Default.yaml.

The name of the config file is passed to the function LoadConfig. If it does not exist, it will be created with the values from the file Config Default.yaml. It uses the YAML format. Any public/private keys in the config are hex encoded. Here are some notable settings:

  • PrivateKey The users Private Key hex encoded. The users public key is derived from it.
  • Listen defines IP:Port combinations to listen on. If not specified, it will listen on all IPs. You can specify an IP but port 0 for auto port selection. IPv6 addresses must be in the format "[IPv6]:Port".

Root peer = A peer operated by a known trusted entity. They allow to speed up the network including discovery of peers and data.

Private Key

The Private Key is required to make any changes to the user's blockchain, including deleting, renaming, and adding files on Peernet, or nuking the blockchain. If the private key is lost, no write access will be possible. Users should always create a secure backup of their private key.

Connectivity

Bootstrap Strategy
  • Connection to root peers (initial seed list):
    • Immediate contact to all root peers.
    • Phase 1: First 10 minutes. Try every 7 seconds to connect to all root peers until at least 2 peers connected.
    • Phase 2: After that (if not 2 peers), try every 5 minutes to connect to remaining root peers for a maximum of 1 hour.
  • Local peer discovery via IPv4 Broadcast and IPv6 Multicast:
    • Send out immediately when starting.
    • Phase 1: Resend every 10 seconds until at least 1 peer in the peer list.
    • Phase 2: Every 10 minutes.
  • Network adapter changes:
    • Check every 10 seconds for new/removed network interfaces and for new/removed IPs.
    • Automatically listen on any newly detected network interfaces and IPs.
    • Start a full Kademlia bucket refresh in case of a new network interface or IP.
  • Kademlia bootstrap:
    • As soon as there are at least 2 peers, keep refreshing buckets (target number is alpha) every 10 seconds 3 times.
Ping

The Ping/Pong commands are used to verify whether connections remain valid. They are only sent in absence of any other commands in the defined timeframe.

  • Active connections
    • Invalidate if 'Last packet in' was older than 22 seconds ago.
    • Send ping if last ping and 'Last packet in' was earlier than 10 seconds.
    • Redundant connections to the same peer (= any connections exceeding the 1 main active one): Mentioned times are multiplied by 4.
  • Inactive connections
    • If inactive for 120 seconds, remove the connection.
    • If there are no connections (neither active/inactive) to the peer, remove it.
    • Send ping if last ping was earlier than 10 seconds.

Above limits are constants and can be adjusted in the code via pingTime, connectionInvalidate, and connectionRemove.

Kademlia

The routing table has a bucket size of 20 and the size of keys 256 bits (blake3 hash). Nodes within buckets are sorted by least recently seen. The number of nodes to contact concurrently in DHT lookups (also known as alpha number) is set to 5.

If a bucket is full when a new peer connects ShouldEvict is called. It compares the RTTs (favoring smaller one) and in absence of the RTT time it will favor the node which is closer by XOR distance. Refresh of buckets is done every 5 minutes and queries a random ID in that bucket if there are not at least alpha nodes. A full refresh of all buckets is done every hour.

Timeouts
  • The default reply timeout (round-trip time) is 20 seconds set in ReplyTimeout. This applies to Response and Pong messages. The RTT timeout implies an average minimum connection speed between peers of about 6.4 KB/s for files of 64 KB size.
  • Separate timeouts for file transfers will be established.
MTU

The default MTU is set to 1280 bytes (see internetSafeMTU constant). This value (and by extension the lower value TransferMaxEmbedSize for file transfer) is chosen for safe transfer, not for highest performance. Different environments (IPv4, IPv6, Ethernet, Internet) have different smallest and common supported MTUs. MTU negotiation or detection is currently not implemented.

File Transfer Performance

The packet encryption/signing overhead appears to require significant CPU overhead during file transfer. This can be improved in the future by defining special file transfer packets that start with a UUID and not the regular protocol header. It would reduce processing time, increase payload data per packet, and therefore the overall transfer speed. A symmetric encryption algorithm (and key negotiation during file transfer initiation) would be required to not lose the security benefit.

Network Listen

Unless specified in the config via Listen, it will listen on all network adapters. The default port is 112, but that may be randomized in the future.

  • Traffic between link-local unicast IPs and non link-local IPs is not allowed.
  • UPnP is supported on IPv4 only for now.

OS Support

The code is compatible and tested on Windows, Linux, Mac, and Android.

ARM32 is not supported due to a Go compiler bug affecting 64-bit atomic access. This may affect old Raspberry Pis.

Contributing

Please note that by contributing code, documentation, ideas, snippets, or any other intellectual property you agree that you have all the necessary rights and you agree that we, the Peernet organization, may use it for any purpose.

© 2021 Peernet s.r.o.

Documentation

Index

Constants

View Source
const (
	ConnectionActive = iota
	ConnectionInactive
	ConnectionRemoved
	ConnectionRedundant // Same as active. Incoming packets are accepted. Outgoing use only for redundancy. Reduces ping overhead.
)

Connection status

View Source
const (
	ExitSuccess            = 0          // This is actually never used.
	ExitErrorConfigAccess  = 1          // Error accessing the config file.
	ExitErrorConfigRead    = 2          // Error reading the config file.
	ExitErrorConfigParse   = 3          // Error parsing the config file.
	ExitErrorLogInit       = 4          // Error initializing log file.
	ExitParamWebapiInvalid = 5          // Parameter for webapi is invalid.
	ExitPrivateKeyCorrupt  = 6          // Private key is corrupt.
	ExitPrivateKeyCreate   = 7          // Cannot create a new private key.
	ExitBlockchainCorrupt  = 8          // Blockchain is corrupt.
	ExitGraceful           = 9          // Graceful shutdown.
	ExitParamApiKeyInvalid = 10         // API key parameter is invalid.
	STATUS_CONTROL_C_EXIT  = 0xC000013A // The application terminated as a result of a CTRL+C. This is a Windows NTSTATUS value.
)

Exit codes signal why the application exited. These are universal between clients developed by the Peernet organization. Clients are encouraged to log additional details in a log file. 3rd party clients may define additional exit codes.

View Source
const (
	TypeBinary     = iota // Binary/unspecified
	TypeText              // Plain text
	TypePicture           // Picture of any format
	TypeVideo             // Video
	TypeAudio             // Audio
	TypeDocument          // Any document file, including office documents, PDFs, power point, spreadsheets
	TypeExecutable        // Any executable file, OS independent
	TypeContainer         // Container files like ZIP, RAR, TAR, ISO
	TypeCompressed        // Compressed files like GZ, BZ
	TypeFolder            // Virtual folder
	TypeEbook             // Ebook
)

General content types of data.

View Source
const (
	FormatBinary        = iota // Binary/unspecified
	FormatPDF                  // PDF document
	FormatWord                 // Word document
	FormatExcel                // Excel
	FormatPowerpoint           // Powerpoint
	FormatPicture              // Pictures (including GIF, excluding icons)
	FormatAudio                // Audio files
	FormatVideo                // Video files
	FormatContainer            // Compressed files including ZIP, RAR, TAR and others
	FormatHTML                 // HTML file
	FormatText                 // Text file
	FormatEbook                // Ebook file
	FormatCompressed           // Compressed file
	FormatDatabase             // Database file
	FormatEmail                // Single email
	FormatCSV                  // CSV file
	FormatFolder               // Virtual folder
	FormatExecutable           // Executable file
	FormatInstaller            // Installer
	FormatAPK                  // APK
	FormatISO                  // ISO
	FormatPeernetSearch        // Peernet Search
)

File formats. New ones may be added to the list as required.

View Source
const (
	DirectionIn  = 0
	DirectionOut = 1
	DirectionBi  = 2
)

Transfer directions

View Source
const ReplyTimeout = 20

ReplyTimeout is the round-trip timeout for message sequences.

View Source
const Version = "Alpha 9/01.11.2022"

Version is the current core library version

Variables

View Source
var ConfigDefault []byte

Functions

func Data2Hash

func Data2Hash(data []byte) (hash []byte)

Data2Hash returns the hash for the data

func FindInterfaceByIP

func FindInterfaceByIP(ip net.IP) (iface *net.Interface, ipnet *net.IPNet)

FindInterfaceByIP finds an interface based on the IP. The IP must be available at the interface.

func IsIPLocal

func IsIPLocal(ip net.IP) bool

IsIPLocal reports whether ip is a private (local) address. The identification of private, or local, unicast addresses uses address type indentification as defined in RFC 1918 for ip4 and RFC 4193 (fc00::/7) for ip6 with the exception of ip4 directed broadcast addresses. Unassigned, reserved, multicast and limited-broadcast addresses are not handled and will return false. IPv6 link-local addresses (fe80::/10) are included in this check.

func IsIPv4

func IsIPv4(IP net.IP) bool

IsIPv4 checks if an IP address is IPv4

func IsIPv6

func IsIPv6(IP net.IP) bool

IsIPv6 checks if an IP address is IPv6

func IsNetworkErrorFatal

func IsNetworkErrorFatal(err error) bool

IsNetworkErrorFatal checks if a network error indicates a broken connection. Not every network error indicates a broken connection. This function prevents from over-dropping connections.

func LoadConfig

func LoadConfig(Filename string, ConfigOut interface{}) (status int, err error)

LoadConfig reads the YAML configuration file and unmarshals it into the provided structure. If the config file does not exist or is empty, it will fall back to the default config which is hardcoded. Status is of type ExitX.

func NetworkListIPs

func NetworkListIPs() (IPs []net.IP, err error)

NetworkListIPs returns a list of all IPs

func NewIPList

func NewIPList() (list *ipList)

NewIPList creates a new list

func PublicKeyFromPeerID

func PublicKeyFromPeerID(peerID string) (publicKey *btcec.PublicKey, err error)

PublicKeyFromPeerID decodes the peer ID (hex encoded) into a public key.

func SaveConfig

func SaveConfig(Filename string, Config interface{}) (err error)

SaveConfig stores the config.

func SaveConfigs

func SaveConfigs(Filename string, Configs ...interface{}) (err error)

SaveConfigs stores the multiple configurations into a single file. They are essentially merged. It is the callers responsibility to make sure no field collision ensue.

func Secp256k1NewPrivateKey

func Secp256k1NewPrivateKey() (privateKey *btcec.PrivateKey, publicKey *btcec.PublicKey, err error)

Secp256k1NewPrivateKey creates a new public-private key pair

func ShouldSendFindSelf

func ShouldSendFindSelf() bool

ShouldSendFindSelf checks if FIND_SELF should be send

Types

type Backend

type Backend struct {
	ConfigFilename string      // Filename of the configuration file.
	Config         *Config     // Core configuration
	ConfigClient   interface{} // Custom configuration from the client
	Filters        Filters     // Filters allow to install hooks.

	GlobalBlockchainCache *BlockchainCache         // Caches blockchains of other peers.
	SearchIndex           *search.SearchIndexStore // Search index of blockchain records.

	UserBlockchain *blockchain.Blockchain // UserBlockchain is the user's blockchain and exports functions to directly read and write it
	UserWarehouse  *warehouse.Warehouse   // UserWarehouse is the user's warehouse for storing files that are shared

	// peerID is the current peer's ID. It is a ECDSA (secp256k1) 257-bit public key.
	PeerPrivateKey *btcec.PrivateKey
	PeerPublicKey  *btcec.PublicKey

	// PeerList keeps track of all peers
	PeerList map[[btcec.PubKeyBytesLenCompressed]byte]*PeerInfo

	// Stdout bundles any output for the end-user. Writers may subscribe/unsubscribe.
	Stdout *multiWriter
	// contains filtered or unexported fields
}

The Backend represents an instance of a Peernet client to be used by a frontend. Global variables and init functions are to be merged.

func Init

func Init(UserAgent string, ConfigFilename string, Filters *Filters, ConfigOut interface{}) (backend *Backend, status int, err error)

Init initializes the client. If the config file does not exist or is empty, a default one will be created. The User Agent must be provided in the form "Application Username/1.0". The returned status is of type ExitX. Anything other than ExitSuccess indicates a fatal failure.

func (*Backend) AsyncSearch

func (backend *Backend) AsyncSearch(Action int, Key []byte, Timeout, TimeoutIR time.Duration, Alpha int) (client *dht.SearchClient)

AsyncSearch creates an async search for the given key in the DHT. Timeout is the total time the search may take, covering all information requests. TimeoutIR is the time an information request may take. Alpha is the number of concurrent requests that will be performed.

func (*Backend) Connect

func (backend *Backend) Connect()

Connect starts bootstrapping and local peer discovery.

func (*Backend) DeleteAccount

func (backend *Backend) DeleteAccount()

DeleteAccount deletes the account

func (*Backend) ExportPrivateKey

func (backend *Backend) ExportPrivateKey() (privateKey *btcec.PrivateKey, publicKey *btcec.PublicKey)

ExportPrivateKey returns the peers public and private key

func (*Backend) FeatureSupport

func (backend *Backend) FeatureSupport() (feature byte)

FeatureSupport returns supported features by this peer

func (*Backend) FindNode

func (backend *Backend) FindNode(nodeID []byte, Timeout time.Duration) (node *dht.Node, peer *PeerInfo, err error)

FindNode finds a node via the DHT

func (*Backend) GetData

func (backend *Backend) GetData(hash []byte) (data []byte, senderNodeID []byte, found bool)

GetData returns the requested data. It checks first the local store and then tries via DHT.

func (*Backend) GetDataDHT

func (backend *Backend) GetDataDHT(hash []byte) (data []byte, senderNodeID []byte, found bool)

GetDataDHT requests data via DHT

func (*Backend) GetDataLocal

func (backend *Backend) GetDataLocal(hash []byte) (data []byte, found bool)

GetDataLocal returns data from the local warehouse.

func (*Backend) GetNetworks

func (backend *Backend) GetNetworks(networkType int) (networksConnected []*Network)

GetNetworks returns the list of connected networks

func (*Backend) IsNodeContact

func (backend *Backend) IsNodeContact(nodeID []byte) (node *dht.Node, peer *PeerInfo)

IsNodeContact checks if the node is a contact in the local DHT routing table

func (*Backend) LiteSessions

func (backend *Backend) LiteSessions() (sessions []*protocol.LiteID)

List of all lite sessions

func (*Backend) LogError

func (backend *Backend) LogError(function, format string, v ...interface{})

Logs an error message.

func (*Backend) NodelistLookup

func (backend *Backend) NodelistLookup(nodeID []byte) (peer *PeerInfo)

NodelistLookup returns the peer from the list with the node ID

func (*Backend) PeerlistAdd

func (backend *Backend) PeerlistAdd(PublicKey *btcec.PublicKey, connections ...*Connection) (peer *PeerInfo, added bool)

PeerlistAdd adds a new peer to the peer list. It does not validate the peer info. If the peer is already added, it does nothing. Connections must be live.

func (*Backend) PeerlistCount

func (backend *Backend) PeerlistCount() (count int)

PeerlistCount returns the current count of peers in the peer list

func (*Backend) PeerlistGet

func (backend *Backend) PeerlistGet() (peers []*PeerInfo)

PeerlistGet returns the full peer list

func (*Backend) PeerlistLookup

func (backend *Backend) PeerlistLookup(publicKey *btcec.PublicKey) (peer *PeerInfo)

PeerlistLookup returns the peer from the list with the public key

func (*Backend) PeerlistRemove

func (backend *Backend) PeerlistRemove(peer *PeerInfo)

PeerlistRemove removes a peer from the peer list.

func (*Backend) ReadBlock

func (backend *Backend) ReadBlock(PublicKey *btcec.PublicKey, Version, BlockNumber uint64) (decoded *blockchain.BlockDecoded, raw []byte, found bool, err error)

ReadBlock reads a block and decodes the records. This may be a block of the user's blockchain, or any other that is cached in the global blockchain cache.

func (*Backend) ReadFile

func (backend *Backend) ReadFile(PublicKey *btcec.PublicKey, Version, BlockNumber uint64, FileID uuid.UUID) (file blockchain.BlockRecordFile, raw []byte, found bool, err error)

ReadFile decodes a file from the given blockchain (the user or any other cached). The block number must be provided.

func (*Backend) SaveConfig

func (backend *Backend) SaveConfig()

SaveConfig stores the current runtime config to file. Any foreign settings not present in the Config structure will be deleted.

func (*Backend) SelfNodeID

func (backend *Backend) SelfNodeID() []byte

SelfNodeID returns the node ID used for DHT

func (*Backend) SelfUserAgent

func (backend *Backend) SelfUserAgent() string

SelfUserAgent returns the User Agent

func (*Backend) SendChatAll

func (backend *Backend) SendChatAll(text string)

SendChatAll sends a text message to all peers

func (*Backend) StoreDataDHT

func (backend *Backend) StoreDataDHT(data []byte, closestCount int) error

StoreDataDHT stores data locally and informs closestCount peers in the DHT about it. Remote peers may choose to keep a record (in case another peers asks) or mirror the full data.

func (*Backend) StoreDataLocal

func (backend *Backend) StoreDataLocal(data []byte) error

StoreDataLocal stores data into the local warehouse.

type BlockTransferStats

type BlockTransferStats struct {
	BlockchainPublicKey *btcec.PublicKey      // Target blockchain
	Direction           int                   // Direction of the data transfer
	LimitBlockCount     uint64                // Max count of blocks to be transferred
	MaxBlockSize        uint64                // Max single block size to transfer
	TargetBlocks        []protocol.BlockRange // List of blocks to transfer
	UDTConn             *udt.UDTSocket        // Underlying UDT connection
}

type BlockchainCache

type BlockchainCache struct {
	BlockchainDirectory string // The directory for storing blockchains in a key-value store.
	MaxBlockSize        uint64 // Max block size to accept.
	MaxBlockCount       uint64 // Max block count to cache per peer.
	LimitTotalRecords   uint64 // Max count of blocks and header in total to keep across all blockchains. 0 = unlimited. Max Records * Max Block Size = Size Limit.
	ReadOnly            bool   // Whether the cache is read only.

	Store *blockchain.MultiStore
	// contains filtered or unexported fields
}

The blockchain cache stores blockchains.

func (*BlockchainCache) SeenBlockchainVersion

func (cache *BlockchainCache) SeenBlockchainVersion(peer *PeerInfo)

SeenBlockchainVersion shall be called with information about another peer's blockchain. If the reported version number is newer, all existing blocks are immediately deleted.

type Config

type Config struct {
	// Locations of important files and folders
	LogFile          string `yaml:"LogFile"`          // Log file. It contains informational and error messages.
	BlockchainMain   string `yaml:"BlockchainMain"`   // Blockchain main stores the end-users blockchain data. It contains meta data of shared files, profile data, and social interactions.
	BlockchainGlobal string `yaml:"BlockchainGlobal"` // Blockchain global caches blockchain data from global users. Empty to disable.
	WarehouseMain    string `yaml:"WarehouseMain"`    // Warehouse main stores the actual data of files shared by the end-user.
	SearchIndex      string `yaml:"SearchIndex"`      // Local search index of blockchain records. Empty to disable.
	GeoIPDatabase    string `yaml:"GeoIPDatabase"`    // GeoLite2 City database to provide GeoIP information.
	DataFolder       string `yaml:"DataFolder"`       // Data folder.

	// Target for the log messages: 0 = Log file,  1 = Stdout, 2 = Log file + Stdout, 3 = None
	LogTarget int `yaml:"LogTarget"`

	// Listen settings
	Listen            []string `yaml:"Listen"`            // IP:Port combinations
	ListenWorkers     int      `yaml:"ListenWorkers"`     // Count of workers to process incoming raw packets. Default 2.
	ListenWorkersLite int      `yaml:"ListenWorkersLite"` // Count of workers to process incoming lite packets. Default 2.

	// User specific settings
	PrivateKey string `yaml:"PrivateKey"` // The Private Key, hex encoded so it can be copied manually

	// Initial peer seed list
	SeedList           []PeerSeed `yaml:"SeedList"`
	AutoUpdateSeedList bool       `yaml:"AutoUpdateSeedList"`
	SeedListVersion    int        `yaml:"SeedListVersion"`

	// Connection settings
	EnableUPnP    bool `yaml:"EnableUPnP"`    // Enables support for UPnP.
	LocalFirewall bool `yaml:"LocalFirewall"` // Indicates that a local firewall may drop unsolicited incoming packets.

	// PortForward specifies an external port that was manually forwarded by the user. All listening IPs must have that same port number forwarded!
	// If this setting is invalid, it will prohibit other peers from connecting. If set, it automatically disables UPnP.
	PortForward uint16 `yaml:"PortForward"`

	// Global blockchain cache limits
	CacheMaxBlockSize  uint64 `yaml:"CacheMaxBlockSize"`  // Max block size to accept in bytes.
	CacheMaxBlockCount uint64 `yaml:"CacheMaxBlockCount"` // Max block count to cache per peer.
	LimitTotalRecords  uint64 `yaml:"LimitTotalRecords"`  // Record count limit. 0 = unlimited. Max Records * Max Block Size = Size Limit.
}

Config defines the minimum required config for a Peernet client.

type Connection

type Connection struct {
	Network       *Network      // Network which received the packet.
	Address       *net.UDPAddr  // Address of the remote peer.
	PortInternal  uint16        // Internal listening port reported by remote peer. 0 if no Announcement/Response message was yet received.
	PortExternal  uint16        // External listening port reported by remote peer. 0 if not known by the peer.
	LastPacketIn  time.Time     // Last time an incoming packet was received.
	LastPacketOut time.Time     // Last time an outgoing packet was attempted to send.
	LastPingOut   time.Time     // Last ping out.
	Expires       time.Time     // Inactive connections only: Expiry date. If it does not become active by that date, it will be considered expired and removed.
	Status        int           // 0 = Active established connection, 1 = Inactive, 2 = Removed, 3 = Redundant
	RoundTripTime time.Duration // Full round-trip time of last reply.
	Firewall      bool          // Whether the remote peer indicates a potential firewall. This means a Traverse message shall be sent to establish a connection.
	// contains filtered or unexported fields
}

Connection is an established connection between a remote IP address and a local network adapter. New connections may only be created in case of successful INCOMING packets.

func (*Connection) Equal

func (c *Connection) Equal(other *Connection) bool

Equal checks if the connection was established other the same network adapter using the same IP address. Port is intentionally not checked.

func (*Connection) IsBehindNAT

func (c *Connection) IsBehindNAT() bool

IsBehindNAT checks if the remote peer on the connection is likely behind a NAT

func (*Connection) IsIPv4

func (c *Connection) IsIPv4() bool

IsIPv4 checks if the connection is using IPv4

func (*Connection) IsIPv6

func (c *Connection) IsIPv6() bool

IsIPv6 checks if the connection is using IPv6

func (*Connection) IsLocal

func (c *Connection) IsLocal() bool

IsLocal checks if the connection is a local network one (LAN)

func (*Connection) IsPortForward

func (c *Connection) IsPortForward() bool

IsPortForward checks if the remote peer uses port forwarding on the connection

type FileTransferStats

type FileTransferStats struct {
	Hash      []byte         // Hash of the file to transfer
	Direction int            // Direction of the data transfer
	FileSize  uint64         // File size if known
	Offset    uint64         // Offset to start the transfer
	Limit     uint64         // Limit in bytes to transfer
	UDTConn   *udt.UDTSocket // Underlying UDT connection
}

type Filters

type Filters struct {
	// NewPeer is called every time a new peer, that is one that is not currently in the peer list.
	// Note that peers might be removed from peer lists and reappear quickly, i.e. this function may be called multiple times for the same peers.
	// The filter must maintain its own map of unique peer IDs if actual uniqueness of new peers is desired.
	NewPeer func(peer *PeerInfo, connection *Connection)

	// NewPeerConnection is called for each new established connection to a peer. Note that connections might be dropped and reconnected at anytime.
	NewPeerConnection func(peer *PeerInfo, connection *Connection)

	// LogError is called for any error.
	LogError func(function, format string, v ...interface{})

	// DHTSearchStatus is called with updates of searches in the DHT. It allows to see the live progress of searches.
	DHTSearchStatus func(client *dht.SearchClient, function, format string, v ...interface{})

	// IncomingRequest receives all incoming information requests. The action field is set accordingly.
	IncomingRequest func(peer *PeerInfo, Action int, Key []byte, Info interface{})

	// PacketIn is a low-level filter for incoming packets after they are decrypted.
	// Traverse messages are not covered.
	PacketIn func(packet *protocol.PacketRaw, senderPublicKey *btcec.PublicKey, connection *Connection)

	// PacketOut is a low-level filter for outgoing packets before they are encrypted.
	// IPv4 broadcast, IPv6 multicast, and Traverse messages are not covered.
	PacketOut func(packet *protocol.PacketRaw, receiverPublicKey *btcec.PublicKey, connection *Connection)

	// MessageIn is a high-level filter for decoded incoming messages. message is of type nil, MessageAnnouncement, MessageResponse, or MessageTraverse
	MessageIn func(peer *PeerInfo, raw *protocol.MessageRaw, message interface{})

	// MessageOutAnnouncement is a high-level filter for outgoing announcements. Peer is nil on first contact.
	// Broadcast and Multicast messages are not covered.
	MessageOutAnnouncement func(receiverPublicKey *btcec.PublicKey, peer *PeerInfo, packet *protocol.PacketRaw, findSelf bool, findPeer []protocol.KeyHash, findValue []protocol.KeyHash, files []protocol.InfoStore)

	// MessageOutResponse is a high-level filter for outgoing responses.
	MessageOutResponse func(peer *PeerInfo, packet *protocol.PacketRaw, hash2Peers []protocol.Hash2Peer, filesEmbed []protocol.EmbeddedFileData, hashesNotFound [][]byte)

	// MessageOutTraverse is a high-level filter for outgoing traverse messages.
	MessageOutTraverse func(peer *PeerInfo, packet *protocol.PacketRaw, embeddedPacket *protocol.PacketRaw, receiverEnd *btcec.PublicKey)

	// MessageOutPing is a high-level filter for outgoing pings.
	MessageOutPing func(peer *PeerInfo, packet *protocol.PacketRaw, connection *Connection)

	// MessageOutPong is a high-level filter for outgoing pongs.
	MessageOutPong func(peer *PeerInfo, packet *protocol.PacketRaw)

	// Called when the statistics change of a single blockchain in the cache. Must be set on init.
	GlobalBlockchainCacheStatistic func(multi *blockchain.MultiStore, header *blockchain.MultiBlockchainHeader, statsOld blockchain.BlockchainStats)

	// Called after a blockchain is deleted from the blockchain cache. The header reflects the status before deletion. Must be set on init.
	GlobalBlockchainCacheDelete func(multi *blockchain.MultiStore, header *blockchain.MultiBlockchainHeader)
}

Filters contains all functions to install the hook. Use nil for unused. The functions are called sequentially and block execution; if the filter takes a long time it should start a Go routine.

type Network

type Network struct {
	sync.RWMutex // for sychronized closing
	// contains filtered or unexported fields
}

Network is a connection adapter through one network interface (adapter). Note that for each IP on the same adapter separate network entries are created.

func (*Network) AutoAssignPort

func (network *Network) AutoAssignPort(ip net.IP, port int) (err error)

AutoAssignPort assigns a port for the given IP. Use port 0 for zero configuration.

func (*Network) BroadcastIPv4

func (network *Network) BroadcastIPv4() (err error)

BroadcastIPv4 prepares sending Broadcasts

func (*Network) BroadcastIPv4Listen

func (network *Network) BroadcastIPv4Listen()

BroadcastIPv4Listen listens for incoming broadcast packets Fork from network.Listen! Keep any changes synced.

func (*Network) BroadcastIPv4Send

func (network *Network) BroadcastIPv4Send() (err error)

BroadcastIPv4Send sends out a single broadcast messages to discover peers

func (*Network) GetAdapterName

func (network *Network) GetAdapterName() string

GetAdapterName returns the adapter name, if available

func (*Network) GetListen

func (network *Network) GetListen() (listen *net.UDPAddr, multicastIPv6 net.IP, broadcastIPv4 []net.IP, ipExternal net.IP, portExternal uint16)

GetListen returns connectivity information

func (*Network) Listen

func (network *Network) Listen()

Listen starts listening for incoming packets on the given UDP connection

func (*Network) MulticastIPv6Join

func (network *Network) MulticastIPv6Join() (err error)

MulticastIPv6Join joins the Multicast group

func (*Network) MulticastIPv6Listen

func (network *Network) MulticastIPv6Listen()

MulticastIPv6Listen listens for incoming multicast packets Fork from network.Listen! Keep any changes synced.

func (*Network) MulticastIPv6Send

func (network *Network) MulticastIPv6Send() (err error)

MulticastIPv6Send sends out a single multicast messages to discover peers at the same site

func (*Network) SelfReportedPorts

func (network *Network) SelfReportedPorts() (portI, portE uint16)

SelfReportedPorts returns the internal and external ports as self-reported by the peer to others.

func (*Network) Terminate

func (network *Network) Terminate()

Terminate sends the termination signal to all workers. It is safe to call Terminate multiple times.

type Networks

type Networks struct {

	// Mutex for both network lists. Higher granularity currently not needed.
	sync.RWMutex

	// Sequences keeps track of all message sequence number, regardless of the network connection.
	Sequences *protocol.SequenceManager

	// Keep track of valid IDs for lite packets.
	LiteRouter *protocol.LiteRouter
	// contains filtered or unexported fields
}

Networks is the collection of all connected networks

func (*Networks) InterfaceStart

func (nets *Networks) InterfaceStart(iface net.Interface, addresses []net.Addr) (networksNew []*Network)

InterfaceStart will start the listeners on all the IP addresses for the network

func (*Networks) PrepareListen

func (nets *Networks) PrepareListen(ipA string, port int) (network *Network, err error)

PrepareListen creates a new network and prepares to listen on the given IP address. If port is 0, one is chosen automatically.

type PeerInfo

type PeerInfo struct {
	PublicKey *btcec.PublicKey // Public key
	NodeID    []byte           // Node ID in Kademlia network = blake3(Public Key).

	sync.RWMutex // Mutex for access to list of connections.

	IsRootPeer bool   // Whether the peer is a trusted root peer.
	UserAgent  string // User Agent reported by remote peer. Empty if no Announcement/Response message was yet received.
	Features   uint8  // Feature bit array. 0 = IPv4_LISTEN, 1 = IPv6_LISTEN, 1 = FIREWALL

	BlockchainHeight  uint64 // Blockchain height
	BlockchainVersion uint64 // Blockchain version

	// statistics
	StatsPacketSent     uint64 // Count of packets sent
	StatsPacketReceived uint64 // Count of packets received

	Backend *Backend
	// contains filtered or unexported fields
}

PeerInfo stores information about a single remote peer

func (*PeerInfo) BlockDownload

func (peer *PeerInfo) BlockDownload(BlockchainPublicKey *btcec.PublicKey, LimitBlockCount, MaxBlockSize uint64, TargetBlocks []protocol.BlockRange, callback func(data []byte, targetBlock protocol.BlockRange, blockSize uint64, availability uint8)) (err error)

Downloads the requested blocks for the selected blockchain from the remote peer. The callback is called for each result.

func (*PeerInfo) BlockTransferRequest

func (peer *PeerInfo) BlockTransferRequest(BlockchainPublicKey *btcec.PublicKey, LimitBlockCount uint64, MaxBlockSize uint64, TargetBlocks []protocol.BlockRange) (udtConn *udt.UDTSocket, virtualConn *VirtualPacketConn, err error)

BlockTransferRequest requests blocks from the peer. The caller must call udtConn.Close() when done. Do not use any of the closing functions of virtualConn.

func (*PeerInfo) Chat

func (peer *PeerInfo) Chat(text string)

Chat sends a text message

func (*PeerInfo) FileTransferRequestUDT

func (peer *PeerInfo) FileTransferRequestUDT(hash []byte, offset, limit uint64) (udtConn *udt.UDTSocket, virtualConn *VirtualPacketConn, err error)

FileTransferRequestUDT creates a UDT server listening for incoming data transfer via the lite protocol and requests a file transfer from a remote peer. The caller must call udtConn.Close() when done. Do not use any of the closing functions of virtualConn. Limit is optional. 0 means the entire file.

func (*PeerInfo) GetConnection2Share

func (peer *PeerInfo) GetConnection2Share(allowLocal, allowIPv4, allowIPv6 bool) (connection *Connection)

GetConnection2Share returns a connection to share. Nil if none. allowLocal specifies whether it is OK to return local IPs.

func (*PeerInfo) GetConnections

func (peer *PeerInfo) GetConnections(active bool) (connections []*Connection)

GetConnections returns the list of connections

func (*PeerInfo) GetRTT

func (peer *PeerInfo) GetRTT() (rtt time.Duration)

GetRTT returns the round-trip time for the most recent active connection. 0 if not available.

func (*PeerInfo) IsBehindNAT

func (peer *PeerInfo) IsBehindNAT() (result bool)

IsBehindNAT checks if the peer is behind NAT

func (*PeerInfo) IsConnectable

func (peer *PeerInfo) IsConnectable(allowLocal, allowIPv4, allowIPv6 bool) bool

IsConnectable checks if the peer is connectable to the given IP parameters.

func (*PeerInfo) IsConnectionActive

func (peer *PeerInfo) IsConnectionActive() bool

IsConnectionActive checks if the peer has an active connection that can be used to send and receive messages

func (*PeerInfo) IsFirewallReported

func (peer *PeerInfo) IsFirewallReported() (result bool)

IsFirewallReported checks if the peer reported to be behind a firewall

func (*PeerInfo) IsPortForward

func (peer *PeerInfo) IsPortForward() (result bool)

IsPortForward checks if the peer uses port forwarding

func (*PeerInfo) IsVirtual

func (peer *PeerInfo) IsVirtual() bool

IsVirtual returns true if the peer has not been connected yet. This is the case if another peer responds with peer details, and that peer shall be contacted.

func (*PeerInfo) Ping

func (peer *PeerInfo) Ping()

Ping sends a ping. This function exists only for debugging purposes, it should not be used normally. This ping is not used for uptime detection and the LastPingOut time in connections is not set.

type PeerSeed

type PeerSeed struct {
	PublicKey string   `yaml:"PublicKey"` // Public key = peer ID. Hex encoded.
	Address   []string `yaml:"Address"`   // IP:Port
}

PeerSeed is a singl peer entry from the config's seed list

type VirtualPacketConn

type VirtualPacketConn struct {
	Peer *PeerInfo

	// Stats are maintained by the caller
	Stats interface{}

	sync.Mutex
	// contains filtered or unexported fields
}

VirtualPacketConn is a virtual connection.

func (*VirtualPacketConn) Close

func (v *VirtualPacketConn) Close(reason int) (err error)

Close provides a Close function to be called by the underlying transfer protocol. Do not call the function manually; otherwise the underlying transfer protocol may not have time to send a termination message (and the remote peer would subsequently try to reconnect). Rather, use the underlying transfer protocol's close function.

func (*VirtualPacketConn) CloseLinger

func (v *VirtualPacketConn) CloseLinger(reason int) (err error)

CloseLinger is to be called by the underlying transfer protocol when it will close the socket soon after lingering around. Lingering happens to resend packets at the end of transfer, when it is not immediately known whether the remote peer received all packets.

func (*VirtualPacketConn) GetTerminateReason

func (v *VirtualPacketConn) GetTerminateReason() int

GetTerminateReason returns the termination reason. 0 = Not yet terminated.

func (*VirtualPacketConn) IsTerminated

func (v *VirtualPacketConn) IsTerminated() bool

IsTerminated checks if the connection is terminated

func (*VirtualPacketConn) Terminate

func (v *VirtualPacketConn) Terminate(reason int) (err error)

Terminate closes the connection. Do not call this function manually. Use the underlying protocol's function to close the connection. Reason: 404 = Remote peer does not store file (upstream), 2 = Remote termination signal (upstream), 3 = Sequence invalidation or expiration (upstream), 1000+ = Transfer protocol indicated closing (downstream)

Directories

Path Synopsis
Package btcec implements support for the elliptic curves needed for bitcoin.
Package btcec implements support for the elliptic curves needed for bitcoin.
Package reuseport provides Listen and Dial functions that set socket options in order to be able to reuse ports.
Package reuseport provides Listen and Dial functions that set socket options in order to be able to reuse ports.
udt
File Username: Shared Recent.go Copyright: 2021 Peernet Foundation s.r.o.
File Username: Shared Recent.go Copyright: 2021 Peernet Foundation s.r.o.

Jump to

Keyboard shortcuts

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