p2p

package
v0.0.0-...-303b437 Latest Latest
Warning

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

Go to latest
Published: Sep 10, 2019 License: Apache-2.0, BSD-2-Clause, BSD-3-Clause, + 4 more Imports: 20 Imported by: 4

README

Factom P2P Networking

Diagram

diagram.jpg

Conceptual

The P2P Network for factom is a custom library which is mostly independent of hte dcnt codebase. It has almost no external dependencies.

It is designed to be autonamous and operate without configuration. When starting up a node will look to the information in the configuration file and the command line to determine who to connect to. The seedURL is a source of initial peers to connect ot for new nodes. Each node will attempt to keep at least 8 outgoing connections live and allow a larger number of incomming connections.

Nodes share peers with each other when they first connect, and periodically thereafter. Nodes also check the messages they get from other nodes ot verify they are on the same network (eg: production blockchain vs testnet) and are of compatible software versions among other things. Each connection results in merits or demerits depending on the quality of the connection. The nodes keep a quality score on a per-IP basis.

Please note that all the networking is IPV4. IPV6 is not supported. Additionally, this network will not tunnel thru NAT.

Nodes can be set up to only dial out to a limited set of peers, called "special peers". Special peers are not shareed with other peers in the network. Additionally, special peers will always be connected to and if there are conectivity problems the connections will remain persistent, and constantly reconnect. Special peers can be determined on the command line or in the configuration file.

Operations

Command line options
  -customnet string
    	This string specifies a custom blockchain network ID.
  -network string
    	Network to join: MAIN, TEST or LOCAL
  -networkPort int
    	Address for p2p network to listen on.
  -peers string
    	Array of peer addresses. 
      These peers are considered "special"
Config file

An example of the config file is below. Network determines which network we are participating in. Main is the production blockchain. TEST is the Testnet.

For each network type you can change the port, seedURL and peers. The SeedURL is a static file of known trusted peers to connect to. The special peers are peers you want to always dial out to.

; --------------- Network: MAIN | TEST | LOCAL
Network                               = LOCAL
PeersFile            = "peers.json"
MainNetworkPort      = 8108
MainSeedURL          = "https://raw.githubusercontent.com/DCNT-developer/DCNT/master/seed/mainseed.txt"
MainSpecialPeers     = ""
TestNetworkPort      = 8109
TestSeedURL          = "https://raw.githubusercontent.com/DCNT-developer/DCNT/master/seed/testseed.txt"
TestSpecialPeers     = ""
LocalNetworkPort     = 8110
LocalSeedURL         = "https://raw.githubusercontent.com/DCNT-developer/DCNT/master/seed/localseed.txt"
LocalSpecialPeers    = ""

Seed file example:

1.2.3.4:5678
2.3.4.5:6789

Architecture

App <-> Controller <-> Connection <-> TCP (or UDP in future)

Controller - controller.go This manages the peers in the network. It keeps connections alive, and routes messages from the application to the appropriate peer. It talks to the application over several channels. It uses a commandChannel for process isolation, but provides public functions for all of the commands. The messages for the network peers go over the ToNetwork and come in on the FromNetwork channels.

Connection - connection.go This struct represents an individual connection to another peer. It talks to the controller over channels, again providing process/memory isolation.

Documentation

Index

Constants

View Source
const (
	ConnectionInitialized  uint8 = iota //Structure created, have peer info. Dial command moves us to Online or Shutdown (depending)
	ConnectionOnline                    // We're connected to the other side.  Normal state
	ConnectionOffline                   // We've been disconnected for whatever reason.  Attempt to reconnect some number of times. Moves to Online if successful, Shutdown if not.
	ConnectionShuttingDown              // We're shutting down, the receives loop exits.
	ConnectionClosed                    // We're shut down, the runloop sets this state right before exiting. Controller can clean us up.
)

Each connection is a simple state machine. The state is managed by a single goroutine which also does networking. The flow is this: Connection gets initialized, and either has a peer or a net connection (From an accept()) If no network connection, the Connection dials. If the dial is successful, it moves to the Online state If not, it moves to the Shutdown state-- we only dial out once when initialized with a peer. If we are online and get a network error, we shift to offline mode. In offline state we attempt to reconnect for a period defined in protocol.go. IF successful, we go back Online. If too many attempts are made, we go to The ConnectionShutdown state, and exit the runloop. In the Shutdown state we notify the controller so that we can be cleaned up.

View Source
const (
	ConnectionIsClosed uint8 = iota // Notifies the controller that we are shut down and can be released
	ConnectionShutdownNow
	ConnectionUpdatingPeer
	ConnectionAdjustPeerQuality
	ConnectionUpdateMetrics
	ConnectionGoOffline // Notifies the connection it should go offinline (eg from another goroutine)
)

These are the commands that connections can send/receive

View Source
const (
	ParcelValid           uint8 = iota
	InvalidPeerDemerit          // The peer sent an invalid message
	InvalidDisconnectPeer       // Eg they are on the wrong network or wrong version of the software
)

These constants support the multiple penalties and responses for Parcel validation

View Source
const (
	RegularPeer        uint8 = iota
	SpecialPeerConfig        // special peer defined in the config file
	SpecialPeerCmdLine       // special peer defined via the cmd line params
)
View Source
const (
	// ProtocolVersion is the latest version this package supports
	ProtocolVersion uint16 = 9
	// ProtocolVersionMinimum is the earliest version this package supports
	ProtocolVersionMinimum uint16 = 9
)
View Source
const MaxPayloadSize = 1000000000

MaxPayloadSize is the maximum bytes a message can be at the networking level.

View Source
const MaxTimeWaitingForReassembly time.Duration = time.Second * 60 * 10

maximum time we wait for a partial message to arrive, old entries are cleaned up only when new part arrives

View Source
const ParcelHeaderSize = 32

ParcelHeaderSize is the number of bytes in a parcel header

Variables

View Source
var (
	SentToPeers = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "dcnt_state_number_of_peers_broadcast",
		Help: "Number of Peers to which we are broadcasting messages",
	})

	StartingPoint = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "dcnt_StartingPoint_peers_broadcast",
		Help: "Number of msgs broadcasting",
	})
)
View Source
var (
	CurrentNetwork                      = TestNet
	NetworkListenPort                   = "8108"
	BroadcastFlag                       = "<BROADCAST>"
	FullBroadcastFlag                   = "<FULLBORADCAST>"
	RandomPeerFlag                      = "<RANDOMPEER>"
	NodeID                       uint64 = 0           // Random number used for loopback protection
	MinumumQualityScore          int32  = -200        // if a peer's score is less than this we ignore them.
	BannedQualityScore           int32  = -2147000000 // Used to ban a peer
	MinumumSharingQualityScore   int32  = 20          // if a peer's score is less than this we don't share them.
	OnlySpecialPeers                    = false       // dial out to special peers only
	AllowUnknownIncomingPeers           = true        // allow incoming connections from peers that are not in the special peer list
	NetworkDeadline                     = time.Duration(30) * time.Second
	NumberPeersToConnect                = 32  // default value; changeable in cfg and cmd line
	NumberPeersToBroadcast              = 16  // This gets overwritten by command line flag!
	MaxNumberIncomingConnections        = 200 // default value; changeable in cfg and cmd line
	MaxNumberOfRedialAttempts           = 5   // How many missing pings (and other) before we give up and close.
	StandardChannelSize                 = 5000
	NetworkStatusInterval               = time.Second * 9
	ConnectionStatusInterval            = time.Second * 122
	PingInterval                        = time.Second * 15
	TimeBetweenRedials                  = time.Second * 20
	PeerSaveInterval                    = time.Second * 30
	PeerRequestInterval                 = time.Second * 180
	PeerDiscoveryInterval               = time.Hour * 4

	// Testing metrics
	TotalMessagesReceived       uint64
	TotalMessagesSent           uint64
	ApplicationMessagesReceived uint64

	CRCKoopmanTable = crc32.MakeTable(crc32.Koopman)
	RandomGenerator *rand.Rand // seeded pseudo-random number generator

)

Global variables for the p2p protocol

View Source
var CommandStrings = map[ParcelCommandType]string{
	TypeHeartbeat:    "Heartbeat",
	TypePing:         "Ping",
	TypePong:         "Pong",
	TypePeerRequest:  "Peer-Request",
	TypePeerResponse: "Peer-Response",
	TypeAlert:        "Alert",
	TypeMessage:      "Message",
	TypeMessagePart:  "MessagePart",
}

CommandStrings is a Map of command ids to strings for easy printing of network comands

View Source
var UpdateKnownPeers sync.Mutex

Functions

func BlockFreeChannelSend

func BlockFreeChannelSend(channel chan interface{}, message interface{}) int

BlockFreeChannelSend will remove things from the queue to make room for new messages if the queue is full. This prevents channel blocking on full.

Returns: The number of elements cleared from the channel to make room

func LimitListenerAll

func LimitListenerAll(l net.Listener) net.Listener

func LimitListenerSources

func LimitListenerSources(l net.Listener) net.Listener

func RegisterPrometheus

func RegisterPrometheus()

RegisterPrometheus registers the variables to be exposed. This can only be run once, hence the boolean flag to prevent panics if launched more than once. This is called in NetStart

Types

type CommandAddPeer

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

CommandAddPeer is used to instruct the Controller to add a connection This connection can come from acceptLoop or some other way.

type CommandAdjustPeerQuality

type CommandAdjustPeerQuality struct {
	PeerHash   string
	Adjustment int32
}

CommandAdjustPeerQuality is used to instruct the Controller to reduce a connections quality score

func (*CommandAdjustPeerQuality) JSONByte

func (e *CommandAdjustPeerQuality) JSONByte() ([]byte, error)

func (*CommandAdjustPeerQuality) JSONString

func (e *CommandAdjustPeerQuality) JSONString() (string, error)

func (*CommandAdjustPeerQuality) String

func (e *CommandAdjustPeerQuality) String() string

type CommandBan

type CommandBan struct {
	PeerHash string
}

CommandBan is used to instruct the Controller to disconnect and ban a peer

func (*CommandBan) JSONByte

func (e *CommandBan) JSONByte() ([]byte, error)

func (*CommandBan) JSONString

func (e *CommandBan) JSONString() (string, error)

func (*CommandBan) String

func (e *CommandBan) String() string

type CommandDialPeer

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

CommandDialPeer is used to instruct the Controller to dial a peer address

type CommandDisconnect

type CommandDisconnect struct {
	PeerHash string
}

CommandDisconnect is used to instruct the Controller to disconnect from a peer

func (*CommandDisconnect) JSONByte

func (e *CommandDisconnect) JSONByte() ([]byte, error)

func (*CommandDisconnect) JSONString

func (e *CommandDisconnect) JSONString() (string, error)

func (*CommandDisconnect) String

func (e *CommandDisconnect) String() string

type CommandShutdown

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

CommandShutdown is used to instruct the Controller to takve various actions.

type Connection

type Connection struct {
	Errors         chan error              // handle errors from connections.
	Commands       chan *ConnectionCommand // handle connection commands
	SendChannel    chan interface{}        // Send means "towards the network" Channel sends Parcels and ConnectionCommands
	ReceiveChannel chan interface{}        // Receive means "from the network" Channel receives Parcels and ConnectionCommands
	ReceiveParcel  chan *Parcel            // Parcels to be handled.

	TimeLastpacket time.Time // Time we last successfully received a packet or command.
	// contains filtered or unexported fields
}

Connection represents a single connection to another peer over the network. It communicates with the application via two channels, send and receive. These channels take structs of type ConnectionCommand or ConnectionParcel (defined below).

func (*Connection) ConnectionState

func (c *Connection) ConnectionState() string

func (*Connection) CopyMetricsFrom

func (c *Connection) CopyMetricsFrom(another *Connection)

Copies metrics from another connection to this one.

func (*Connection) Init

func (c *Connection) Init(peer Peer, persistent bool) *Connection

Init is called when we have peer info and need to dial into the peer

func (*Connection) InitWithConn

func (c *Connection) InitWithConn(conn net.Conn, peer Peer) *Connection

InitWithConn is called from our accept loop when a peer dials into us and we already have a network conn

func (*Connection) IsOnline

func (c *Connection) IsOnline() bool

func (*Connection) IsOutGoing

func (c *Connection) IsOutGoing() bool

func (*Connection) IsPersistent

func (c *Connection) IsPersistent() bool

func (*Connection) Notes

func (c *Connection) Notes() string

func (*Connection) Start

func (c *Connection) Start()

func (*Connection) StatusString

func (c *Connection) StatusString() string

type ConnectionCommand

type ConnectionCommand struct {
	Command uint8
	Peer    Peer
	Delta   int32
	Metrics ConnectionMetrics
}

ConnectionCommand is used to instruct the Connection to carry out some functionality.

func (*ConnectionCommand) JSONByte

func (e *ConnectionCommand) JSONByte() ([]byte, error)

func (*ConnectionCommand) JSONString

func (e *ConnectionCommand) JSONString() (string, error)

func (*ConnectionCommand) String

func (e *ConnectionCommand) String() string

type ConnectionManager

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

func (*ConnectionManager) Add

func (cm *ConnectionManager) Add(connection *Connection)

Add a new connection.

func (*ConnectionManager) All

func (cm *ConnectionManager) All() map[string]*Connection

Get the map of all connections by the peer hash.

func (*ConnectionManager) ConnectedTo

func (cm *ConnectionManager) ConnectedTo(address string) bool

Checks if we are already connected to a specified address.

func (*ConnectionManager) Count

func (cm *ConnectionManager) Count() int

Get the number of all connections

func (*ConnectionManager) GetAllRegular

func (cm *ConnectionManager) GetAllRegular() []*Connection

Get connections for all online, active regular peers, but in random order.

func (*ConnectionManager) GetByHash

func (cm *ConnectionManager) GetByHash(peerHash string) (*Connection, bool)

Get the connection for a specified peer hash.

func (*ConnectionManager) GetRandom

func (cm *ConnectionManager) GetRandom() *Connection

Get a single random connection from all the online and active connection we have, returns nil if none are found.

func (*ConnectionManager) GetRandomRegular

func (cm *ConnectionManager) GetRandomRegular(sampleSize int) []*Connection

Get a set of random connections from all the online, active regular peers we have.

func (*ConnectionManager) Init

func (*ConnectionManager) Remove

func (cm *ConnectionManager) Remove(connection *Connection)

Remove an existing connection.

func (*ConnectionManager) SendToAll

func (cm *ConnectionManager) SendToAll(message interface{})

Send a message to all the connections.

func (*ConnectionManager) UpdatePrometheusMetrics

func (cm *ConnectionManager) UpdatePrometheusMetrics()

Update connection counts in Prometheus.

type ConnectionMetrics

type ConnectionMetrics struct {
	MomentConnected  time.Time // when the connection started.
	BytesSent        uint32    // Keeping track of the data sent/received for console
	BytesReceived    uint32    // Keeping track of the data sent/received for console
	MessagesSent     uint32    // Keeping track of the data sent/received for console
	MessagesReceived uint32    // Keeping track of the data sent/received for console
	PeerAddress      string    // Peer IP Address
	PeerQuality      int32     // Quality of the connection.
	PeerType         string    // Type of the peer (regular, special_config, ...)
	// Red: Below -50
	// Yellow: -50 - 100
	// Green: > 100
	ConnectionState string // Basic state of the connection
	ConnectionNotes string // Connectivity notes for the connection
}

ConnectionMetrics is used to encapsulate various metrics about the connection.

type ConnectionParcel

type ConnectionParcel struct {
	Parcel Parcel
}

ConnectionParcel is sent to convey an application message destined for the network.

func (*ConnectionParcel) JSONByte

func (e *ConnectionParcel) JSONByte() ([]byte, error)

func (*ConnectionParcel) JSONString

func (e *ConnectionParcel) JSONString() (string, error)

func (*ConnectionParcel) String

func (e *ConnectionParcel) String() string

type Controller

type Controller struct {
	ToNetwork   chan interface{} // Parcels from the application for us to route
	FromNetwork chan interface{} // Parcels from the network for the application

	NodeID uint64
	// contains filtered or unexported fields
}

Controller manages the peer to peer network.

func (*Controller) AddPeer

func (c *Controller) AddPeer(conn net.Conn)

func (*Controller) AdjustPeerQuality

func (c *Controller) AdjustPeerQuality(peerHash string, adjustment int32)

func (*Controller) Ban

func (c *Controller) Ban(peerHash string)

func (*Controller) DialPeer

func (c *Controller) DialPeer(peer Peer, persistent bool)

func (*Controller) Disconnect

func (c *Controller) Disconnect(peerHash string)

func (*Controller) GetNumberOfConnections

func (c *Controller) GetNumberOfConnections() int

func (*Controller) Init

func (c *Controller) Init(ci ControllerInit) *Controller

func (*Controller) NetworkStop

func (c *Controller) NetworkStop()

func (*Controller) ReloadSpecialPeers

func (c *Controller) ReloadSpecialPeers(newPeersConfig string)

func (*Controller) StartNetwork

func (c *Controller) StartNetwork()

StartNetwork configures the network, starts the runloop

type ControllerInit

type ControllerInit struct {
	NodeName                 string           // Name of the current node
	Port                     string           // Port to listen on
	PeersFile                string           // Path to file to find / save peers
	Network                  NetworkID        // Network - eg MainNet, TestNet etc.
	Exclusive                bool             // flag to indicate we should only connect to trusted peers
	ExclusiveIn              bool             // flag to indicate we should only connect to trusted peers and disallow incoming connections
	SeedURL                  string           // URL to a source of peer info
	ConfigPeers              string           // Peers to always connect to at startup, and stay persistent, passed from the config file
	CmdLinePeers             string           // Additional special peers passed from the command line
	ConnectionMetricsChannel chan interface{} // Channel on which we put the connection metrics map, periodically.
	LogPath                  string           // Path for logs
	LogLevel                 string           // Logging level
}

type Discovery

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

func (*Discovery) DiscoverPeersFromSeed

func (d *Discovery) DiscoverPeersFromSeed()

DiscoverPeers gets a set of peers from a DNS Seed

func (*Discovery) GetOutgoingPeers

func (d *Discovery) GetOutgoingPeers() []Peer

GetOutgoingPeers gets a set of peers to connect to on startup For now, this gives a set of 12 of the total known peers. We want peers from diverse networks. So,method is this:

	-- generate list of candidates (if exclusive, only special peers)
	-- sort candidates by distance
 -- if num canddiates is less than desired set, return all candidates
 -- Otherwise,repeatedly take candidates at the 0%, %25, %50, %75, %100 points in the list
 -- remove each candidate from the list.
 -- continue until there are no candidates left, or we have our set.

func (*Discovery) Init

func (d *Discovery) Init(peersFile string, seed string) *Discovery

func (*Discovery) LearnPeers

func (d *Discovery) LearnPeers(parcel Parcel)

LearnPeers receives a set of peers from other hosts The unique peers are added to our peer list. The peers are in a json encoded string as a byte slice

func (*Discovery) LoadPeers

func (d *Discovery) LoadPeers()

LoadPeers loads the known peers from disk OVERWRITING PREVIOUS VALUES

func (*Discovery) SavePeers

func (d *Discovery) SavePeers()

SavePeers just saves our known peers out to disk. Called periodically.

func (*Discovery) SharePeers

func (d *Discovery) SharePeers() []byte

SharePeers gets a set of peers to send to other hosts For now, this gives a random set of the total known peers. The peers are in a json encoded string as byte slice

type NetworkID

type NetworkID uint32

NetworkIdentifier represents the P2P network we are participating in (eg: test, nmain, etc.)

const (
	// MainNet represents the production network
	MainNet NetworkID = 0xfeedbeef

	// TestNet represents a testing network
	TestNet NetworkID = 0xdeadbeef

	// LocalNet represents any arbitrary/private network
	LocalNet NetworkID = 0xbeaded
)

Network indicators.

func (*NetworkID) String

func (n *NetworkID) String() string

type Parcel

type Parcel struct {
	Header  ParcelHeader
	Payload []byte
}

Parcel is the atomic level of communication for the p2p network. It contains within it the necessary info for the networking protocol, plus the message that the Application is sending.

func NewParcel

func NewParcel(network NetworkID, payload []byte) *Parcel

func ParcelsForPayload

func ParcelsForPayload(network NetworkID, payload []byte) []Parcel

func ReassembleParcel

func ReassembleParcel(parcels []*Parcel) *Parcel

func (*Parcel) Init

func (p *Parcel) Init(header ParcelHeader) *Parcel

func (*Parcel) LogEntry

func (p *Parcel) LogEntry() *log.Entry

func (*Parcel) MessageType

func (p *Parcel) MessageType() string

func (*Parcel) UpdateHeader

func (p *Parcel) UpdateHeader()

type ParcelCommandType

type ParcelCommandType uint16
const (
	TypeHeartbeat    ParcelCommandType = iota // "Note, I'm still alive"
	TypePing                                  // "Are you there?"
	TypePong                                  // "yes, I'm here"
	TypePeerRequest                           // "Please share some peers"
	TypePeerResponse                          // "Here's some peers I know about."
	TypeAlert                                 // network wide alerts (used in bitcoin to indicate criticalities)
	TypeMessage                               // Application level message
	TypeMessagePart                           // Application level message that was split into multiple parts
)

Parcel commands -- all new commands should be added to the *end* of the list!

type ParcelHeader

type ParcelHeader struct {
	Network     NetworkID         // 4 bytes - the network we are on (eg testnet, main net, etc.)
	Version     uint16            // 2 bytes - the version of the protocol we are running.
	Type        ParcelCommandType // 2 bytes - network level commands (eg: ping/pong)
	Length      uint32            // 4 bytes - length of the payload (that follows this header) in bytes
	TargetPeer  string            // ? bytes - "" or nil for broadcast, otherwise the destination peer's hash.
	Crc32       uint32            // 4 bytes - data integrity hash (of the payload itself.)
	PartNo      uint16            // 2 bytes - in case of multipart parcels, indicates which part this corresponds to, otherwise should be 0
	PartsTotal  uint16            // 2 bytes - in case of multipart parcels, indicates the total number of parts that the receiver should expect
	NodeID      uint64
	PeerAddress string // address of the peer set by connection to know who sent message (for tracking source of other peers)
	PeerPort    string // port of the peer , or we are listening on
	AppHash     string // Application specific message hash, for tracing
	AppType     string // Application specific message type, for tracing
}

func (*ParcelHeader) Init

func (p *ParcelHeader) Init(network NetworkID) *ParcelHeader

type PartialMessage

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

type PartsAssembler

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

PartsAssembler is responsible for assembling message parts into full messages

func (*PartsAssembler) Init

func (assembler *PartsAssembler) Init() *PartsAssembler

Initializes the assembler

type Peer

type Peer struct {
	QualityScore int32     // 0 is neutral quality, negative is a bad peer.
	Address      string    // Must be in form of x.x.x.x
	Port         string    // Must be in form of xxxx
	NodeID       uint64    // a nonce to distinguish multiple nodes behind one IP address
	Hash         string    // This is more of a connection ID than hash right now.
	Location     uint32    // IP address as an int.
	Network      NetworkID // The network this peer reference lives on.
	Type         uint8
	Connections  int                  // Number of successful connections.
	LastContact  time.Time            // Keep track of how long ago we talked to the peer.
	Source       map[string]time.Time // source where we heard from the peer.
	// contains filtered or unexported fields
}

func (*Peer) AddressPort

func (p *Peer) AddressPort() string

func (*Peer) Init

func (p *Peer) Init(address string, port string, quality int32, peerType uint8, connections int) *Peer

func (*Peer) IsSamePeerAs

func (p *Peer) IsSamePeerAs(netAddress net.Addr) bool

func (*Peer) IsSpecial

func (p *Peer) IsSpecial() bool

func (*Peer) LastSource

func (p *Peer) LastSource() (result string)

gets the last source where this peer was seen

func (*Peer) LocationFromAddress

func (p *Peer) LocationFromAddress() (location uint32)

TODO Hadn't considered IPV6 address support. TODO Need to audit all the net code to check IPv6 addresses Here's an IPv6 conversion: Ref: http://stackoverflow.com/questions/23297141/golang-net-ip-to-ipv6-from-mysql-as-decimal39-0-conversion

func ipv6ToInt(IPv6Addr net.IP) *big.Int {
    IPv6Int := big.NewInt(0)
    IPv6Int.SetBytes(IPv6Addr)
    return IPv6Int
}

Problem is we're working with string addresses, may never have made a connection. TODO - we might have a DNS address, not iP address and need to resolve it! locationFromAddress converts the peers address into a uint32 "location" numeric

func (*Peer) PeerFixedIdent

func (p *Peer) PeerFixedIdent() string

func (*Peer) PeerIdent

func (p *Peer) PeerIdent() string

func (*Peer) PeerLogFields

func (p *Peer) PeerLogFields() log.Fields

func (*Peer) PeerTypeString

func (p *Peer) PeerTypeString() string

type PeerDistanceSort

type PeerDistanceSort []Peer

sort.Sort interface implementation

func (PeerDistanceSort) Len

func (p PeerDistanceSort) Len() int

func (PeerDistanceSort) Less

func (p PeerDistanceSort) Less(i, j int) bool

func (PeerDistanceSort) Swap

func (p PeerDistanceSort) Swap(i, j int)

type PeerQualitySort

type PeerQualitySort []Peer

sort.Sort interface implementation

func (PeerQualitySort) Len

func (p PeerQualitySort) Len() int

func (PeerQualitySort) Less

func (p PeerQualitySort) Less(i, j int) bool

func (PeerQualitySort) Swap

func (p PeerQualitySort) Swap(i, j int)

Jump to

Keyboard shortcuts

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