57
vendor/github.com/libp2p/go-libp2p/core/canonicallog/canonicallog.go
generated
vendored
Normal file
57
vendor/github.com/libp2p/go-libp2p/core/canonicallog/canonicallog.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package canonicallog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
var log = logging.WithSkip(logging.Logger("canonical-log"), 1)
|
||||
|
||||
// LogMisbehavingPeer is the canonical way to log a misbehaving peer.
|
||||
// Protocols should use this to identify a misbehaving peer to allow the end
|
||||
// user to easily identify these nodes across protocols and libp2p.
|
||||
func LogMisbehavingPeer(p peer.ID, peerAddr multiaddr.Multiaddr, component string, err error, msg string) {
|
||||
log.Warnf("CANONICAL_MISBEHAVING_PEER: peer=%s addr=%s component=%s err=%q msg=%q", p, peerAddr.String(), component, err, msg)
|
||||
}
|
||||
|
||||
// LogMisbehavingPeerNetAddr is the canonical way to log a misbehaving peer.
|
||||
// Protocols should use this to identify a misbehaving peer to allow the end
|
||||
// user to easily identify these nodes across protocols and libp2p.
|
||||
func LogMisbehavingPeerNetAddr(p peer.ID, peerAddr net.Addr, component string, originalErr error, msg string) {
|
||||
ma, err := manet.FromNetAddr(peerAddr)
|
||||
if err != nil {
|
||||
log.Warnf("CANONICAL_MISBEHAVING_PEER: peer=%s net_addr=%s component=%s err=%q msg=%q", p, peerAddr.String(), component, originalErr, msg)
|
||||
return
|
||||
}
|
||||
|
||||
LogMisbehavingPeer(p, ma, component, originalErr, msg)
|
||||
}
|
||||
|
||||
// LogPeerStatus logs any useful information about a peer. It takes in a sample
|
||||
// rate and will only log one in every sampleRate messages (randomly). This is
|
||||
// useful in surfacing events that are normal in isolation, but may be abnormal
|
||||
// in large quantities. For example, a successful connection from an IP address
|
||||
// is normal. 10,000 connections from that same IP address is not normal. libp2p
|
||||
// itself does nothing besides emitting this log. Hook this up to another tool
|
||||
// like fail2ban to action on the log.
|
||||
func LogPeerStatus(sampleRate int, p peer.ID, peerAddr multiaddr.Multiaddr, keyVals ...string) {
|
||||
if rand.Intn(sampleRate) == 0 {
|
||||
keyValsStr := strings.Builder{}
|
||||
for i, kOrV := range keyVals {
|
||||
if i%2 == 0 {
|
||||
fmt.Fprintf(&keyValsStr, " %v=", kOrV)
|
||||
} else {
|
||||
fmt.Fprintf(&keyValsStr, "%q", kOrV)
|
||||
}
|
||||
}
|
||||
log.Infof("CANONICAL_PEER_STATUS: peer=%s addr=%s sample_rate=%v%s", p, peerAddr.String(), sampleRate, keyValsStr.String())
|
||||
}
|
||||
}
|
||||
109
vendor/github.com/libp2p/go-libp2p/core/connmgr/decay.go
generated
vendored
Normal file
109
vendor/github.com/libp2p/go-libp2p/core/connmgr/decay.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
package connmgr
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// Decayer is implemented by connection managers supporting decaying tags. A
|
||||
// decaying tag is one whose value automatically decays over time.
|
||||
//
|
||||
// The actual application of the decay behaviour is encapsulated in a
|
||||
// user-provided decaying function (DecayFn). The function is called on every
|
||||
// tick (determined by the interval parameter), and returns either the new value
|
||||
// of the tag, or whether it should be erased altogether.
|
||||
//
|
||||
// We do not set values on a decaying tag. Rather, we "bump" decaying tags by a
|
||||
// delta. This calls the BumpFn with the old value and the delta, to determine
|
||||
// the new value.
|
||||
//
|
||||
// Such a pluggable design affords a great deal of flexibility and versatility.
|
||||
// Behaviours that are straightforward to implement include:
|
||||
//
|
||||
// - Decay a tag by -1, or by half its current value, on every tick.
|
||||
// - Every time a value is bumped, sum it to its current value.
|
||||
// - Exponentially boost a score with every bump.
|
||||
// - Sum the incoming score, but keep it within min, max bounds.
|
||||
//
|
||||
// Commonly used DecayFns and BumpFns are provided in this package.
|
||||
type Decayer interface {
|
||||
io.Closer
|
||||
|
||||
// RegisterDecayingTag creates and registers a new decaying tag, if and only
|
||||
// if a tag with the supplied name doesn't exist yet. Otherwise, an error is
|
||||
// returned.
|
||||
//
|
||||
// The caller provides the interval at which the tag is refreshed, as well
|
||||
// as the decay function and the bump function. Refer to godocs on DecayFn
|
||||
// and BumpFn for more info.
|
||||
RegisterDecayingTag(name string, interval time.Duration, decayFn DecayFn, bumpFn BumpFn) (DecayingTag, error)
|
||||
}
|
||||
|
||||
// DecayFn applies a decay to the peer's score. The implementation must call
|
||||
// DecayFn at the interval supplied when registering the tag.
|
||||
//
|
||||
// It receives a copy of the decaying value, and returns the score after
|
||||
// applying the decay, as well as a flag to signal if the tag should be erased.
|
||||
type DecayFn func(value DecayingValue) (after int, rm bool)
|
||||
|
||||
// BumpFn applies a delta onto an existing score, and returns the new score.
|
||||
//
|
||||
// Non-trivial bump functions include exponential boosting, moving averages,
|
||||
// ceilings, etc.
|
||||
type BumpFn func(value DecayingValue, delta int) (after int)
|
||||
|
||||
// DecayingTag represents a decaying tag. The tag is a long-lived general
|
||||
// object, used to operate on tag values for peers.
|
||||
type DecayingTag interface {
|
||||
// Name returns the name of the tag.
|
||||
Name() string
|
||||
|
||||
// Interval is the effective interval at which this tag will tick. Upon
|
||||
// registration, the desired interval may be overwritten depending on the
|
||||
// decayer's resolution, and this method allows you to obtain the effective
|
||||
// interval.
|
||||
Interval() time.Duration
|
||||
|
||||
// Bump applies a delta to a tag value, calling its bump function. The bump
|
||||
// will be applied asynchronously, and a non-nil error indicates a fault
|
||||
// when queuing.
|
||||
Bump(peer peer.ID, delta int) error
|
||||
|
||||
// Remove removes a decaying tag from a peer. The removal will be applied
|
||||
// asynchronously, and a non-nil error indicates a fault when queuing.
|
||||
Remove(peer peer.ID) error
|
||||
|
||||
// Close closes a decaying tag. The Decayer will stop tracking this tag,
|
||||
// and the state of all peers in the Connection Manager holding this tag
|
||||
// will be updated.
|
||||
//
|
||||
// The deletion is performed asynchronously.
|
||||
//
|
||||
// Once deleted, a tag should not be used, and further calls to Bump/Remove
|
||||
// will error.
|
||||
//
|
||||
// Duplicate calls to Remove will not return errors, but a failure to queue
|
||||
// the first actual removal, will (e.g. when the system is backlogged).
|
||||
Close() error
|
||||
}
|
||||
|
||||
// DecayingValue represents a value for a decaying tag.
|
||||
type DecayingValue struct {
|
||||
// Tag points to the tag this value belongs to.
|
||||
Tag DecayingTag
|
||||
|
||||
// Peer is the peer ID to whom this value is associated.
|
||||
Peer peer.ID
|
||||
|
||||
// Added is the timestamp when this value was added for the first time for
|
||||
// a tag and a peer.
|
||||
Added time.Time
|
||||
|
||||
// LastVisit is the timestamp of the last visit.
|
||||
LastVisit time.Time
|
||||
|
||||
// Value is the current value of the tag.
|
||||
Value int
|
||||
}
|
||||
89
vendor/github.com/libp2p/go-libp2p/core/connmgr/gater.go
generated
vendored
Normal file
89
vendor/github.com/libp2p/go-libp2p/core/connmgr/gater.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package connmgr
|
||||
|
||||
import (
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/control"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// ConnectionGater can be implemented by a type that supports active
|
||||
// inbound or outbound connection gating.
|
||||
//
|
||||
// ConnectionGaters are active, whereas ConnManagers tend to be passive.
|
||||
//
|
||||
// A ConnectionGater will be consulted during different states in the lifecycle
|
||||
// of a connection being established/upgraded. Specific functions will be called
|
||||
// throughout the process, to allow you to intercept the connection at that stage.
|
||||
//
|
||||
// InterceptPeerDial is called on an imminent outbound peer dial request, prior
|
||||
// to the addresses of that peer being available/resolved. Blocking connections
|
||||
// at this stage is typical for blacklisting scenarios.
|
||||
//
|
||||
// InterceptAddrDial is called on an imminent outbound dial to a peer on a
|
||||
// particular address. Blocking connections at this stage is typical for
|
||||
// address filtering.
|
||||
//
|
||||
// InterceptAccept is called as soon as a transport listener receives an
|
||||
// inbound connection request, before any upgrade takes place. Transports who
|
||||
// accept already secure and/or multiplexed connections (e.g. possibly QUIC)
|
||||
// MUST call this method regardless, for correctness/consistency.
|
||||
//
|
||||
// InterceptSecured is called for both inbound and outbound connections,
|
||||
// after a security handshake has taken place and we've authenticated the peer.
|
||||
//
|
||||
// InterceptUpgraded is called for inbound and outbound connections, after
|
||||
// libp2p has finished upgrading the connection entirely to a secure,
|
||||
// multiplexed channel.
|
||||
//
|
||||
// This interface can be used to implement *strict/active* connection management
|
||||
// policies, such as hard limiting of connections once a maximum count has been
|
||||
// reached, maintaining a peer blacklist, or limiting connections by transport
|
||||
// quotas.
|
||||
//
|
||||
// EXPERIMENTAL: a DISCONNECT protocol/message will be supported in the future.
|
||||
// This allows gaters and other components to communicate the intention behind
|
||||
// a connection closure, to curtail potential reconnection attempts.
|
||||
//
|
||||
// For now, InterceptUpgraded can return a non-zero DisconnectReason when
|
||||
// blocking a connection, but this interface is likely to change in the future
|
||||
// as we solidify this feature. The reason why only this method can handle
|
||||
// DisconnectReasons is that we require stream multiplexing capability to open a
|
||||
// control protocol stream to transmit the message.
|
||||
type ConnectionGater interface {
|
||||
// InterceptPeerDial tests whether we're permitted to Dial the specified peer.
|
||||
//
|
||||
// This is called by the network.Network implementation when dialling a peer.
|
||||
InterceptPeerDial(p peer.ID) (allow bool)
|
||||
|
||||
// InterceptAddrDial tests whether we're permitted to dial the specified
|
||||
// multiaddr for the given peer.
|
||||
//
|
||||
// This is called by the network.Network implementation after it has
|
||||
// resolved the peer's addrs, and prior to dialling each.
|
||||
InterceptAddrDial(peer.ID, ma.Multiaddr) (allow bool)
|
||||
|
||||
// InterceptAccept tests whether an incipient inbound connection is allowed.
|
||||
//
|
||||
// This is called by the upgrader, or by the transport directly (e.g. QUIC,
|
||||
// Bluetooth), straight after it has accepted a connection from its socket.
|
||||
InterceptAccept(network.ConnMultiaddrs) (allow bool)
|
||||
|
||||
// InterceptSecured tests whether a given connection, now authenticated,
|
||||
// is allowed.
|
||||
//
|
||||
// This is called by the upgrader, after it has performed the security
|
||||
// handshake, and before it negotiates the muxer, or by the directly by the
|
||||
// transport, at the exact same checkpoint.
|
||||
InterceptSecured(network.Direction, peer.ID, network.ConnMultiaddrs) (allow bool)
|
||||
|
||||
// InterceptUpgraded tests whether a fully capable connection is allowed.
|
||||
//
|
||||
// At this point, the connection a multiplexer has been selected.
|
||||
// When rejecting a connection, the gater can return a DisconnectReason.
|
||||
// Refer to the godoc on the ConnectionGater type for more information.
|
||||
//
|
||||
// NOTE: the go-libp2p implementation currently IGNORES the disconnect reason.
|
||||
InterceptUpgraded(network.Conn) (allow bool, reason control.DisconnectReason)
|
||||
}
|
||||
91
vendor/github.com/libp2p/go-libp2p/core/connmgr/manager.go
generated
vendored
Normal file
91
vendor/github.com/libp2p/go-libp2p/core/connmgr/manager.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Package connmgr provides connection tracking and management interfaces for libp2p.
|
||||
//
|
||||
// The ConnManager interface exported from this package allows libp2p to enforce an
|
||||
// upper bound on the total number of open connections. To avoid service disruptions,
|
||||
// connections can be tagged with metadata and optionally "protected" to ensure that
|
||||
// essential connections are not arbitrarily cut.
|
||||
package connmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// SupportsDecay evaluates if the provided ConnManager supports decay, and if
|
||||
// so, it returns the Decayer object. Refer to godocs on Decayer for more info.
|
||||
func SupportsDecay(mgr ConnManager) (Decayer, bool) {
|
||||
d, ok := mgr.(Decayer)
|
||||
return d, ok
|
||||
}
|
||||
|
||||
// ConnManager tracks connections to peers, and allows consumers to associate
|
||||
// metadata with each peer.
|
||||
//
|
||||
// It enables connections to be trimmed based on implementation-defined
|
||||
// heuristics. The ConnManager allows libp2p to enforce an upper bound on the
|
||||
// total number of open connections.
|
||||
//
|
||||
// ConnManagers supporting decaying tags implement Decayer. Use the
|
||||
// SupportsDecay function to safely cast an instance to Decayer, if supported.
|
||||
type ConnManager interface {
|
||||
// TagPeer tags a peer with a string, associating a weight with the tag.
|
||||
TagPeer(peer.ID, string, int)
|
||||
|
||||
// Untag removes the tagged value from the peer.
|
||||
UntagPeer(p peer.ID, tag string)
|
||||
|
||||
// UpsertTag updates an existing tag or inserts a new one.
|
||||
//
|
||||
// The connection manager calls the upsert function supplying the current
|
||||
// value of the tag (or zero if inexistent). The return value is used as
|
||||
// the new value of the tag.
|
||||
UpsertTag(p peer.ID, tag string, upsert func(int) int)
|
||||
|
||||
// GetTagInfo returns the metadata associated with the peer,
|
||||
// or nil if no metadata has been recorded for the peer.
|
||||
GetTagInfo(p peer.ID) *TagInfo
|
||||
|
||||
// TrimOpenConns terminates open connections based on an implementation-defined
|
||||
// heuristic.
|
||||
TrimOpenConns(ctx context.Context)
|
||||
|
||||
// Notifee returns an implementation that can be called back to inform of
|
||||
// opened and closed connections.
|
||||
Notifee() network.Notifiee
|
||||
|
||||
// Protect protects a peer from having its connection(s) pruned.
|
||||
//
|
||||
// Tagging allows different parts of the system to manage protections without interfering with one another.
|
||||
//
|
||||
// Calls to Protect() with the same tag are idempotent. They are not refcounted, so after multiple calls
|
||||
// to Protect() with the same tag, a single Unprotect() call bearing the same tag will revoke the protection.
|
||||
Protect(id peer.ID, tag string)
|
||||
|
||||
// Unprotect removes a protection that may have been placed on a peer, under the specified tag.
|
||||
//
|
||||
// The return value indicates whether the peer continues to be protected after this call, by way of a different tag.
|
||||
// See notes on Protect() for more info.
|
||||
Unprotect(id peer.ID, tag string) (protected bool)
|
||||
|
||||
// IsProtected returns true if the peer is protected for some tag; if the tag is the empty string
|
||||
// then it will return true if the peer is protected for any tag
|
||||
IsProtected(id peer.ID, tag string) (protected bool)
|
||||
|
||||
// Close closes the connection manager and stops background processes.
|
||||
Close() error
|
||||
}
|
||||
|
||||
// TagInfo stores metadata associated with a peer.
|
||||
type TagInfo struct {
|
||||
FirstSeen time.Time
|
||||
Value int
|
||||
|
||||
// Tags maps tag ids to the numerical values.
|
||||
Tags map[string]int
|
||||
|
||||
// Conns maps connection ids (such as remote multiaddr) to their creation time.
|
||||
Conns map[string]time.Time
|
||||
}
|
||||
24
vendor/github.com/libp2p/go-libp2p/core/connmgr/null.go
generated
vendored
Normal file
24
vendor/github.com/libp2p/go-libp2p/core/connmgr/null.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
package connmgr
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// NullConnMgr is a ConnMgr that provides no functionality.
|
||||
type NullConnMgr struct{}
|
||||
|
||||
var _ ConnManager = (*NullConnMgr)(nil)
|
||||
|
||||
func (NullConnMgr) TagPeer(peer.ID, string, int) {}
|
||||
func (NullConnMgr) UntagPeer(peer.ID, string) {}
|
||||
func (NullConnMgr) UpsertTag(peer.ID, string, func(int) int) {}
|
||||
func (NullConnMgr) GetTagInfo(peer.ID) *TagInfo { return &TagInfo{} }
|
||||
func (NullConnMgr) TrimOpenConns(ctx context.Context) {}
|
||||
func (NullConnMgr) Notifee() network.Notifiee { return network.GlobalNoopNotifiee }
|
||||
func (NullConnMgr) Protect(peer.ID, string) {}
|
||||
func (NullConnMgr) Unprotect(peer.ID, string) bool { return false }
|
||||
func (NullConnMgr) IsProtected(peer.ID, string) bool { return false }
|
||||
func (NullConnMgr) Close() error { return nil }
|
||||
67
vendor/github.com/libp2p/go-libp2p/core/connmgr/presets.go
generated
vendored
Normal file
67
vendor/github.com/libp2p/go-libp2p/core/connmgr/presets.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package connmgr
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DecayNone applies no decay.
|
||||
func DecayNone() DecayFn {
|
||||
return func(value DecayingValue) (_ int, rm bool) {
|
||||
return value.Value, false
|
||||
}
|
||||
}
|
||||
|
||||
// DecayFixed subtracts from by the provided minuend, and deletes the tag when
|
||||
// first reaching 0 or negative.
|
||||
func DecayFixed(minuend int) DecayFn {
|
||||
return func(value DecayingValue) (_ int, rm bool) {
|
||||
v := value.Value - minuend
|
||||
return v, v <= 0
|
||||
}
|
||||
}
|
||||
|
||||
// DecayLinear applies a fractional coefficient to the value of the current tag,
|
||||
// rounding down via math.Floor. It erases the tag when the result is zero.
|
||||
func DecayLinear(coef float64) DecayFn {
|
||||
return func(value DecayingValue) (after int, rm bool) {
|
||||
v := math.Floor(float64(value.Value) * coef)
|
||||
return int(v), v <= 0
|
||||
}
|
||||
}
|
||||
|
||||
// DecayExpireWhenInactive expires a tag after a certain period of no bumps.
|
||||
func DecayExpireWhenInactive(after time.Duration) DecayFn {
|
||||
return func(value DecayingValue) (_ int, rm bool) {
|
||||
rm = time.Until(value.LastVisit) >= after
|
||||
return 0, rm
|
||||
}
|
||||
}
|
||||
|
||||
// BumpSumUnbounded adds the incoming value to the peer's score.
|
||||
func BumpSumUnbounded() BumpFn {
|
||||
return func(value DecayingValue, delta int) (after int) {
|
||||
return value.Value + delta
|
||||
}
|
||||
}
|
||||
|
||||
// BumpSumBounded keeps summing the incoming score, keeping it within a
|
||||
// [min, max] range.
|
||||
func BumpSumBounded(min, max int) BumpFn {
|
||||
return func(value DecayingValue, delta int) (after int) {
|
||||
v := value.Value + delta
|
||||
if v >= max {
|
||||
return max
|
||||
} else if v <= min {
|
||||
return min
|
||||
}
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// BumpOverwrite replaces the current value of the tag with the incoming one.
|
||||
func BumpOverwrite() BumpFn {
|
||||
return func(value DecayingValue, delta int) (after int) {
|
||||
return delta
|
||||
}
|
||||
}
|
||||
9
vendor/github.com/libp2p/go-libp2p/core/control/disconnect.go
generated
vendored
Normal file
9
vendor/github.com/libp2p/go-libp2p/core/control/disconnect.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package control
|
||||
|
||||
// DisconnectReason communicates the reason why a connection is being closed.
|
||||
//
|
||||
// A zero value stands for "no reason" / NA.
|
||||
//
|
||||
// This is an EXPERIMENTAL type. It will change in the future. Refer to the
|
||||
// connmgr.ConnectionGater godoc for more info.
|
||||
type DisconnectReason int
|
||||
187
vendor/github.com/libp2p/go-libp2p/core/crypto/ecdsa.go
generated
vendored
Normal file
187
vendor/github.com/libp2p/go-libp2p/core/crypto/ecdsa.go
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// ECDSAPrivateKey is an implementation of an ECDSA private key
|
||||
type ECDSAPrivateKey struct {
|
||||
priv *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// ECDSAPublicKey is an implementation of an ECDSA public key
|
||||
type ECDSAPublicKey struct {
|
||||
pub *ecdsa.PublicKey
|
||||
}
|
||||
|
||||
// ECDSASig holds the r and s values of an ECDSA signature
|
||||
type ECDSASig struct {
|
||||
R, S *big.Int
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrNotECDSAPubKey is returned when the public key passed is not an ecdsa public key
|
||||
ErrNotECDSAPubKey = errors.New("not an ecdsa public key")
|
||||
// ErrNilSig is returned when the signature is nil
|
||||
ErrNilSig = errors.New("sig is nil")
|
||||
// ErrNilPrivateKey is returned when a nil private key is provided
|
||||
ErrNilPrivateKey = errors.New("private key is nil")
|
||||
// ErrNilPublicKey is returned when a nil public key is provided
|
||||
ErrNilPublicKey = errors.New("public key is nil")
|
||||
// ECDSACurve is the default ecdsa curve used
|
||||
ECDSACurve = elliptic.P256()
|
||||
)
|
||||
|
||||
// GenerateECDSAKeyPair generates a new ecdsa private and public key
|
||||
func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) {
|
||||
return GenerateECDSAKeyPairWithCurve(ECDSACurve, src)
|
||||
}
|
||||
|
||||
// GenerateECDSAKeyPairWithCurve generates a new ecdsa private and public key with a specified curve
|
||||
func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) {
|
||||
priv, err := ecdsa.GenerateKey(curve, src)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil
|
||||
}
|
||||
|
||||
// ECDSAKeyPairFromKey generates a new ecdsa private and public key from an input private key
|
||||
func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) {
|
||||
if priv == nil {
|
||||
return nil, nil, ErrNilPrivateKey
|
||||
}
|
||||
|
||||
return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil
|
||||
}
|
||||
|
||||
// ECDSAPublicKeyFromPubKey generates a new ecdsa public key from an input public key
|
||||
func ECDSAPublicKeyFromPubKey(pub ecdsa.PublicKey) (PubKey, error) {
|
||||
return &ECDSAPublicKey{pub: &pub}, nil
|
||||
}
|
||||
|
||||
// MarshalECDSAPrivateKey returns x509 bytes from a private key
|
||||
func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key marshal") }()
|
||||
return x509.MarshalECPrivateKey(ePriv.priv)
|
||||
}
|
||||
|
||||
// MarshalECDSAPublicKey returns x509 bytes from a public key
|
||||
func MarshalECDSAPublicKey(ePub ECDSAPublicKey) (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ECDSA public-key marshal") }()
|
||||
return x509.MarshalPKIXPublicKey(ePub.pub)
|
||||
}
|
||||
|
||||
// UnmarshalECDSAPrivateKey returns a private key from x509 bytes
|
||||
func UnmarshalECDSAPrivateKey(data []byte) (res PrivKey, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key unmarshal") }()
|
||||
|
||||
priv, err := x509.ParseECPrivateKey(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ECDSAPrivateKey{priv}, nil
|
||||
}
|
||||
|
||||
// UnmarshalECDSAPublicKey returns the public key from x509 bytes
|
||||
func UnmarshalECDSAPublicKey(data []byte) (key PubKey, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ECDSA public-key unmarshal") }()
|
||||
|
||||
pubIfc, err := x509.ParsePKIXPublicKey(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pub, ok := pubIfc.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, ErrNotECDSAPubKey
|
||||
}
|
||||
|
||||
return &ECDSAPublicKey{pub}, nil
|
||||
}
|
||||
|
||||
// Type returns the key type
|
||||
func (ePriv *ECDSAPrivateKey) Type() pb.KeyType {
|
||||
return pb.KeyType_ECDSA
|
||||
}
|
||||
|
||||
// Raw returns x509 bytes from a private key
|
||||
func (ePriv *ECDSAPrivateKey) Raw() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ECDSA private-key marshal") }()
|
||||
return x509.MarshalECPrivateKey(ePriv.priv)
|
||||
}
|
||||
|
||||
// Equals compares two private keys
|
||||
func (ePriv *ECDSAPrivateKey) Equals(o Key) bool {
|
||||
return basicEquals(ePriv, o)
|
||||
}
|
||||
|
||||
// Sign returns the signature of the input data
|
||||
func (ePriv *ECDSAPrivateKey) Sign(data []byte) (sig []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ECDSA signing") }()
|
||||
hash := sha256.Sum256(data)
|
||||
r, s, err := ecdsa.Sign(rand.Reader, ePriv.priv, hash[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return asn1.Marshal(ECDSASig{
|
||||
R: r,
|
||||
S: s,
|
||||
})
|
||||
}
|
||||
|
||||
// GetPublic returns a public key
|
||||
func (ePriv *ECDSAPrivateKey) GetPublic() PubKey {
|
||||
return &ECDSAPublicKey{&ePriv.priv.PublicKey}
|
||||
}
|
||||
|
||||
// Type returns the key type
|
||||
func (ePub *ECDSAPublicKey) Type() pb.KeyType {
|
||||
return pb.KeyType_ECDSA
|
||||
}
|
||||
|
||||
// Raw returns x509 bytes from a public key
|
||||
func (ePub *ECDSAPublicKey) Raw() ([]byte, error) {
|
||||
return x509.MarshalPKIXPublicKey(ePub.pub)
|
||||
}
|
||||
|
||||
// Equals compares to public keys
|
||||
func (ePub *ECDSAPublicKey) Equals(o Key) bool {
|
||||
return basicEquals(ePub, o)
|
||||
}
|
||||
|
||||
// Verify compares data to a signature
|
||||
func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (success bool, err error) {
|
||||
defer func() {
|
||||
catch.HandlePanic(recover(), &err, "ECDSA signature verification")
|
||||
|
||||
// Just to be extra paranoid.
|
||||
if err != nil {
|
||||
success = false
|
||||
}
|
||||
}()
|
||||
|
||||
sig := new(ECDSASig)
|
||||
if _, err := asn1.Unmarshal(sigBytes, sig); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
hash := sha256.Sum256(data)
|
||||
|
||||
return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil
|
||||
}
|
||||
156
vendor/github.com/libp2p/go-libp2p/core/crypto/ed25519.go
generated
vendored
Normal file
156
vendor/github.com/libp2p/go-libp2p/core/crypto/ed25519.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
)
|
||||
|
||||
// Ed25519PrivateKey is an ed25519 private key.
|
||||
type Ed25519PrivateKey struct {
|
||||
k ed25519.PrivateKey
|
||||
}
|
||||
|
||||
// Ed25519PublicKey is an ed25519 public key.
|
||||
type Ed25519PublicKey struct {
|
||||
k ed25519.PublicKey
|
||||
}
|
||||
|
||||
// GenerateEd25519Key generates a new ed25519 private and public key pair.
|
||||
func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) {
|
||||
pub, priv, err := ed25519.GenerateKey(src)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &Ed25519PrivateKey{
|
||||
k: priv,
|
||||
},
|
||||
&Ed25519PublicKey{
|
||||
k: pub,
|
||||
},
|
||||
nil
|
||||
}
|
||||
|
||||
// Type of the private key (Ed25519).
|
||||
func (k *Ed25519PrivateKey) Type() pb.KeyType {
|
||||
return pb.KeyType_Ed25519
|
||||
}
|
||||
|
||||
// Raw private key bytes.
|
||||
func (k *Ed25519PrivateKey) Raw() ([]byte, error) {
|
||||
// The Ed25519 private key contains two 32-bytes curve points, the private
|
||||
// key and the public key.
|
||||
// It makes it more efficient to get the public key without re-computing an
|
||||
// elliptic curve multiplication.
|
||||
buf := make([]byte, len(k.k))
|
||||
copy(buf, k.k)
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (k *Ed25519PrivateKey) pubKeyBytes() []byte {
|
||||
return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:]
|
||||
}
|
||||
|
||||
// Equals compares two ed25519 private keys.
|
||||
func (k *Ed25519PrivateKey) Equals(o Key) bool {
|
||||
edk, ok := o.(*Ed25519PrivateKey)
|
||||
if !ok {
|
||||
return basicEquals(k, o)
|
||||
}
|
||||
|
||||
return subtle.ConstantTimeCompare(k.k, edk.k) == 1
|
||||
}
|
||||
|
||||
// GetPublic returns an ed25519 public key from a private key.
|
||||
func (k *Ed25519PrivateKey) GetPublic() PubKey {
|
||||
return &Ed25519PublicKey{k: k.pubKeyBytes()}
|
||||
}
|
||||
|
||||
// Sign returns a signature from an input message.
|
||||
func (k *Ed25519PrivateKey) Sign(msg []byte) (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "ed15519 signing") }()
|
||||
|
||||
return ed25519.Sign(k.k, msg), nil
|
||||
}
|
||||
|
||||
// Type of the public key (Ed25519).
|
||||
func (k *Ed25519PublicKey) Type() pb.KeyType {
|
||||
return pb.KeyType_Ed25519
|
||||
}
|
||||
|
||||
// Raw public key bytes.
|
||||
func (k *Ed25519PublicKey) Raw() ([]byte, error) {
|
||||
return k.k, nil
|
||||
}
|
||||
|
||||
// Equals compares two ed25519 public keys.
|
||||
func (k *Ed25519PublicKey) Equals(o Key) bool {
|
||||
edk, ok := o.(*Ed25519PublicKey)
|
||||
if !ok {
|
||||
return basicEquals(k, o)
|
||||
}
|
||||
|
||||
return bytes.Equal(k.k, edk.k)
|
||||
}
|
||||
|
||||
// Verify checks a signature against the input data.
|
||||
func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (success bool, err error) {
|
||||
defer func() {
|
||||
catch.HandlePanic(recover(), &err, "ed15519 signature verification")
|
||||
|
||||
// To be safe.
|
||||
if err != nil {
|
||||
success = false
|
||||
}
|
||||
}()
|
||||
return ed25519.Verify(k.k, data, sig), nil
|
||||
}
|
||||
|
||||
// UnmarshalEd25519PublicKey returns a public key from input bytes.
|
||||
func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) {
|
||||
if len(data) != 32 {
|
||||
return nil, errors.New("expect ed25519 public key data size to be 32")
|
||||
}
|
||||
|
||||
return &Ed25519PublicKey{
|
||||
k: ed25519.PublicKey(data),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UnmarshalEd25519PrivateKey returns a private key from input bytes.
|
||||
func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) {
|
||||
switch len(data) {
|
||||
case ed25519.PrivateKeySize + ed25519.PublicKeySize:
|
||||
// Remove the redundant public key. See issue #36.
|
||||
redundantPk := data[ed25519.PrivateKeySize:]
|
||||
pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize]
|
||||
if subtle.ConstantTimeCompare(pk, redundantPk) == 0 {
|
||||
return nil, errors.New("expected redundant ed25519 public key to be redundant")
|
||||
}
|
||||
|
||||
// No point in storing the extra data.
|
||||
newKey := make([]byte, ed25519.PrivateKeySize)
|
||||
copy(newKey, data[:ed25519.PrivateKeySize])
|
||||
data = newKey
|
||||
case ed25519.PrivateKeySize:
|
||||
default:
|
||||
return nil, fmt.Errorf(
|
||||
"expected ed25519 data size to be %d or %d, got %d",
|
||||
ed25519.PrivateKeySize,
|
||||
ed25519.PrivateKeySize+ed25519.PublicKeySize,
|
||||
len(data),
|
||||
)
|
||||
}
|
||||
|
||||
return &Ed25519PrivateKey{
|
||||
k: ed25519.PrivateKey(data),
|
||||
}, nil
|
||||
}
|
||||
291
vendor/github.com/libp2p/go-libp2p/core/crypto/key.go
generated
vendored
Normal file
291
vendor/github.com/libp2p/go-libp2p/core/crypto/key.go
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
// Package crypto implements various cryptographic utilities used by libp2p.
|
||||
// This includes a Public and Private key interface and key implementations
|
||||
// for supported key algorithms.
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
//go:generate protoc --go_out=. --go_opt=Mpb/crypto.proto=./pb pb/crypto.proto
|
||||
|
||||
const (
|
||||
// RSA is an enum for the supported RSA key type
|
||||
RSA = iota
|
||||
// Ed25519 is an enum for the supported Ed25519 key type
|
||||
Ed25519
|
||||
// Secp256k1 is an enum for the supported Secp256k1 key type
|
||||
Secp256k1
|
||||
// ECDSA is an enum for the supported ECDSA key type
|
||||
ECDSA
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrBadKeyType is returned when a key is not supported
|
||||
ErrBadKeyType = errors.New("invalid or unsupported key type")
|
||||
// KeyTypes is a list of supported keys
|
||||
KeyTypes = []int{
|
||||
RSA,
|
||||
Ed25519,
|
||||
Secp256k1,
|
||||
ECDSA,
|
||||
}
|
||||
)
|
||||
|
||||
// PubKeyUnmarshaller is a func that creates a PubKey from a given slice of bytes
|
||||
type PubKeyUnmarshaller func(data []byte) (PubKey, error)
|
||||
|
||||
// PrivKeyUnmarshaller is a func that creates a PrivKey from a given slice of bytes
|
||||
type PrivKeyUnmarshaller func(data []byte) (PrivKey, error)
|
||||
|
||||
// PubKeyUnmarshallers is a map of unmarshallers by key type
|
||||
var PubKeyUnmarshallers = map[pb.KeyType]PubKeyUnmarshaller{
|
||||
pb.KeyType_RSA: UnmarshalRsaPublicKey,
|
||||
pb.KeyType_Ed25519: UnmarshalEd25519PublicKey,
|
||||
pb.KeyType_Secp256k1: UnmarshalSecp256k1PublicKey,
|
||||
pb.KeyType_ECDSA: UnmarshalECDSAPublicKey,
|
||||
}
|
||||
|
||||
// PrivKeyUnmarshallers is a map of unmarshallers by key type
|
||||
var PrivKeyUnmarshallers = map[pb.KeyType]PrivKeyUnmarshaller{
|
||||
pb.KeyType_RSA: UnmarshalRsaPrivateKey,
|
||||
pb.KeyType_Ed25519: UnmarshalEd25519PrivateKey,
|
||||
pb.KeyType_Secp256k1: UnmarshalSecp256k1PrivateKey,
|
||||
pb.KeyType_ECDSA: UnmarshalECDSAPrivateKey,
|
||||
}
|
||||
|
||||
// Key represents a crypto key that can be compared to another key
|
||||
type Key interface {
|
||||
// Equals checks whether two PubKeys are the same
|
||||
Equals(Key) bool
|
||||
|
||||
// Raw returns the raw bytes of the key (not wrapped in the
|
||||
// libp2p-crypto protobuf).
|
||||
//
|
||||
// This function is the inverse of {Priv,Pub}KeyUnmarshaler.
|
||||
Raw() ([]byte, error)
|
||||
|
||||
// Type returns the protobuf key type.
|
||||
Type() pb.KeyType
|
||||
}
|
||||
|
||||
// PrivKey represents a private key that can be used to generate a public key and sign data
|
||||
type PrivKey interface {
|
||||
Key
|
||||
|
||||
// Cryptographically sign the given bytes
|
||||
Sign([]byte) ([]byte, error)
|
||||
|
||||
// Return a public key paired with this private key
|
||||
GetPublic() PubKey
|
||||
}
|
||||
|
||||
// PubKey is a public key that can be used to verify data signed with the corresponding private key
|
||||
type PubKey interface {
|
||||
Key
|
||||
|
||||
// Verify that 'sig' is the signed hash of 'data'
|
||||
Verify(data []byte, sig []byte) (bool, error)
|
||||
}
|
||||
|
||||
// GenSharedKey generates the shared key from a given private key
|
||||
type GenSharedKey func([]byte) ([]byte, error)
|
||||
|
||||
// GenerateKeyPair generates a private and public key
|
||||
func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) {
|
||||
return GenerateKeyPairWithReader(typ, bits, rand.Reader)
|
||||
}
|
||||
|
||||
// GenerateKeyPairWithReader returns a keypair of the given type and bit-size
|
||||
func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) {
|
||||
switch typ {
|
||||
case RSA:
|
||||
return GenerateRSAKeyPair(bits, src)
|
||||
case Ed25519:
|
||||
return GenerateEd25519Key(src)
|
||||
case Secp256k1:
|
||||
return GenerateSecp256k1Key(src)
|
||||
case ECDSA:
|
||||
return GenerateECDSAKeyPair(src)
|
||||
default:
|
||||
return nil, nil, ErrBadKeyType
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateEKeyPair returns an ephemeral public key and returns a function that will compute
|
||||
// the shared secret key. Used in the identify module.
|
||||
//
|
||||
// Focuses only on ECDH now, but can be made more general in the future.
|
||||
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
|
||||
var curve elliptic.Curve
|
||||
|
||||
switch curveName {
|
||||
case "P-256":
|
||||
curve = elliptic.P256()
|
||||
case "P-384":
|
||||
curve = elliptic.P384()
|
||||
case "P-521":
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown curve name")
|
||||
}
|
||||
|
||||
priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pubKey := elliptic.Marshal(curve, x, y)
|
||||
|
||||
done := func(theirPub []byte) ([]byte, error) {
|
||||
// Verify and unpack node's public key.
|
||||
x, y := elliptic.Unmarshal(curve, theirPub)
|
||||
if x == nil {
|
||||
return nil, fmt.Errorf("malformed public key: %d %v", len(theirPub), theirPub)
|
||||
}
|
||||
|
||||
if !curve.IsOnCurve(x, y) {
|
||||
return nil, errors.New("invalid public key")
|
||||
}
|
||||
|
||||
// Generate shared secret.
|
||||
secret, _ := curve.ScalarMult(x, y, priv)
|
||||
|
||||
return secret.Bytes(), nil
|
||||
}
|
||||
|
||||
return pubKey, done, nil
|
||||
}
|
||||
|
||||
// UnmarshalPublicKey converts a protobuf serialized public key into its
|
||||
// representative object
|
||||
func UnmarshalPublicKey(data []byte) (PubKey, error) {
|
||||
pmes := new(pb.PublicKey)
|
||||
err := proto.Unmarshal(data, pmes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return PublicKeyFromProto(pmes)
|
||||
}
|
||||
|
||||
// PublicKeyFromProto converts an unserialized protobuf PublicKey message
|
||||
// into its representative object.
|
||||
func PublicKeyFromProto(pmes *pb.PublicKey) (PubKey, error) {
|
||||
um, ok := PubKeyUnmarshallers[pmes.GetType()]
|
||||
if !ok {
|
||||
return nil, ErrBadKeyType
|
||||
}
|
||||
|
||||
data := pmes.GetData()
|
||||
|
||||
pk, err := um(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch tpk := pk.(type) {
|
||||
case *RsaPublicKey:
|
||||
tpk.cached, _ = proto.Marshal(pmes)
|
||||
}
|
||||
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
// MarshalPublicKey converts a public key object into a protobuf serialized
|
||||
// public key
|
||||
func MarshalPublicKey(k PubKey) ([]byte, error) {
|
||||
pbmes, err := PublicKeyToProto(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return proto.Marshal(pbmes)
|
||||
}
|
||||
|
||||
// PublicKeyToProto converts a public key object into an unserialized
|
||||
// protobuf PublicKey message.
|
||||
func PublicKeyToProto(k PubKey) (*pb.PublicKey, error) {
|
||||
data, err := k.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.PublicKey{
|
||||
Type: k.Type().Enum(),
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UnmarshalPrivateKey converts a protobuf serialized private key into its
|
||||
// representative object
|
||||
func UnmarshalPrivateKey(data []byte) (PrivKey, error) {
|
||||
pmes := new(pb.PrivateKey)
|
||||
err := proto.Unmarshal(data, pmes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
um, ok := PrivKeyUnmarshallers[pmes.GetType()]
|
||||
if !ok {
|
||||
return nil, ErrBadKeyType
|
||||
}
|
||||
|
||||
return um(pmes.GetData())
|
||||
}
|
||||
|
||||
// MarshalPrivateKey converts a key object into its protobuf serialized form.
|
||||
func MarshalPrivateKey(k PrivKey) ([]byte, error) {
|
||||
data, err := k.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Marshal(&pb.PrivateKey{
|
||||
Type: k.Type().Enum(),
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// ConfigDecodeKey decodes from b64 (for config file) to a byte array that can be unmarshalled.
|
||||
func ConfigDecodeKey(b string) ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(b)
|
||||
}
|
||||
|
||||
// ConfigEncodeKey encodes a marshalled key to b64 (for config file).
|
||||
func ConfigEncodeKey(b []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(b)
|
||||
}
|
||||
|
||||
// KeyEqual checks whether two Keys are equivalent (have identical byte representations).
|
||||
func KeyEqual(k1, k2 Key) bool {
|
||||
if k1 == k2 {
|
||||
return true
|
||||
}
|
||||
|
||||
return k1.Equals(k2)
|
||||
}
|
||||
|
||||
func basicEquals(k1, k2 Key) bool {
|
||||
if k1.Type() != k2.Type() {
|
||||
return false
|
||||
}
|
||||
|
||||
a, err := k1.Raw()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
b, err := k2.Raw()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return subtle.ConstantTimeCompare(a, b) == 1
|
||||
}
|
||||
78
vendor/github.com/libp2p/go-libp2p/core/crypto/key_to_stdlib.go
generated
vendored
Normal file
78
vendor/github.com/libp2p/go-libp2p/core/crypto/key_to_stdlib.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
)
|
||||
|
||||
// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p/core/crypto keys
|
||||
func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {
|
||||
if priv == nil {
|
||||
return nil, nil, ErrNilPrivateKey
|
||||
}
|
||||
|
||||
switch p := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &RsaPrivateKey{*p}, &RsaPublicKey{k: p.PublicKey}, nil
|
||||
|
||||
case *ecdsa.PrivateKey:
|
||||
return &ECDSAPrivateKey{p}, &ECDSAPublicKey{&p.PublicKey}, nil
|
||||
|
||||
case *ed25519.PrivateKey:
|
||||
pubIfc := p.Public()
|
||||
pub, _ := pubIfc.(ed25519.PublicKey)
|
||||
return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil
|
||||
|
||||
case *secp256k1.PrivateKey:
|
||||
sPriv := Secp256k1PrivateKey(*p)
|
||||
sPub := Secp256k1PublicKey(*p.PubKey())
|
||||
return &sPriv, &sPub, nil
|
||||
|
||||
default:
|
||||
return nil, nil, ErrBadKeyType
|
||||
}
|
||||
}
|
||||
|
||||
// PrivKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) private keys
|
||||
func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) {
|
||||
if priv == nil {
|
||||
return nil, ErrNilPrivateKey
|
||||
}
|
||||
|
||||
switch p := priv.(type) {
|
||||
case *RsaPrivateKey:
|
||||
return &p.sk, nil
|
||||
case *ECDSAPrivateKey:
|
||||
return p.priv, nil
|
||||
case *Ed25519PrivateKey:
|
||||
return &p.k, nil
|
||||
case *Secp256k1PrivateKey:
|
||||
return p, nil
|
||||
default:
|
||||
return nil, ErrBadKeyType
|
||||
}
|
||||
}
|
||||
|
||||
// PubKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) public keys
|
||||
func PubKeyToStdKey(pub PubKey) (crypto.PublicKey, error) {
|
||||
if pub == nil {
|
||||
return nil, ErrNilPublicKey
|
||||
}
|
||||
|
||||
switch p := pub.(type) {
|
||||
case *RsaPublicKey:
|
||||
return &p.k, nil
|
||||
case *ECDSAPublicKey:
|
||||
return p.pub, nil
|
||||
case *Ed25519PublicKey:
|
||||
return p.k, nil
|
||||
case *Secp256k1PublicKey:
|
||||
return p, nil
|
||||
default:
|
||||
return nil, ErrBadKeyType
|
||||
}
|
||||
}
|
||||
297
vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.pb.go
generated
vendored
Normal file
297
vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.pb.go
generated
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: pb/crypto.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type KeyType int32
|
||||
|
||||
const (
|
||||
KeyType_RSA KeyType = 0
|
||||
KeyType_Ed25519 KeyType = 1
|
||||
KeyType_Secp256k1 KeyType = 2
|
||||
KeyType_ECDSA KeyType = 3
|
||||
)
|
||||
|
||||
// Enum value maps for KeyType.
|
||||
var (
|
||||
KeyType_name = map[int32]string{
|
||||
0: "RSA",
|
||||
1: "Ed25519",
|
||||
2: "Secp256k1",
|
||||
3: "ECDSA",
|
||||
}
|
||||
KeyType_value = map[string]int32{
|
||||
"RSA": 0,
|
||||
"Ed25519": 1,
|
||||
"Secp256k1": 2,
|
||||
"ECDSA": 3,
|
||||
}
|
||||
)
|
||||
|
||||
func (x KeyType) Enum() *KeyType {
|
||||
p := new(KeyType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x KeyType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (KeyType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_pb_crypto_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (KeyType) Type() protoreflect.EnumType {
|
||||
return &file_pb_crypto_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x KeyType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (x *KeyType) UnmarshalJSON(b []byte) error {
|
||||
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = KeyType(num)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprecated: Use KeyType.Descriptor instead.
|
||||
func (KeyType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_pb_crypto_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type PublicKey struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Type *KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PublicKey) Reset() {
|
||||
*x = PublicKey{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_crypto_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PublicKey) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PublicKey) ProtoMessage() {}
|
||||
|
||||
func (x *PublicKey) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_crypto_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead.
|
||||
func (*PublicKey) Descriptor() ([]byte, []int) {
|
||||
return file_pb_crypto_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PublicKey) GetType() KeyType {
|
||||
if x != nil && x.Type != nil {
|
||||
return *x.Type
|
||||
}
|
||||
return KeyType_RSA
|
||||
}
|
||||
|
||||
func (x *PublicKey) GetData() []byte {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PrivateKey struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Type *KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PrivateKey) Reset() {
|
||||
*x = PrivateKey{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_crypto_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PrivateKey) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PrivateKey) ProtoMessage() {}
|
||||
|
||||
func (x *PrivateKey) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_crypto_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PrivateKey.ProtoReflect.Descriptor instead.
|
||||
func (*PrivateKey) Descriptor() ([]byte, []int) {
|
||||
return file_pb_crypto_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *PrivateKey) GetType() KeyType {
|
||||
if x != nil && x.Type != nil {
|
||||
return *x.Type
|
||||
}
|
||||
return KeyType_RSA
|
||||
}
|
||||
|
||||
func (x *PrivateKey) GetData() []byte {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pb_crypto_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pb_crypto_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x70, 0x62, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x09, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x22, 0x47, 0x0a, 0x09,
|
||||
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70,
|
||||
0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52,
|
||||
0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x48, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28,
|
||||
0x0e, 0x32, 0x12, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65,
|
||||
0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44,
|
||||
0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x2a,
|
||||
0x39, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x53,
|
||||
0x41, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x10, 0x01,
|
||||
0x12, 0x0d, 0x0a, 0x09, 0x53, 0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31, 0x10, 0x02, 0x12,
|
||||
0x09, 0x0a, 0x05, 0x45, 0x43, 0x44, 0x53, 0x41, 0x10, 0x03, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f,
|
||||
0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63,
|
||||
0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x62,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pb_crypto_proto_rawDescOnce sync.Once
|
||||
file_pb_crypto_proto_rawDescData = file_pb_crypto_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pb_crypto_proto_rawDescGZIP() []byte {
|
||||
file_pb_crypto_proto_rawDescOnce.Do(func() {
|
||||
file_pb_crypto_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_crypto_proto_rawDescData)
|
||||
})
|
||||
return file_pb_crypto_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pb_crypto_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_pb_crypto_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_pb_crypto_proto_goTypes = []interface{}{
|
||||
(KeyType)(0), // 0: crypto.pb.KeyType
|
||||
(*PublicKey)(nil), // 1: crypto.pb.PublicKey
|
||||
(*PrivateKey)(nil), // 2: crypto.pb.PrivateKey
|
||||
}
|
||||
var file_pb_crypto_proto_depIdxs = []int32{
|
||||
0, // 0: crypto.pb.PublicKey.Type:type_name -> crypto.pb.KeyType
|
||||
0, // 1: crypto.pb.PrivateKey.Type:type_name -> crypto.pb.KeyType
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pb_crypto_proto_init() }
|
||||
func file_pb_crypto_proto_init() {
|
||||
if File_pb_crypto_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pb_crypto_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PublicKey); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pb_crypto_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PrivateKey); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_pb_crypto_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pb_crypto_proto_goTypes,
|
||||
DependencyIndexes: file_pb_crypto_proto_depIdxs,
|
||||
EnumInfos: file_pb_crypto_proto_enumTypes,
|
||||
MessageInfos: file_pb_crypto_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pb_crypto_proto = out.File
|
||||
file_pb_crypto_proto_rawDesc = nil
|
||||
file_pb_crypto_proto_goTypes = nil
|
||||
file_pb_crypto_proto_depIdxs = nil
|
||||
}
|
||||
22
vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto
generated
vendored
Normal file
22
vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package crypto.pb;
|
||||
|
||||
option go_package = "github.com/libp2p/go-libp2p/core/crypto/pb";
|
||||
|
||||
enum KeyType {
|
||||
RSA = 0;
|
||||
Ed25519 = 1;
|
||||
Secp256k1 = 2;
|
||||
ECDSA = 3;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
||||
|
||||
message PrivateKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
||||
28
vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_common.go
generated
vendored
Normal file
28
vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_common.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// WeakRsaKeyEnv is an environment variable which, when set, lowers the
|
||||
// minimum required bits of RSA keys to 512. This should be used exclusively in
|
||||
// test situations.
|
||||
const WeakRsaKeyEnv = "LIBP2P_ALLOW_WEAK_RSA_KEYS"
|
||||
|
||||
var MinRsaKeyBits = 2048
|
||||
|
||||
var maxRsaKeyBits = 8192
|
||||
|
||||
// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key
|
||||
// that's smaller than MinRsaKeyBits bits. In test
|
||||
var ErrRsaKeyTooSmall error
|
||||
var ErrRsaKeyTooBig error = fmt.Errorf("rsa keys must be <= %d bits", maxRsaKeyBits)
|
||||
|
||||
func init() {
|
||||
if _, ok := os.LookupEnv(WeakRsaKeyEnv); ok {
|
||||
MinRsaKeyBits = 512
|
||||
}
|
||||
|
||||
ErrRsaKeyTooSmall = fmt.Errorf("rsa keys must be >= %d bits to be useful", MinRsaKeyBits)
|
||||
}
|
||||
155
vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_go.go
generated
vendored
Normal file
155
vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_go.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// RsaPrivateKey is a rsa private key
|
||||
type RsaPrivateKey struct {
|
||||
sk rsa.PrivateKey
|
||||
}
|
||||
|
||||
// RsaPublicKey is a rsa public key
|
||||
type RsaPublicKey struct {
|
||||
k rsa.PublicKey
|
||||
|
||||
cached []byte
|
||||
}
|
||||
|
||||
// GenerateRSAKeyPair generates a new rsa private and public key
|
||||
func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) {
|
||||
if bits < MinRsaKeyBits {
|
||||
return nil, nil, ErrRsaKeyTooSmall
|
||||
}
|
||||
if bits > maxRsaKeyBits {
|
||||
return nil, nil, ErrRsaKeyTooBig
|
||||
}
|
||||
priv, err := rsa.GenerateKey(src, bits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pk := priv.PublicKey
|
||||
return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{k: pk}, nil
|
||||
}
|
||||
|
||||
// Verify compares a signature against input data
|
||||
func (pk *RsaPublicKey) Verify(data, sig []byte) (success bool, err error) {
|
||||
defer func() {
|
||||
catch.HandlePanic(recover(), &err, "RSA signature verification")
|
||||
|
||||
// To be safe
|
||||
if err != nil {
|
||||
success = false
|
||||
}
|
||||
}()
|
||||
hashed := sha256.Sum256(data)
|
||||
err = rsa.VerifyPKCS1v15(&pk.k, crypto.SHA256, hashed[:], sig)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (pk *RsaPublicKey) Type() pb.KeyType {
|
||||
return pb.KeyType_RSA
|
||||
}
|
||||
|
||||
func (pk *RsaPublicKey) Raw() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "RSA public-key marshaling") }()
|
||||
return x509.MarshalPKIXPublicKey(&pk.k)
|
||||
}
|
||||
|
||||
// Equals checks whether this key is equal to another
|
||||
func (pk *RsaPublicKey) Equals(k Key) bool {
|
||||
// make sure this is a rsa public key
|
||||
other, ok := (k).(*RsaPublicKey)
|
||||
if !ok {
|
||||
return basicEquals(pk, k)
|
||||
}
|
||||
|
||||
return pk.k.N.Cmp(other.k.N) == 0 && pk.k.E == other.k.E
|
||||
}
|
||||
|
||||
// Sign returns a signature of the input data
|
||||
func (sk *RsaPrivateKey) Sign(message []byte) (sig []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "RSA signing") }()
|
||||
hashed := sha256.Sum256(message)
|
||||
return rsa.SignPKCS1v15(rand.Reader, &sk.sk, crypto.SHA256, hashed[:])
|
||||
}
|
||||
|
||||
// GetPublic returns a public key
|
||||
func (sk *RsaPrivateKey) GetPublic() PubKey {
|
||||
return &RsaPublicKey{k: sk.sk.PublicKey}
|
||||
}
|
||||
|
||||
func (sk *RsaPrivateKey) Type() pb.KeyType {
|
||||
return pb.KeyType_RSA
|
||||
}
|
||||
|
||||
func (sk *RsaPrivateKey) Raw() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "RSA private-key marshaling") }()
|
||||
b := x509.MarshalPKCS1PrivateKey(&sk.sk)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Equals checks whether this key is equal to another
|
||||
func (sk *RsaPrivateKey) Equals(k Key) bool {
|
||||
// make sure this is a rsa public key
|
||||
other, ok := (k).(*RsaPrivateKey)
|
||||
if !ok {
|
||||
return basicEquals(sk, k)
|
||||
}
|
||||
|
||||
a := sk.sk
|
||||
b := other.sk
|
||||
|
||||
// Don't care about constant time. We're only comparing the public half.
|
||||
return a.PublicKey.N.Cmp(b.PublicKey.N) == 0 && a.PublicKey.E == b.PublicKey.E
|
||||
}
|
||||
|
||||
// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
|
||||
func UnmarshalRsaPrivateKey(b []byte) (key PrivKey, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "RSA private-key unmarshaling") }()
|
||||
sk, err := x509.ParsePKCS1PrivateKey(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sk.N.BitLen() < MinRsaKeyBits {
|
||||
return nil, ErrRsaKeyTooSmall
|
||||
}
|
||||
if sk.N.BitLen() > maxRsaKeyBits {
|
||||
return nil, ErrRsaKeyTooBig
|
||||
}
|
||||
return &RsaPrivateKey{sk: *sk}, nil
|
||||
}
|
||||
|
||||
// UnmarshalRsaPublicKey returns a public key from the input x509 bytes
|
||||
func UnmarshalRsaPublicKey(b []byte) (key PubKey, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "RSA public-key unmarshaling") }()
|
||||
pub, err := x509.ParsePKIXPublicKey(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pk, ok := pub.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, errors.New("not actually an rsa public key")
|
||||
}
|
||||
if pk.N.BitLen() < MinRsaKeyBits {
|
||||
return nil, ErrRsaKeyTooSmall
|
||||
}
|
||||
if pk.N.BitLen() > maxRsaKeyBits {
|
||||
return nil, ErrRsaKeyTooBig
|
||||
}
|
||||
|
||||
return &RsaPublicKey{k: *pk}, nil
|
||||
}
|
||||
127
vendor/github.com/libp2p/go-libp2p/core/crypto/secp256k1.go
generated
vendored
Normal file
127
vendor/github.com/libp2p/go-libp2p/core/crypto/secp256k1.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// Secp256k1PrivateKey is a Secp256k1 private key
|
||||
type Secp256k1PrivateKey secp256k1.PrivateKey
|
||||
|
||||
// Secp256k1PublicKey is a Secp256k1 public key
|
||||
type Secp256k1PublicKey secp256k1.PublicKey
|
||||
|
||||
// GenerateSecp256k1Key generates a new Secp256k1 private and public key pair
|
||||
func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) {
|
||||
privk, err := secp256k1.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := (*Secp256k1PrivateKey)(privk)
|
||||
return k, k.GetPublic(), nil
|
||||
}
|
||||
|
||||
// UnmarshalSecp256k1PrivateKey returns a private key from bytes
|
||||
func UnmarshalSecp256k1PrivateKey(data []byte) (k PrivKey, err error) {
|
||||
if len(data) != secp256k1.PrivKeyBytesLen {
|
||||
return nil, fmt.Errorf("expected secp256k1 data size to be %d", secp256k1.PrivKeyBytesLen)
|
||||
}
|
||||
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 private-key unmarshal") }()
|
||||
|
||||
privk := secp256k1.PrivKeyFromBytes(data)
|
||||
return (*Secp256k1PrivateKey)(privk), nil
|
||||
}
|
||||
|
||||
// UnmarshalSecp256k1PublicKey returns a public key from bytes
|
||||
func UnmarshalSecp256k1PublicKey(data []byte) (_k PubKey, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public-key unmarshal") }()
|
||||
k, err := secp256k1.ParsePubKey(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return (*Secp256k1PublicKey)(k), nil
|
||||
}
|
||||
|
||||
// Type returns the private key type
|
||||
func (k *Secp256k1PrivateKey) Type() pb.KeyType {
|
||||
return pb.KeyType_Secp256k1
|
||||
}
|
||||
|
||||
// Raw returns the bytes of the key
|
||||
func (k *Secp256k1PrivateKey) Raw() ([]byte, error) {
|
||||
return (*secp256k1.PrivateKey)(k).Serialize(), nil
|
||||
}
|
||||
|
||||
// Equals compares two private keys
|
||||
func (k *Secp256k1PrivateKey) Equals(o Key) bool {
|
||||
sk, ok := o.(*Secp256k1PrivateKey)
|
||||
if !ok {
|
||||
return basicEquals(k, o)
|
||||
}
|
||||
|
||||
return k.GetPublic().Equals(sk.GetPublic())
|
||||
}
|
||||
|
||||
// Sign returns a signature from input data
|
||||
func (k *Secp256k1PrivateKey) Sign(data []byte) (_sig []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 signing") }()
|
||||
key := (*secp256k1.PrivateKey)(k)
|
||||
hash := sha256.Sum256(data)
|
||||
sig := ecdsa.Sign(key, hash[:])
|
||||
|
||||
return sig.Serialize(), nil
|
||||
}
|
||||
|
||||
// GetPublic returns a public key
|
||||
func (k *Secp256k1PrivateKey) GetPublic() PubKey {
|
||||
return (*Secp256k1PublicKey)((*secp256k1.PrivateKey)(k).PubKey())
|
||||
}
|
||||
|
||||
// Type returns the public key type
|
||||
func (k *Secp256k1PublicKey) Type() pb.KeyType {
|
||||
return pb.KeyType_Secp256k1
|
||||
}
|
||||
|
||||
// Raw returns the bytes of the key
|
||||
func (k *Secp256k1PublicKey) Raw() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public key marshaling") }()
|
||||
return (*secp256k1.PublicKey)(k).SerializeCompressed(), nil
|
||||
}
|
||||
|
||||
// Equals compares two public keys
|
||||
func (k *Secp256k1PublicKey) Equals(o Key) bool {
|
||||
sk, ok := o.(*Secp256k1PublicKey)
|
||||
if !ok {
|
||||
return basicEquals(k, o)
|
||||
}
|
||||
|
||||
return (*secp256k1.PublicKey)(k).IsEqual((*secp256k1.PublicKey)(sk))
|
||||
}
|
||||
|
||||
// Verify compares a signature against the input data
|
||||
func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (success bool, err error) {
|
||||
defer func() {
|
||||
catch.HandlePanic(recover(), &err, "secp256k1 signature verification")
|
||||
|
||||
// To be extra safe.
|
||||
if err != nil {
|
||||
success = false
|
||||
}
|
||||
}()
|
||||
sig, err := ecdsa.ParseDERSignature(sigStr)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
hash := sha256.Sum256(data)
|
||||
return sig.Verify(hash[:], (*secp256k1.PublicKey)(k)), nil
|
||||
}
|
||||
27
vendor/github.com/libp2p/go-libp2p/core/discovery/discovery.go
generated
vendored
Normal file
27
vendor/github.com/libp2p/go-libp2p/core/discovery/discovery.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Package discovery provides service advertisement and peer discovery interfaces for libp2p.
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// Advertiser is an interface for advertising services
|
||||
type Advertiser interface {
|
||||
// Advertise advertises a service
|
||||
Advertise(ctx context.Context, ns string, opts ...Option) (time.Duration, error)
|
||||
}
|
||||
|
||||
// Discoverer is an interface for peer discovery
|
||||
type Discoverer interface {
|
||||
// FindPeers discovers peers providing a service
|
||||
FindPeers(ctx context.Context, ns string, opts ...Option) (<-chan peer.AddrInfo, error)
|
||||
}
|
||||
|
||||
// Discovery is an interface that combines service advertisement and peer discovery
|
||||
type Discovery interface {
|
||||
Advertiser
|
||||
Discoverer
|
||||
}
|
||||
41
vendor/github.com/libp2p/go-libp2p/core/discovery/options.go
generated
vendored
Normal file
41
vendor/github.com/libp2p/go-libp2p/core/discovery/options.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package discovery
|
||||
|
||||
import "time"
|
||||
|
||||
// DiscoveryOpt is a single discovery option.
|
||||
type Option func(opts *Options) error
|
||||
|
||||
// DiscoveryOpts is a set of discovery options.
|
||||
type Options struct {
|
||||
Ttl time.Duration
|
||||
Limit int
|
||||
|
||||
// Other (implementation-specific) options
|
||||
Other map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// Apply applies the given options to this DiscoveryOpts
|
||||
func (opts *Options) Apply(options ...Option) error {
|
||||
for _, o := range options {
|
||||
if err := o(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TTL is an option that provides a hint for the duration of an advertisement
|
||||
func TTL(ttl time.Duration) Option {
|
||||
return func(opts *Options) error {
|
||||
opts.Ttl = ttl
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Limit is an option that provides an upper bound on the peer count for discovery
|
||||
func Limit(limit int) Option {
|
||||
return func(opts *Options) error {
|
||||
opts.Limit = limit
|
||||
return nil
|
||||
}
|
||||
}
|
||||
83
vendor/github.com/libp2p/go-libp2p/core/event/addrs.go
generated
vendored
Normal file
83
vendor/github.com/libp2p/go-libp2p/core/event/addrs.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// AddrAction represents an action taken on one of a Host's listen addresses.
|
||||
// It is used to add context to address change events in EvtLocalAddressesUpdated.
|
||||
type AddrAction int
|
||||
|
||||
const (
|
||||
// Unknown means that the event producer was unable to determine why the address
|
||||
// is in the current state.
|
||||
Unknown AddrAction = iota
|
||||
|
||||
// Added means that the address is new and was not present prior to the event.
|
||||
Added
|
||||
|
||||
// Maintained means that the address was not altered between the current and
|
||||
// previous states.
|
||||
Maintained
|
||||
|
||||
// Removed means that the address was removed from the Host.
|
||||
Removed
|
||||
)
|
||||
|
||||
// UpdatedAddress is used in the EvtLocalAddressesUpdated event to convey
|
||||
// address change information.
|
||||
type UpdatedAddress struct {
|
||||
// Address contains the address that was updated.
|
||||
Address ma.Multiaddr
|
||||
|
||||
// Action indicates what action was taken on the address during the
|
||||
// event. May be Unknown if the event producer cannot produce diffs.
|
||||
Action AddrAction
|
||||
}
|
||||
|
||||
// EvtLocalAddressesUpdated should be emitted when the set of listen addresses for
|
||||
// the local host changes. This may happen for a number of reasons. For example,
|
||||
// we may have opened a new relay connection, established a new NAT mapping via
|
||||
// UPnP, or been informed of our observed address by another peer.
|
||||
//
|
||||
// EvtLocalAddressesUpdated contains a snapshot of the current listen addresses,
|
||||
// and may also contain a diff between the current state and the previous state.
|
||||
// If the event producer is capable of creating a diff, the Diffs field will be
|
||||
// true, and event consumers can inspect the Action field of each UpdatedAddress
|
||||
// to see how each address was modified.
|
||||
//
|
||||
// For example, the Action will tell you whether an address in
|
||||
// the Current list was Added by the event producer, or was Maintained without
|
||||
// changes. Addresses that were removed from the Host will have the AddrAction
|
||||
// of Removed, and will be in the Removed list.
|
||||
//
|
||||
// If the event producer is not capable or producing diffs, the Diffs field will
|
||||
// be false, the Removed list will always be empty, and the Action for each
|
||||
// UpdatedAddress in the Current list will be Unknown.
|
||||
//
|
||||
// In addition to the above, EvtLocalAddressesUpdated also contains the updated peer.PeerRecord
|
||||
// for the Current set of listen addresses, wrapped in a record.Envelope and signed by the Host's private key.
|
||||
// This record can be shared with other peers to inform them of what we believe are our diallable addresses
|
||||
// a secure and authenticated way.
|
||||
type EvtLocalAddressesUpdated struct {
|
||||
|
||||
// Diffs indicates whether this event contains a diff of the Host's previous
|
||||
// address set.
|
||||
Diffs bool
|
||||
|
||||
// Current contains all current listen addresses for the Host.
|
||||
// If Diffs == true, the Action field of each UpdatedAddress will tell
|
||||
// you whether an address was Added, or was Maintained from the previous
|
||||
// state.
|
||||
Current []UpdatedAddress
|
||||
|
||||
// Removed contains addresses that were removed from the Host.
|
||||
// This field is only set when Diffs == true.
|
||||
Removed []UpdatedAddress
|
||||
|
||||
// SignedPeerRecord contains our own updated peer.PeerRecord, listing the addresses enumerated in Current.
|
||||
// wrapped in a record.Envelope and signed by the Host's private key.
|
||||
SignedPeerRecord *record.Envelope
|
||||
}
|
||||
100
vendor/github.com/libp2p/go-libp2p/core/event/bus.go
generated
vendored
Normal file
100
vendor/github.com/libp2p/go-libp2p/core/event/bus.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// SubscriptionOpt represents a subscriber option. Use the options exposed by the implementation of choice.
|
||||
type SubscriptionOpt = func(interface{}) error
|
||||
|
||||
// EmitterOpt represents an emitter option. Use the options exposed by the implementation of choice.
|
||||
type EmitterOpt = func(interface{}) error
|
||||
|
||||
// CancelFunc closes a subscriber.
|
||||
type CancelFunc = func()
|
||||
|
||||
// wildcardSubscriptionType is a virtual type to represent wildcard
|
||||
// subscriptions.
|
||||
type wildcardSubscriptionType interface{}
|
||||
|
||||
// WildcardSubscription is the type to subscribe to receive all events
|
||||
// emitted in the eventbus.
|
||||
var WildcardSubscription = new(wildcardSubscriptionType)
|
||||
|
||||
// Emitter represents an actor that emits events onto the eventbus.
|
||||
type Emitter interface {
|
||||
io.Closer
|
||||
|
||||
// Emit emits an event onto the eventbus. If any channel subscribed to the topic is blocked,
|
||||
// calls to Emit will block.
|
||||
//
|
||||
// Calling this function with wrong event type will cause a panic.
|
||||
Emit(evt interface{}) error
|
||||
}
|
||||
|
||||
// Subscription represents a subscription to one or multiple event types.
|
||||
type Subscription interface {
|
||||
io.Closer
|
||||
|
||||
// Out returns the channel from which to consume events.
|
||||
Out() <-chan interface{}
|
||||
|
||||
// Name returns the name for the subscription
|
||||
Name() string
|
||||
}
|
||||
|
||||
// Bus is an interface for a type-based event delivery system.
|
||||
type Bus interface {
|
||||
// Subscribe creates a new Subscription.
|
||||
//
|
||||
// eventType can be either a pointer to a single event type, or a slice of pointers to
|
||||
// subscribe to multiple event types at once, under a single subscription (and channel).
|
||||
//
|
||||
// Failing to drain the channel may cause publishers to block.
|
||||
//
|
||||
// If you want to subscribe to ALL events emitted in the bus, use
|
||||
// `WildcardSubscription` as the `eventType`:
|
||||
//
|
||||
// eventbus.Subscribe(WildcardSubscription)
|
||||
//
|
||||
// Simple example
|
||||
//
|
||||
// sub, err := eventbus.Subscribe(new(EventType))
|
||||
// defer sub.Close()
|
||||
// for e := range sub.Out() {
|
||||
// event := e.(EventType) // guaranteed safe
|
||||
// [...]
|
||||
// }
|
||||
//
|
||||
// Multi-type example
|
||||
//
|
||||
// sub, err := eventbus.Subscribe([]interface{}{new(EventA), new(EventB)})
|
||||
// defer sub.Close()
|
||||
// for e := range sub.Out() {
|
||||
// select e.(type):
|
||||
// case EventA:
|
||||
// [...]
|
||||
// case EventB:
|
||||
// [...]
|
||||
// }
|
||||
// }
|
||||
Subscribe(eventType interface{}, opts ...SubscriptionOpt) (Subscription, error)
|
||||
|
||||
// Emitter creates a new event emitter.
|
||||
//
|
||||
// eventType accepts typed nil pointers, and uses the type information for wiring purposes.
|
||||
//
|
||||
// Example:
|
||||
// em, err := eventbus.Emitter(new(EventT))
|
||||
// defer em.Close() // MUST call this after being done with the emitter
|
||||
// em.Emit(EventT{})
|
||||
Emitter(eventType interface{}, opts ...EmitterOpt) (Emitter, error)
|
||||
|
||||
// GetAllEventTypes returns all the event types that this bus knows about
|
||||
// (having emitters and subscribers). It omits the WildcardSubscription.
|
||||
//
|
||||
// The caller is guaranteed that this function will only return value types;
|
||||
// no pointer types will be returned.
|
||||
GetAllEventTypes() []reflect.Type
|
||||
}
|
||||
21
vendor/github.com/libp2p/go-libp2p/core/event/dht.go
generated
vendored
Normal file
21
vendor/github.com/libp2p/go-libp2p/core/event/dht.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package event
|
||||
|
||||
// RawJSON is a type that contains a raw JSON string.
|
||||
type RawJSON string
|
||||
|
||||
// GenericDHTEvent is a type that encapsulates an actual DHT event by carrying
|
||||
// its raw JSON.
|
||||
//
|
||||
// Context: the DHT event system is rather bespoke and a bit messy at the time,
|
||||
// so until we unify/clean that up, this event bridges the gap. It should only
|
||||
// be consumed for informational purposes.
|
||||
//
|
||||
// EXPERIMENTAL: this will likely be removed if/when the DHT event types are
|
||||
// hoisted to core, and the DHT event system is reconciled with the eventbus.
|
||||
type GenericDHTEvent struct {
|
||||
// Type is the type of the DHT event that occurred.
|
||||
Type string
|
||||
|
||||
// Raw is the raw JSON representation of the event payload.
|
||||
Raw RawJSON
|
||||
}
|
||||
11
vendor/github.com/libp2p/go-libp2p/core/event/doc.go
generated
vendored
Normal file
11
vendor/github.com/libp2p/go-libp2p/core/event/doc.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Package event contains the abstractions for a local event bus, along with the standard events
|
||||
// that libp2p subsystems may emit.
|
||||
//
|
||||
// Source code is arranged as follows:
|
||||
// - doc.go: this file.
|
||||
// - bus.go: abstractions for the event bus.
|
||||
// - rest: event structs, sensibly categorised in files by entity, and following this naming convention:
|
||||
// Evt[Entity (noun)][Event (verb past tense / gerund)]
|
||||
// The past tense is used to convey that something happened, whereas the gerund form of the verb (-ing)
|
||||
// expresses that a process is in progress. Examples: EvtConnEstablishing, EvtConnEstablished.
|
||||
package event
|
||||
17
vendor/github.com/libp2p/go-libp2p/core/event/identify.go
generated
vendored
Normal file
17
vendor/github.com/libp2p/go-libp2p/core/event/identify.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package event
|
||||
|
||||
import "github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
// EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed.
|
||||
type EvtPeerIdentificationCompleted struct {
|
||||
// Peer is the ID of the peer whose identification succeeded.
|
||||
Peer peer.ID
|
||||
}
|
||||
|
||||
// EvtPeerIdentificationFailed is emitted when the initial identification round for a peer failed.
|
||||
type EvtPeerIdentificationFailed struct {
|
||||
// Peer is the ID of the peer whose identification failed.
|
||||
Peer peer.ID
|
||||
// Reason is the reason why identification failed.
|
||||
Reason error
|
||||
}
|
||||
18
vendor/github.com/libp2p/go-libp2p/core/event/nattype.go
generated
vendored
Normal file
18
vendor/github.com/libp2p/go-libp2p/core/event/nattype.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package event
|
||||
|
||||
import "github.com/libp2p/go-libp2p/core/network"
|
||||
|
||||
// EvtNATDeviceTypeChanged is an event struct to be emitted when the type of the NAT device changes for a Transport Protocol.
|
||||
//
|
||||
// Note: This event is meaningful ONLY if the AutoNAT Reachability is Private.
|
||||
// Consumers of this event should ALSO consume the `EvtLocalReachabilityChanged` event and interpret
|
||||
// this event ONLY if the Reachability on the `EvtLocalReachabilityChanged` is Private.
|
||||
type EvtNATDeviceTypeChanged struct {
|
||||
// TransportProtocol is the Transport Protocol for which the NAT Device Type has been determined.
|
||||
TransportProtocol network.NATTransportProtocol
|
||||
// NatDeviceType indicates the type of the NAT Device for the Transport Protocol.
|
||||
// Currently, it can be either a `Cone NAT` or a `Symmetric NAT`. Please see the detailed documentation
|
||||
// on `network.NATDeviceType` enumerations for a better understanding of what these types mean and
|
||||
// how they impact Connectivity and Hole Punching.
|
||||
NatDeviceType network.NATDeviceType
|
||||
}
|
||||
55
vendor/github.com/libp2p/go-libp2p/core/event/network.go
generated
vendored
Normal file
55
vendor/github.com/libp2p/go-libp2p/core/event/network.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// EvtPeerConnectednessChanged should be emitted every time the "connectedness" to a
|
||||
// given peer changes. Specifically, this event is emitted in the following
|
||||
// cases:
|
||||
//
|
||||
// - Connectedness = Connected: Every time we transition from having no
|
||||
// connections to a peer to having at least one connection to the peer.
|
||||
// - Connectedness = NotConnected: Every time we transition from having at least
|
||||
// one connection to a peer to having no connections to the peer.
|
||||
//
|
||||
// Additional connectedness states may be added in the future. This list should
|
||||
// not be considered exhaustive.
|
||||
//
|
||||
// Take note:
|
||||
//
|
||||
// - It's possible to have _multiple_ connections to a given peer.
|
||||
// - Both libp2p and networks are asynchronous.
|
||||
//
|
||||
// This means that all the following situations are possible:
|
||||
//
|
||||
// A connection is cut and is re-established:
|
||||
//
|
||||
// - Peer A observes a transition from Connected -> NotConnected -> Connected
|
||||
// - Peer B observes a transition from Connected -> NotConnected -> Connected
|
||||
//
|
||||
// Explanation: Both peers observe the connection die. This is the "nice" case.
|
||||
//
|
||||
// A connection is cut and is re-established.
|
||||
//
|
||||
// - Peer A observes a transition from Connected -> NotConnected -> Connected.
|
||||
// - Peer B observes no transition.
|
||||
//
|
||||
// Explanation: Peer A re-establishes the dead connection. Peer B observes the
|
||||
// new connection form before it observes the old connection die.
|
||||
//
|
||||
// A connection is cut:
|
||||
//
|
||||
// - Peer A observes no transition.
|
||||
// - Peer B observes no transition.
|
||||
//
|
||||
// Explanation: There were two connections and one was cut. This connection
|
||||
// might have been in active use but neither peer will observe a change in
|
||||
// "connectedness". Peers should always make sure to retry network requests.
|
||||
type EvtPeerConnectednessChanged struct {
|
||||
// Peer is the remote peer whose connectedness has changed.
|
||||
Peer peer.ID
|
||||
// Connectedness is the new connectedness state.
|
||||
Connectedness network.Connectedness
|
||||
}
|
||||
26
vendor/github.com/libp2p/go-libp2p/core/event/protocol.go
generated
vendored
Normal file
26
vendor/github.com/libp2p/go-libp2p/core/event/protocol.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p/core/protocol"
|
||||
)
|
||||
|
||||
// EvtPeerProtocolsUpdated should be emitted when a peer we're connected to adds or removes protocols from their stack.
|
||||
type EvtPeerProtocolsUpdated struct {
|
||||
// Peer is the peer whose protocols were updated.
|
||||
Peer peer.ID
|
||||
// Added enumerates the protocols that were added by this peer.
|
||||
Added []protocol.ID
|
||||
// Removed enumerates the protocols that were removed by this peer.
|
||||
Removed []protocol.ID
|
||||
}
|
||||
|
||||
// EvtLocalProtocolsUpdated should be emitted when stream handlers are attached or detached from the local host.
|
||||
// For handlers attached with a matcher predicate (host.SetStreamHandlerMatch()), only the protocol ID will be
|
||||
// included in this event.
|
||||
type EvtLocalProtocolsUpdated struct {
|
||||
// Added enumerates the protocols that were added locally.
|
||||
Added []protocol.ID
|
||||
// Removed enumerates the protocols that were removed locally.
|
||||
Removed []protocol.ID
|
||||
}
|
||||
13
vendor/github.com/libp2p/go-libp2p/core/event/reachability.go
generated
vendored
Normal file
13
vendor/github.com/libp2p/go-libp2p/core/event/reachability.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
package event
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
)
|
||||
|
||||
// EvtLocalReachabilityChanged is an event struct to be emitted when the local's
|
||||
// node reachability changes state.
|
||||
//
|
||||
// This event is usually emitted by the AutoNAT subsystem.
|
||||
type EvtLocalReachabilityChanged struct {
|
||||
Reachability network.Reachability
|
||||
}
|
||||
11
vendor/github.com/libp2p/go-libp2p/core/host/helpers.go
generated
vendored
Normal file
11
vendor/github.com/libp2p/go-libp2p/core/host/helpers.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package host
|
||||
|
||||
import "github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
// InfoFromHost returns a peer.AddrInfo struct with the Host's ID and all of its Addrs.
|
||||
func InfoFromHost(h Host) *peer.AddrInfo {
|
||||
return &peer.AddrInfo{
|
||||
ID: h.ID(),
|
||||
Addrs: h.Addrs(),
|
||||
}
|
||||
}
|
||||
75
vendor/github.com/libp2p/go-libp2p/core/host/host.go
generated
vendored
Normal file
75
vendor/github.com/libp2p/go-libp2p/core/host/host.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Package host provides the core Host interface for libp2p.
|
||||
//
|
||||
// Host represents a single libp2p node in a peer-to-peer network.
|
||||
package host
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/connmgr"
|
||||
"github.com/libp2p/go-libp2p/core/event"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/peerstore"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Host is an object participating in a p2p network, which
|
||||
// implements protocols or provides services. It handles
|
||||
// requests like a Server, and issues requests like a Client.
|
||||
// It is called Host because it is both Server and Client (and Peer
|
||||
// may be confusing).
|
||||
type Host interface {
|
||||
// ID returns the (local) peer.ID associated with this Host
|
||||
ID() peer.ID
|
||||
|
||||
// Peerstore returns the Host's repository of Peer Addresses and Keys.
|
||||
Peerstore() peerstore.Peerstore
|
||||
|
||||
// Returns the listen addresses of the Host
|
||||
Addrs() []ma.Multiaddr
|
||||
|
||||
// Networks returns the Network interface of the Host
|
||||
Network() network.Network
|
||||
|
||||
// Mux returns the Mux multiplexing incoming streams to protocol handlers
|
||||
Mux() protocol.Switch
|
||||
|
||||
// Connect ensures there is a connection between this host and the peer with
|
||||
// given peer.ID. Connect will absorb the addresses in pi into its internal
|
||||
// peerstore. If there is not an active connection, Connect will issue a
|
||||
// h.Network.Dial, and block until a connection is open, or an error is
|
||||
// returned. // TODO: Relay + NAT.
|
||||
Connect(ctx context.Context, pi peer.AddrInfo) error
|
||||
|
||||
// SetStreamHandler sets the protocol handler on the Host's Mux.
|
||||
// This is equivalent to:
|
||||
// host.Mux().SetHandler(proto, handler)
|
||||
// (Thread-safe)
|
||||
SetStreamHandler(pid protocol.ID, handler network.StreamHandler)
|
||||
|
||||
// SetStreamHandlerMatch sets the protocol handler on the Host's Mux
|
||||
// using a matching function for protocol selection.
|
||||
SetStreamHandlerMatch(protocol.ID, func(protocol.ID) bool, network.StreamHandler)
|
||||
|
||||
// RemoveStreamHandler removes a handler on the mux that was set by
|
||||
// SetStreamHandler
|
||||
RemoveStreamHandler(pid protocol.ID)
|
||||
|
||||
// NewStream opens a new stream to given peer p, and writes a p2p/protocol
|
||||
// header with given ProtocolID. If there is no connection to p, attempts
|
||||
// to create one. If ProtocolID is "", writes no header.
|
||||
// (Thread-safe)
|
||||
NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (network.Stream, error)
|
||||
|
||||
// Close shuts down the host, its Network, and services.
|
||||
Close() error
|
||||
|
||||
// ConnManager returns this hosts connection manager
|
||||
ConnManager() connmgr.ConnManager
|
||||
|
||||
// EventBus returns the hosts eventbus
|
||||
EventBus() event.Bus
|
||||
}
|
||||
18
vendor/github.com/libp2p/go-libp2p/core/internal/catch/catch.go
generated
vendored
Normal file
18
vendor/github.com/libp2p/go-libp2p/core/internal/catch/catch.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package catch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var panicWriter io.Writer = os.Stderr
|
||||
|
||||
// HandlePanic handles and logs panics.
|
||||
func HandlePanic(rerr interface{}, err *error, where string) {
|
||||
if rerr != nil {
|
||||
fmt.Fprintf(panicWriter, "caught panic: %s\n%s\n", rerr, debug.Stack())
|
||||
*err = fmt.Errorf("panic in %s: %s", where, rerr)
|
||||
}
|
||||
}
|
||||
176
vendor/github.com/libp2p/go-libp2p/core/metrics/bandwidth.go
generated
vendored
Normal file
176
vendor/github.com/libp2p/go-libp2p/core/metrics/bandwidth.go
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// Package metrics provides metrics collection and reporting interfaces for libp2p.
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-flow-metrics"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
)
|
||||
|
||||
// BandwidthCounter tracks incoming and outgoing data transferred by the local peer.
|
||||
// Metrics are available for total bandwidth across all peers / protocols, as well
|
||||
// as segmented by remote peer ID and protocol ID.
|
||||
type BandwidthCounter struct {
|
||||
totalIn flow.Meter
|
||||
totalOut flow.Meter
|
||||
|
||||
protocolIn flow.MeterRegistry
|
||||
protocolOut flow.MeterRegistry
|
||||
|
||||
peerIn flow.MeterRegistry
|
||||
peerOut flow.MeterRegistry
|
||||
}
|
||||
|
||||
// NewBandwidthCounter creates a new BandwidthCounter.
|
||||
func NewBandwidthCounter() *BandwidthCounter {
|
||||
return new(BandwidthCounter)
|
||||
}
|
||||
|
||||
// LogSentMessage records the size of an outgoing message
|
||||
// without associating the bandwidth to a specific peer or protocol.
|
||||
func (bwc *BandwidthCounter) LogSentMessage(size int64) {
|
||||
bwc.totalOut.Mark(uint64(size))
|
||||
}
|
||||
|
||||
// LogRecvMessage records the size of an incoming message
|
||||
// without associating the bandwidth to a specific peer or protocol.
|
||||
func (bwc *BandwidthCounter) LogRecvMessage(size int64) {
|
||||
bwc.totalIn.Mark(uint64(size))
|
||||
}
|
||||
|
||||
// LogSentMessageStream records the size of an outgoing message over a single logical stream.
|
||||
// Bandwidth is associated with the given protocol.ID and peer.ID.
|
||||
func (bwc *BandwidthCounter) LogSentMessageStream(size int64, proto protocol.ID, p peer.ID) {
|
||||
bwc.protocolOut.Get(string(proto)).Mark(uint64(size))
|
||||
bwc.peerOut.Get(string(p)).Mark(uint64(size))
|
||||
}
|
||||
|
||||
// LogRecvMessageStream records the size of an incoming message over a single logical stream.
|
||||
// Bandwidth is associated with the given protocol.ID and peer.ID.
|
||||
func (bwc *BandwidthCounter) LogRecvMessageStream(size int64, proto protocol.ID, p peer.ID) {
|
||||
bwc.protocolIn.Get(string(proto)).Mark(uint64(size))
|
||||
bwc.peerIn.Get(string(p)).Mark(uint64(size))
|
||||
}
|
||||
|
||||
// GetBandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID.
|
||||
// The metrics returned include all traffic sent / received for the peer, regardless of protocol.
|
||||
func (bwc *BandwidthCounter) GetBandwidthForPeer(p peer.ID) (out Stats) {
|
||||
inSnap := bwc.peerIn.Get(string(p)).Snapshot()
|
||||
outSnap := bwc.peerOut.Get(string(p)).Snapshot()
|
||||
|
||||
return Stats{
|
||||
TotalIn: int64(inSnap.Total),
|
||||
TotalOut: int64(outSnap.Total),
|
||||
RateIn: inSnap.Rate,
|
||||
RateOut: outSnap.Rate,
|
||||
}
|
||||
}
|
||||
|
||||
// GetBandwidthForProtocol returns a Stats struct with bandwidth metrics associated with the given protocol.ID.
|
||||
// The metrics returned include all traffic sent / received for the protocol, regardless of which peers were
|
||||
// involved.
|
||||
func (bwc *BandwidthCounter) GetBandwidthForProtocol(proto protocol.ID) (out Stats) {
|
||||
inSnap := bwc.protocolIn.Get(string(proto)).Snapshot()
|
||||
outSnap := bwc.protocolOut.Get(string(proto)).Snapshot()
|
||||
|
||||
return Stats{
|
||||
TotalIn: int64(inSnap.Total),
|
||||
TotalOut: int64(outSnap.Total),
|
||||
RateIn: inSnap.Rate,
|
||||
RateOut: outSnap.Rate,
|
||||
}
|
||||
}
|
||||
|
||||
// GetBandwidthTotals returns a Stats struct with bandwidth metrics for all data sent / received by the
|
||||
// local peer, regardless of protocol or remote peer IDs.
|
||||
func (bwc *BandwidthCounter) GetBandwidthTotals() (out Stats) {
|
||||
inSnap := bwc.totalIn.Snapshot()
|
||||
outSnap := bwc.totalOut.Snapshot()
|
||||
|
||||
return Stats{
|
||||
TotalIn: int64(inSnap.Total),
|
||||
TotalOut: int64(outSnap.Total),
|
||||
RateIn: inSnap.Rate,
|
||||
RateOut: outSnap.Rate,
|
||||
}
|
||||
}
|
||||
|
||||
// GetBandwidthByPeer returns a map of all remembered peers and the bandwidth
|
||||
// metrics with respect to each. This method may be very expensive.
|
||||
func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats {
|
||||
peers := make(map[peer.ID]Stats)
|
||||
|
||||
bwc.peerIn.ForEach(func(p string, meter *flow.Meter) {
|
||||
id := peer.ID(p)
|
||||
snap := meter.Snapshot()
|
||||
|
||||
stat := peers[id]
|
||||
stat.TotalIn = int64(snap.Total)
|
||||
stat.RateIn = snap.Rate
|
||||
peers[id] = stat
|
||||
})
|
||||
|
||||
bwc.peerOut.ForEach(func(p string, meter *flow.Meter) {
|
||||
id := peer.ID(p)
|
||||
snap := meter.Snapshot()
|
||||
|
||||
stat := peers[id]
|
||||
stat.TotalOut = int64(snap.Total)
|
||||
stat.RateOut = snap.Rate
|
||||
peers[id] = stat
|
||||
})
|
||||
|
||||
return peers
|
||||
}
|
||||
|
||||
// GetBandwidthByProtocol returns a map of all remembered protocols and
|
||||
// the bandwidth metrics with respect to each. This method may be moderately
|
||||
// expensive.
|
||||
func (bwc *BandwidthCounter) GetBandwidthByProtocol() map[protocol.ID]Stats {
|
||||
protocols := make(map[protocol.ID]Stats)
|
||||
|
||||
bwc.protocolIn.ForEach(func(p string, meter *flow.Meter) {
|
||||
id := protocol.ID(p)
|
||||
snap := meter.Snapshot()
|
||||
|
||||
stat := protocols[id]
|
||||
stat.TotalIn = int64(snap.Total)
|
||||
stat.RateIn = snap.Rate
|
||||
protocols[id] = stat
|
||||
})
|
||||
|
||||
bwc.protocolOut.ForEach(func(p string, meter *flow.Meter) {
|
||||
id := protocol.ID(p)
|
||||
snap := meter.Snapshot()
|
||||
|
||||
stat := protocols[id]
|
||||
stat.TotalOut = int64(snap.Total)
|
||||
stat.RateOut = snap.Rate
|
||||
protocols[id] = stat
|
||||
})
|
||||
|
||||
return protocols
|
||||
}
|
||||
|
||||
// Reset clears all stats.
|
||||
func (bwc *BandwidthCounter) Reset() {
|
||||
bwc.totalIn.Reset()
|
||||
bwc.totalOut.Reset()
|
||||
|
||||
bwc.protocolIn.Clear()
|
||||
bwc.protocolOut.Clear()
|
||||
|
||||
bwc.peerIn.Clear()
|
||||
bwc.peerOut.Clear()
|
||||
}
|
||||
|
||||
// TrimIdle trims all timers idle since the given time.
|
||||
func (bwc *BandwidthCounter) TrimIdle(since time.Time) {
|
||||
bwc.peerIn.TrimIdle(since)
|
||||
bwc.peerOut.TrimIdle(since)
|
||||
bwc.protocolIn.TrimIdle(since)
|
||||
bwc.protocolOut.TrimIdle(since)
|
||||
}
|
||||
31
vendor/github.com/libp2p/go-libp2p/core/metrics/reporter.go
generated
vendored
Normal file
31
vendor/github.com/libp2p/go-libp2p/core/metrics/reporter.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Package metrics provides metrics collection and reporting interfaces for libp2p.
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
)
|
||||
|
||||
// Stats represents a point-in-time snapshot of bandwidth metrics.
|
||||
//
|
||||
// The TotalIn and TotalOut fields record cumulative bytes sent / received.
|
||||
// The RateIn and RateOut fields record bytes sent / received per second.
|
||||
type Stats struct {
|
||||
TotalIn int64
|
||||
TotalOut int64
|
||||
RateIn float64
|
||||
RateOut float64
|
||||
}
|
||||
|
||||
// Reporter provides methods for logging and retrieving metrics.
|
||||
type Reporter interface {
|
||||
LogSentMessage(int64)
|
||||
LogRecvMessage(int64)
|
||||
LogSentMessageStream(int64, protocol.ID, peer.ID)
|
||||
LogRecvMessageStream(int64, protocol.ID, peer.ID)
|
||||
GetBandwidthForPeer(peer.ID) Stats
|
||||
GetBandwidthForProtocol(protocol.ID) Stats
|
||||
GetBandwidthTotals() Stats
|
||||
GetBandwidthByPeer() map[peer.ID]Stats
|
||||
GetBandwidthByProtocol() map[protocol.ID]Stats
|
||||
}
|
||||
93
vendor/github.com/libp2p/go-libp2p/core/network/conn.go
generated
vendored
Normal file
93
vendor/github.com/libp2p/go-libp2p/core/network/conn.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
ic "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Conn is a connection to a remote peer. It multiplexes streams.
|
||||
// Usually there is no need to use a Conn directly, but it may
|
||||
// be useful to get information about the peer on the other side:
|
||||
//
|
||||
// stream.Conn().RemotePeer()
|
||||
type Conn interface {
|
||||
io.Closer
|
||||
|
||||
ConnSecurity
|
||||
ConnMultiaddrs
|
||||
ConnStat
|
||||
ConnScoper
|
||||
|
||||
// ID returns an identifier that uniquely identifies this Conn within this
|
||||
// host, during this run. Connection IDs may repeat across restarts.
|
||||
ID() string
|
||||
|
||||
// NewStream constructs a new Stream over this conn.
|
||||
NewStream(context.Context) (Stream, error)
|
||||
|
||||
// GetStreams returns all open streams over this conn.
|
||||
GetStreams() []Stream
|
||||
|
||||
// IsClosed returns whether a connection is fully closed, so it can
|
||||
// be garbage collected.
|
||||
IsClosed() bool
|
||||
}
|
||||
|
||||
// ConnectionState holds information about the connection.
|
||||
type ConnectionState struct {
|
||||
// The stream multiplexer used on this connection (if any). For example: /yamux/1.0.0
|
||||
StreamMultiplexer protocol.ID
|
||||
// The security protocol used on this connection (if any). For example: /tls/1.0.0
|
||||
Security protocol.ID
|
||||
// the transport used on this connection. For example: tcp
|
||||
Transport string
|
||||
// indicates whether StreamMultiplexer was selected using inlined muxer negotiation
|
||||
UsedEarlyMuxerNegotiation bool
|
||||
}
|
||||
|
||||
// ConnSecurity is the interface that one can mix into a connection interface to
|
||||
// give it the security methods.
|
||||
type ConnSecurity interface {
|
||||
// LocalPeer returns our peer ID
|
||||
LocalPeer() peer.ID
|
||||
|
||||
// RemotePeer returns the peer ID of the remote peer.
|
||||
RemotePeer() peer.ID
|
||||
|
||||
// RemotePublicKey returns the public key of the remote peer.
|
||||
RemotePublicKey() ic.PubKey
|
||||
|
||||
// ConnState returns information about the connection state.
|
||||
ConnState() ConnectionState
|
||||
}
|
||||
|
||||
// ConnMultiaddrs is an interface mixin for connection types that provide multiaddr
|
||||
// addresses for the endpoints.
|
||||
type ConnMultiaddrs interface {
|
||||
// LocalMultiaddr returns the local Multiaddr associated
|
||||
// with this connection
|
||||
LocalMultiaddr() ma.Multiaddr
|
||||
|
||||
// RemoteMultiaddr returns the remote Multiaddr associated
|
||||
// with this connection
|
||||
RemoteMultiaddr() ma.Multiaddr
|
||||
}
|
||||
|
||||
// ConnStat is an interface mixin for connection types that provide connection statistics.
|
||||
type ConnStat interface {
|
||||
// Stat stores metadata pertaining to this conn.
|
||||
Stat() ConnStats
|
||||
}
|
||||
|
||||
// ConnScoper is the interface that one can mix into a connection interface to give it a resource
|
||||
// management scope
|
||||
type ConnScoper interface {
|
||||
// Scope returns the user view of this connection's resource scope
|
||||
Scope() ConnScope
|
||||
}
|
||||
110
vendor/github.com/libp2p/go-libp2p/core/network/context.go
generated
vendored
Normal file
110
vendor/github.com/libp2p/go-libp2p/core/network/context.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DialPeerTimeout is the default timeout for a single call to `DialPeer`. When
|
||||
// there are multiple concurrent calls to `DialPeer`, this timeout will apply to
|
||||
// each independently.
|
||||
var DialPeerTimeout = 60 * time.Second
|
||||
|
||||
type noDialCtxKey struct{}
|
||||
type dialPeerTimeoutCtxKey struct{}
|
||||
type forceDirectDialCtxKey struct{}
|
||||
type useTransientCtxKey struct{}
|
||||
type simConnectCtxKey struct{ isClient bool }
|
||||
|
||||
var noDial = noDialCtxKey{}
|
||||
var forceDirectDial = forceDirectDialCtxKey{}
|
||||
var useTransient = useTransientCtxKey{}
|
||||
var simConnectIsServer = simConnectCtxKey{}
|
||||
var simConnectIsClient = simConnectCtxKey{isClient: true}
|
||||
|
||||
// EXPERIMENTAL
|
||||
// WithForceDirectDial constructs a new context with an option that instructs the network
|
||||
// to attempt to force a direct connection to a peer via a dial even if a proxied connection to it already exists.
|
||||
func WithForceDirectDial(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, forceDirectDial, reason)
|
||||
}
|
||||
|
||||
// EXPERIMENTAL
|
||||
// GetForceDirectDial returns true if the force direct dial option is set in the context.
|
||||
func GetForceDirectDial(ctx context.Context) (forceDirect bool, reason string) {
|
||||
v := ctx.Value(forceDirectDial)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// WithSimultaneousConnect constructs a new context with an option that instructs the transport
|
||||
// to apply hole punching logic where applicable.
|
||||
// EXPERIMENTAL
|
||||
func WithSimultaneousConnect(ctx context.Context, isClient bool, reason string) context.Context {
|
||||
if isClient {
|
||||
return context.WithValue(ctx, simConnectIsClient, reason)
|
||||
}
|
||||
return context.WithValue(ctx, simConnectIsServer, reason)
|
||||
}
|
||||
|
||||
// GetSimultaneousConnect returns true if the simultaneous connect option is set in the context.
|
||||
// EXPERIMENTAL
|
||||
func GetSimultaneousConnect(ctx context.Context) (simconnect bool, isClient bool, reason string) {
|
||||
if v := ctx.Value(simConnectIsClient); v != nil {
|
||||
return true, true, v.(string)
|
||||
}
|
||||
if v := ctx.Value(simConnectIsServer); v != nil {
|
||||
return true, false, v.(string)
|
||||
}
|
||||
return false, false, ""
|
||||
}
|
||||
|
||||
// WithNoDial constructs a new context with an option that instructs the network
|
||||
// to not attempt a new dial when opening a stream.
|
||||
func WithNoDial(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, noDial, reason)
|
||||
}
|
||||
|
||||
// GetNoDial returns true if the no dial option is set in the context.
|
||||
func GetNoDial(ctx context.Context) (nodial bool, reason string) {
|
||||
v := ctx.Value(noDial)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// GetDialPeerTimeout returns the current DialPeer timeout (or the default).
|
||||
func GetDialPeerTimeout(ctx context.Context) time.Duration {
|
||||
if to, ok := ctx.Value(dialPeerTimeoutCtxKey{}).(time.Duration); ok {
|
||||
return to
|
||||
}
|
||||
return DialPeerTimeout
|
||||
}
|
||||
|
||||
// WithDialPeerTimeout returns a new context with the DialPeer timeout applied.
|
||||
//
|
||||
// This timeout overrides the default DialPeerTimeout and applies per-dial
|
||||
// independently.
|
||||
func WithDialPeerTimeout(ctx context.Context, timeout time.Duration) context.Context {
|
||||
return context.WithValue(ctx, dialPeerTimeoutCtxKey{}, timeout)
|
||||
}
|
||||
|
||||
// WithUseTransient constructs a new context with an option that instructs the network
|
||||
// that it is acceptable to use a transient connection when opening a new stream.
|
||||
func WithUseTransient(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, useTransient, reason)
|
||||
}
|
||||
|
||||
// GetUseTransient returns true if the use transient option is set in the context.
|
||||
func GetUseTransient(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(useTransient)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
33
vendor/github.com/libp2p/go-libp2p/core/network/errors.go
generated
vendored
Normal file
33
vendor/github.com/libp2p/go-libp2p/core/network/errors.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
type temporaryError string
|
||||
|
||||
func (e temporaryError) Error() string { return string(e) }
|
||||
func (e temporaryError) Temporary() bool { return true }
|
||||
func (e temporaryError) Timeout() bool { return false }
|
||||
|
||||
var _ net.Error = temporaryError("")
|
||||
|
||||
// ErrNoRemoteAddrs is returned when there are no addresses associated with a peer during a dial.
|
||||
var ErrNoRemoteAddrs = errors.New("no remote addresses")
|
||||
|
||||
// ErrNoConn is returned when attempting to open a stream to a peer with the NoDial
|
||||
// option and no usable connection is available.
|
||||
var ErrNoConn = errors.New("no usable connection to peer")
|
||||
|
||||
// ErrTransientConn is returned when attempting to open a stream to a peer with only a transient
|
||||
// connection, without specifying the UseTransient option.
|
||||
var ErrTransientConn = errors.New("transient connection to peer")
|
||||
|
||||
// ErrResourceLimitExceeded is returned when attempting to perform an operation that would
|
||||
// exceed system resource limits.
|
||||
var ErrResourceLimitExceeded = temporaryError("resource limit exceeded")
|
||||
|
||||
// ErrResourceScopeClosed is returned when attempting to reserve resources in a closed resource
|
||||
// scope.
|
||||
var ErrResourceScopeClosed = errors.New("resource scope closed")
|
||||
95
vendor/github.com/libp2p/go-libp2p/core/network/mux.go
generated
vendored
Normal file
95
vendor/github.com/libp2p/go-libp2p/core/network/mux.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrReset is returned when reading or writing on a reset stream.
|
||||
var ErrReset = errors.New("stream reset")
|
||||
|
||||
// MuxedStream is a bidirectional io pipe within a connection.
|
||||
type MuxedStream interface {
|
||||
io.Reader
|
||||
io.Writer
|
||||
|
||||
// Close closes the stream.
|
||||
//
|
||||
// * Any buffered data for writing will be flushed.
|
||||
// * Future reads will fail.
|
||||
// * Any in-progress reads/writes will be interrupted.
|
||||
//
|
||||
// Close may be asynchronous and _does not_ guarantee receipt of the
|
||||
// data.
|
||||
//
|
||||
// Close closes the stream for both reading and writing.
|
||||
// Close is equivalent to calling `CloseRead` and `CloseWrite`. Importantly, Close will not wait for any form of acknowledgment.
|
||||
// If acknowledgment is required, the caller must call `CloseWrite`, then wait on the stream for a response (or an EOF),
|
||||
// then call Close() to free the stream object.
|
||||
//
|
||||
// When done with a stream, the user must call either Close() or `Reset()` to discard the stream, even after calling `CloseRead` and/or `CloseWrite`.
|
||||
io.Closer
|
||||
|
||||
// CloseWrite closes the stream for writing but leaves it open for
|
||||
// reading.
|
||||
//
|
||||
// CloseWrite does not free the stream, users must still call Close or
|
||||
// Reset.
|
||||
CloseWrite() error
|
||||
|
||||
// CloseRead closes the stream for reading but leaves it open for
|
||||
// writing.
|
||||
//
|
||||
// When CloseRead is called, all in-progress Read calls are interrupted with a non-EOF error and
|
||||
// no further calls to Read will succeed.
|
||||
//
|
||||
// The handling of new incoming data on the stream after calling this function is implementation defined.
|
||||
//
|
||||
// CloseRead does not free the stream, users must still call Close or
|
||||
// Reset.
|
||||
CloseRead() error
|
||||
|
||||
// Reset closes both ends of the stream. Use this to tell the remote
|
||||
// side to hang up and go away.
|
||||
Reset() error
|
||||
|
||||
SetDeadline(time.Time) error
|
||||
SetReadDeadline(time.Time) error
|
||||
SetWriteDeadline(time.Time) error
|
||||
}
|
||||
|
||||
// MuxedConn represents a connection to a remote peer that has been
|
||||
// extended to support stream multiplexing.
|
||||
//
|
||||
// A MuxedConn allows a single net.Conn connection to carry many logically
|
||||
// independent bidirectional streams of binary data.
|
||||
//
|
||||
// Together with network.ConnSecurity, MuxedConn is a component of the
|
||||
// transport.CapableConn interface, which represents a "raw" network
|
||||
// connection that has been "upgraded" to support the libp2p capabilities
|
||||
// of secure communication and stream multiplexing.
|
||||
type MuxedConn interface {
|
||||
// Close closes the stream muxer and the the underlying net.Conn.
|
||||
io.Closer
|
||||
|
||||
// IsClosed returns whether a connection is fully closed, so it can
|
||||
// be garbage collected.
|
||||
IsClosed() bool
|
||||
|
||||
// OpenStream creates a new stream.
|
||||
OpenStream(context.Context) (MuxedStream, error)
|
||||
|
||||
// AcceptStream accepts a stream opened by the other side.
|
||||
AcceptStream() (MuxedStream, error)
|
||||
}
|
||||
|
||||
// Multiplexer wraps a net.Conn with a stream multiplexing
|
||||
// implementation and returns a MuxedConn that supports opening
|
||||
// multiple streams over the underlying net.Conn
|
||||
type Multiplexer interface {
|
||||
// NewConn constructs a new connection
|
||||
NewConn(c net.Conn, isServer bool, scope PeerScope) (MuxedConn, error)
|
||||
}
|
||||
58
vendor/github.com/libp2p/go-libp2p/core/network/nattype.go
generated
vendored
Normal file
58
vendor/github.com/libp2p/go-libp2p/core/network/nattype.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
package network
|
||||
|
||||
// NATDeviceType indicates the type of the NAT device.
|
||||
type NATDeviceType int
|
||||
|
||||
const (
|
||||
// NATDeviceTypeUnknown indicates that the type of the NAT device is unknown.
|
||||
NATDeviceTypeUnknown NATDeviceType = iota
|
||||
|
||||
// NATDeviceTypeCone indicates that the NAT device is a Cone NAT.
|
||||
// A Cone NAT is a NAT where all outgoing connections from the same source IP address and port are mapped by the NAT device
|
||||
// to the same IP address and port irrespective of the destination address.
|
||||
// With regards to RFC 3489, this could be either a Full Cone NAT, a Restricted Cone NAT or a
|
||||
// Port Restricted Cone NAT. However, we do NOT differentiate between them here and simply classify all such NATs as a Cone NAT.
|
||||
// NAT traversal with hole punching is possible with a Cone NAT ONLY if the remote peer is ALSO behind a Cone NAT.
|
||||
// If the remote peer is behind a Symmetric NAT, hole punching will fail.
|
||||
NATDeviceTypeCone
|
||||
|
||||
// NATDeviceTypeSymmetric indicates that the NAT device is a Symmetric NAT.
|
||||
// A Symmetric NAT maps outgoing connections with different destination addresses to different IP addresses and ports,
|
||||
// even if they originate from the same source IP address and port.
|
||||
// NAT traversal with hole-punching is currently NOT possible in libp2p with Symmetric NATs irrespective of the remote peer's NAT type.
|
||||
NATDeviceTypeSymmetric
|
||||
)
|
||||
|
||||
func (r NATDeviceType) String() string {
|
||||
switch r {
|
||||
case 0:
|
||||
return "Unknown"
|
||||
case 1:
|
||||
return "Cone"
|
||||
case 2:
|
||||
return "Symmetric"
|
||||
default:
|
||||
return "unrecognized"
|
||||
}
|
||||
}
|
||||
|
||||
// NATTransportProtocol is the transport protocol for which the NAT Device Type has been determined.
|
||||
type NATTransportProtocol int
|
||||
|
||||
const (
|
||||
// NATTransportUDP means that the NAT Device Type has been determined for the UDP Protocol.
|
||||
NATTransportUDP NATTransportProtocol = iota
|
||||
// NATTransportTCP means that the NAT Device Type has been determined for the TCP Protocol.
|
||||
NATTransportTCP
|
||||
)
|
||||
|
||||
func (n NATTransportProtocol) String() string {
|
||||
switch n {
|
||||
case 0:
|
||||
return "UDP"
|
||||
case 1:
|
||||
return "TCP"
|
||||
default:
|
||||
return "unrecognized"
|
||||
}
|
||||
}
|
||||
198
vendor/github.com/libp2p/go-libp2p/core/network/network.go
generated
vendored
Normal file
198
vendor/github.com/libp2p/go-libp2p/core/network/network.go
generated
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
// Package network provides core networking abstractions for libp2p.
|
||||
//
|
||||
// The network package provides the high-level Network interface for interacting
|
||||
// with other libp2p peers, which is the primary public API for initiating and
|
||||
// accepting connections to remote peers.
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/peerstore"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// MessageSizeMax is a soft (recommended) maximum for network messages.
|
||||
// One can write more, as the interface is a stream. But it is useful
|
||||
// to bunch it up into multiple read/writes when the whole message is
|
||||
// a single, large serialized object.
|
||||
const MessageSizeMax = 1 << 22 // 4 MB
|
||||
|
||||
// Direction represents which peer in a stream initiated a connection.
|
||||
type Direction int
|
||||
|
||||
const (
|
||||
// DirUnknown is the default direction.
|
||||
DirUnknown Direction = iota
|
||||
// DirInbound is for when the remote peer initiated a connection.
|
||||
DirInbound
|
||||
// DirOutbound is for when the local peer initiated a connection.
|
||||
DirOutbound
|
||||
)
|
||||
|
||||
const unrecognized = "(unrecognized)"
|
||||
|
||||
func (d Direction) String() string {
|
||||
str := [...]string{"Unknown", "Inbound", "Outbound"}
|
||||
if d < 0 || int(d) >= len(str) {
|
||||
return unrecognized
|
||||
}
|
||||
return str[d]
|
||||
}
|
||||
|
||||
// Connectedness signals the capacity for a connection with a given node.
|
||||
// It is used to signal to services and other peers whether a node is reachable.
|
||||
type Connectedness int
|
||||
|
||||
const (
|
||||
// NotConnected means no connection to peer, and no extra information (default)
|
||||
NotConnected Connectedness = iota
|
||||
|
||||
// Connected means has an open, live connection to peer
|
||||
Connected
|
||||
|
||||
// CanConnect means recently connected to peer, terminated gracefully
|
||||
CanConnect
|
||||
|
||||
// CannotConnect means recently attempted connecting but failed to connect.
|
||||
// (should signal "made effort, failed")
|
||||
CannotConnect
|
||||
)
|
||||
|
||||
func (c Connectedness) String() string {
|
||||
str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect"}
|
||||
if c < 0 || int(c) >= len(str) {
|
||||
return unrecognized
|
||||
}
|
||||
return str[c]
|
||||
}
|
||||
|
||||
// Reachability indicates how reachable a node is.
|
||||
type Reachability int
|
||||
|
||||
const (
|
||||
// ReachabilityUnknown indicates that the reachability status of the
|
||||
// node is unknown.
|
||||
ReachabilityUnknown Reachability = iota
|
||||
|
||||
// ReachabilityPublic indicates that the node is reachable from the
|
||||
// public internet.
|
||||
ReachabilityPublic
|
||||
|
||||
// ReachabilityPrivate indicates that the node is not reachable from the
|
||||
// public internet.
|
||||
//
|
||||
// NOTE: This node may _still_ be reachable via relays.
|
||||
ReachabilityPrivate
|
||||
)
|
||||
|
||||
func (r Reachability) String() string {
|
||||
str := [...]string{"Unknown", "Public", "Private"}
|
||||
if r < 0 || int(r) >= len(str) {
|
||||
return unrecognized
|
||||
}
|
||||
return str[r]
|
||||
}
|
||||
|
||||
// ConnStats stores metadata pertaining to a given Conn.
|
||||
type ConnStats struct {
|
||||
Stats
|
||||
// NumStreams is the number of streams on the connection.
|
||||
NumStreams int
|
||||
}
|
||||
|
||||
// Stats stores metadata pertaining to a given Stream / Conn.
|
||||
type Stats struct {
|
||||
// Direction specifies whether this is an inbound or an outbound connection.
|
||||
Direction Direction
|
||||
// Opened is the timestamp when this connection was opened.
|
||||
Opened time.Time
|
||||
// Transient indicates that this connection is transient and may be closed soon.
|
||||
Transient bool
|
||||
// Extra stores additional metadata about this connection.
|
||||
Extra map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// StreamHandler is the type of function used to listen for
|
||||
// streams opened by the remote side.
|
||||
type StreamHandler func(Stream)
|
||||
|
||||
// Network is the interface used to connect to the outside world.
|
||||
// It dials and listens for connections. it uses a Swarm to pool
|
||||
// connections (see swarm pkg, and peerstream.Swarm). Connections
|
||||
// are encrypted with a TLS-like protocol.
|
||||
type Network interface {
|
||||
Dialer
|
||||
io.Closer
|
||||
|
||||
// SetStreamHandler sets the handler for new streams opened by the
|
||||
// remote side. This operation is thread-safe.
|
||||
SetStreamHandler(StreamHandler)
|
||||
|
||||
// NewStream returns a new stream to given peer p.
|
||||
// If there is no connection to p, attempts to create one.
|
||||
NewStream(context.Context, peer.ID) (Stream, error)
|
||||
|
||||
// Listen tells the network to start listening on given multiaddrs.
|
||||
Listen(...ma.Multiaddr) error
|
||||
|
||||
// ListenAddresses returns a list of addresses at which this network listens.
|
||||
ListenAddresses() []ma.Multiaddr
|
||||
|
||||
// InterfaceListenAddresses returns a list of addresses at which this network
|
||||
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||
// use the known local interfaces.
|
||||
InterfaceListenAddresses() ([]ma.Multiaddr, error)
|
||||
|
||||
// ResourceManager returns the ResourceManager associated with this network
|
||||
ResourceManager() ResourceManager
|
||||
}
|
||||
|
||||
// Dialer represents a service that can dial out to peers
|
||||
// (this is usually just a Network, but other services may not need the whole
|
||||
// stack, and thus it becomes easier to mock)
|
||||
type Dialer interface {
|
||||
// Peerstore returns the internal peerstore
|
||||
// This is useful to tell the dialer about a new address for a peer.
|
||||
// Or use one of the public keys found out over the network.
|
||||
Peerstore() peerstore.Peerstore
|
||||
|
||||
// LocalPeer returns the local peer associated with this network
|
||||
LocalPeer() peer.ID
|
||||
|
||||
// DialPeer establishes a connection to a given peer
|
||||
DialPeer(context.Context, peer.ID) (Conn, error)
|
||||
|
||||
// ClosePeer closes the connection to a given peer
|
||||
ClosePeer(peer.ID) error
|
||||
|
||||
// Connectedness returns a state signaling connection capabilities
|
||||
Connectedness(peer.ID) Connectedness
|
||||
|
||||
// Peers returns the peers connected
|
||||
Peers() []peer.ID
|
||||
|
||||
// Conns returns the connections in this Network
|
||||
Conns() []Conn
|
||||
|
||||
// ConnsToPeer returns the connections in this Network for given peer.
|
||||
ConnsToPeer(p peer.ID) []Conn
|
||||
|
||||
// Notify/StopNotify register and unregister a notifiee for signals
|
||||
Notify(Notifiee)
|
||||
StopNotify(Notifiee)
|
||||
}
|
||||
|
||||
// AddrDelay provides an address along with the delay after which the address
|
||||
// should be dialed
|
||||
type AddrDelay struct {
|
||||
Addr ma.Multiaddr
|
||||
Delay time.Duration
|
||||
}
|
||||
|
||||
// DialRanker provides a schedule of dialing the provided addresses
|
||||
type DialRanker func([]ma.Multiaddr) []AddrDelay
|
||||
67
vendor/github.com/libp2p/go-libp2p/core/network/notifee.go
generated
vendored
Normal file
67
vendor/github.com/libp2p/go-libp2p/core/network/notifee.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Notifiee is an interface for an object wishing to receive
|
||||
// notifications from a Network.
|
||||
type Notifiee interface {
|
||||
Listen(Network, ma.Multiaddr) // called when network starts listening on an addr
|
||||
ListenClose(Network, ma.Multiaddr) // called when network stops listening on an addr
|
||||
Connected(Network, Conn) // called when a connection opened
|
||||
Disconnected(Network, Conn) // called when a connection closed
|
||||
}
|
||||
|
||||
// NotifyBundle implements Notifiee by calling any of the functions set on it,
|
||||
// and nop'ing if they are unset. This is the easy way to register for
|
||||
// notifications.
|
||||
type NotifyBundle struct {
|
||||
ListenF func(Network, ma.Multiaddr)
|
||||
ListenCloseF func(Network, ma.Multiaddr)
|
||||
|
||||
ConnectedF func(Network, Conn)
|
||||
DisconnectedF func(Network, Conn)
|
||||
}
|
||||
|
||||
var _ Notifiee = (*NotifyBundle)(nil)
|
||||
|
||||
// Listen calls ListenF if it is not null.
|
||||
func (nb *NotifyBundle) Listen(n Network, a ma.Multiaddr) {
|
||||
if nb.ListenF != nil {
|
||||
nb.ListenF(n, a)
|
||||
}
|
||||
}
|
||||
|
||||
// ListenClose calls ListenCloseF if it is not null.
|
||||
func (nb *NotifyBundle) ListenClose(n Network, a ma.Multiaddr) {
|
||||
if nb.ListenCloseF != nil {
|
||||
nb.ListenCloseF(n, a)
|
||||
}
|
||||
}
|
||||
|
||||
// Connected calls ConnectedF if it is not null.
|
||||
func (nb *NotifyBundle) Connected(n Network, c Conn) {
|
||||
if nb.ConnectedF != nil {
|
||||
nb.ConnectedF(n, c)
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnected calls DisconnectedF if it is not null.
|
||||
func (nb *NotifyBundle) Disconnected(n Network, c Conn) {
|
||||
if nb.DisconnectedF != nil {
|
||||
nb.DisconnectedF(n, c)
|
||||
}
|
||||
}
|
||||
|
||||
// Global noop notifiee. Do not change.
|
||||
var GlobalNoopNotifiee = &NoopNotifiee{}
|
||||
|
||||
type NoopNotifiee struct{}
|
||||
|
||||
var _ Notifiee = (*NoopNotifiee)(nil)
|
||||
|
||||
func (nn *NoopNotifiee) Connected(n Network, c Conn) {}
|
||||
func (nn *NoopNotifiee) Disconnected(n Network, c Conn) {}
|
||||
func (nn *NoopNotifiee) Listen(n Network, addr ma.Multiaddr) {}
|
||||
func (nn *NoopNotifiee) ListenClose(n Network, addr ma.Multiaddr) {}
|
||||
326
vendor/github.com/libp2p/go-libp2p/core/network/rcmgr.go
generated
vendored
Normal file
326
vendor/github.com/libp2p/go-libp2p/core/network/rcmgr.go
generated
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// ResourceManager is the interface to the network resource management subsystem.
|
||||
// The ResourceManager tracks and accounts for resource usage in the stack, from the internals
|
||||
// to the application, and provides a mechanism to limit resource usage according to a user
|
||||
// configurable policy.
|
||||
//
|
||||
// Resource Management through the ResourceManager is based on the concept of Resource
|
||||
// Management Scopes, whereby resource usage is constrained by a DAG of scopes,
|
||||
// The following diagram illustrates the structure of the resource constraint DAG:
|
||||
// System
|
||||
//
|
||||
// +------------> Transient.............+................+
|
||||
// | . .
|
||||
// +------------> Service------------- . ----------+ .
|
||||
// | . | .
|
||||
// +-------------> Protocol----------- . ----------+ .
|
||||
// | . | .
|
||||
// +--------------> Peer \ | .
|
||||
// +------------> Connection | .
|
||||
// | \ \
|
||||
// +---------------------------> Stream
|
||||
//
|
||||
// The basic resources accounted by the ResourceManager include memory, streams, connections,
|
||||
// and file descriptors. These account for both space and time used by
|
||||
// the stack, as each resource has a direct effect on the system
|
||||
// availability and performance.
|
||||
//
|
||||
// The modus operandi of the resource manager is to restrict resource usage at the time of
|
||||
// reservation. When a component of the stack needs to use a resource, it reserves it in the
|
||||
// appropriate scope. The resource manager gates the reservation against the scope applicable
|
||||
// limits; if the limit is exceeded, then an error (wrapping ErrResourceLimitExceeded) and it
|
||||
// is up the component to act accordingly. At the lower levels of the stack, this will normally
|
||||
// signal a failure of some sorts, like failing to opening a stream or a connection, which will
|
||||
// propagate to the programmer. Some components may be able to handle resource reservation failure
|
||||
// more gracefully; for instance a muxer trying to grow a buffer for a window change, will simply
|
||||
// retain the existing window size and continue to operate normally albeit with some degraded
|
||||
// throughput.
|
||||
// All resources reserved in some scope are released when the scope is closed. For low level
|
||||
// scopes, mainly Connection and Stream scopes, this happens when the connection or stream is
|
||||
// closed.
|
||||
//
|
||||
// Service programmers will typically use the resource manager to reserve memory
|
||||
// for their subsystem.
|
||||
// This happens with two avenues: the programmer can attach a stream to a service, whereby
|
||||
// resources reserved by the stream are automatically accounted in the service budget; or the
|
||||
// programmer may directly interact with the service scope, by using ViewService through the
|
||||
// resource manager interface.
|
||||
//
|
||||
// Application programmers can also directly reserve memory in some applicable scope. In order
|
||||
// to facilitate control flow delimited resource accounting, all scopes defined in the system
|
||||
// allow for the user to create spans. Spans are temporary scopes rooted at some
|
||||
// other scope and release their resources when the programmer is done with them. Span
|
||||
// scopes can form trees, with nested spans.
|
||||
//
|
||||
// Typical Usage:
|
||||
// - Low level components of the system (transports, muxers) all have access to the resource
|
||||
// manager and create connection and stream scopes through it. These scopes are accessible
|
||||
// to the user, albeit with a narrower interface, through Conn and Stream objects who have
|
||||
// a Scope method.
|
||||
// - Services typically center around streams, where the programmer can attach streams to a
|
||||
// particular service. They can also directly reserve memory for a service by accessing the
|
||||
// service scope using the ResourceManager interface.
|
||||
// - Applications that want to account for their network resource usage can reserve memory,
|
||||
// typically using a span, directly in the System or a Service scope; they can also
|
||||
// opt to use appropriate stream scopes for streams that they create or own.
|
||||
//
|
||||
// User Serviceable Parts: the user has the option to specify their own implementation of the
|
||||
// interface. We provide a canonical implementation in the go-libp2p-resource-manager package.
|
||||
// The user of that package can specify limits for the various scopes, which can be static
|
||||
// or dynamic.
|
||||
//
|
||||
// WARNING The ResourceManager interface is considered experimental and subject to change
|
||||
// in subsequent releases.
|
||||
type ResourceManager interface {
|
||||
ResourceScopeViewer
|
||||
|
||||
// OpenConnection creates a new connection scope not yet associated with any peer; the connection
|
||||
// is scoped at the transient scope.
|
||||
// The caller owns the returned scope and is responsible for calling Done in order to signify
|
||||
// the end of the scope's span.
|
||||
OpenConnection(dir Direction, usefd bool, endpoint multiaddr.Multiaddr) (ConnManagementScope, error)
|
||||
|
||||
// OpenStream creates a new stream scope, initially unnegotiated.
|
||||
// An unnegotiated stream will be initially unattached to any protocol scope
|
||||
// and constrained by the transient scope.
|
||||
// The caller owns the returned scope and is responsible for calling Done in order to signify
|
||||
// the end of th scope's span.
|
||||
OpenStream(p peer.ID, dir Direction) (StreamManagementScope, error)
|
||||
|
||||
// Close closes the resource manager
|
||||
Close() error
|
||||
}
|
||||
|
||||
// ResourceScopeViewer is a mixin interface providing view methods for accessing top level
|
||||
// scopes.
|
||||
type ResourceScopeViewer interface {
|
||||
// ViewSystem views the system-wide resource scope.
|
||||
// The system scope is the top level scope that accounts for global
|
||||
// resource usage at all levels of the system. This scope constrains all
|
||||
// other scopes and institutes global hard limits.
|
||||
ViewSystem(func(ResourceScope) error) error
|
||||
|
||||
// ViewTransient views the transient (DMZ) resource scope.
|
||||
// The transient scope accounts for resources that are in the process of
|
||||
// full establishment. For instance, a new connection prior to the
|
||||
// handshake does not belong to any peer, but it still needs to be
|
||||
// constrained as this opens an avenue for attacks in transient resource
|
||||
// usage. Similarly, a stream that has not negotiated a protocol yet is
|
||||
// constrained by the transient scope.
|
||||
ViewTransient(func(ResourceScope) error) error
|
||||
|
||||
// ViewService retrieves a service-specific scope.
|
||||
ViewService(string, func(ServiceScope) error) error
|
||||
|
||||
// ViewProtocol views the resource management scope for a specific protocol.
|
||||
ViewProtocol(protocol.ID, func(ProtocolScope) error) error
|
||||
|
||||
// ViewPeer views the resource management scope for a specific peer.
|
||||
ViewPeer(peer.ID, func(PeerScope) error) error
|
||||
}
|
||||
|
||||
const (
|
||||
// ReservationPriorityLow is a reservation priority that indicates a reservation if the scope
|
||||
// memory utilization is at 40% or less.
|
||||
ReservationPriorityLow uint8 = 101
|
||||
// Reservation PriorityMedium is a reservation priority that indicates a reservation if the scope
|
||||
// memory utilization is at 60% or less.
|
||||
ReservationPriorityMedium uint8 = 152
|
||||
// ReservationPriorityHigh is a reservation priority that indicates a reservation if the scope
|
||||
// memory utilization is at 80% or less.
|
||||
ReservationPriorityHigh uint8 = 203
|
||||
// ReservationPriorityAlways is a reservation priority that indicates a reservation if there is
|
||||
// enough memory, regardless of scope utilization.
|
||||
ReservationPriorityAlways uint8 = 255
|
||||
)
|
||||
|
||||
// ResourceScope is the interface for all scopes.
|
||||
type ResourceScope interface {
|
||||
// ReserveMemory reserves memory/buffer space in the scope; the unit is bytes.
|
||||
//
|
||||
// If ReserveMemory returns an error, then no memory was reserved and the caller should handle
|
||||
// the failure condition.
|
||||
//
|
||||
// The priority argument indicates the priority of the memory reservation. A reservation
|
||||
// will fail if the available memory is less than (1+prio)/256 of the scope limit, providing
|
||||
// a mechanism to gracefully handle optional reservations that might overload the system.
|
||||
// For instance, a muxer growing a window buffer will use a low priority and only grow the buffer
|
||||
// if there is no memory pressure in the system.
|
||||
//
|
||||
// There are 4 predefined priority levels, Low, Medium, High and Always,
|
||||
// capturing common patterns, but the user is free to use any granularity applicable to his case.
|
||||
ReserveMemory(size int, prio uint8) error
|
||||
|
||||
// ReleaseMemory explicitly releases memory previously reserved with ReserveMemory
|
||||
ReleaseMemory(size int)
|
||||
|
||||
// Stat retrieves current resource usage for the scope.
|
||||
Stat() ScopeStat
|
||||
|
||||
// BeginSpan creates a new span scope rooted at this scope
|
||||
BeginSpan() (ResourceScopeSpan, error)
|
||||
}
|
||||
|
||||
// ResourceScopeSpan is a ResourceScope with a delimited span.
|
||||
// Span scopes are control flow delimited and release all their associated resources
|
||||
// when the programmer calls Done.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// s, err := someScope.BeginSpan()
|
||||
// if err != nil { ... }
|
||||
// defer s.Done()
|
||||
//
|
||||
// if err := s.ReserveMemory(...); err != nil { ... }
|
||||
// // ... use memory
|
||||
type ResourceScopeSpan interface {
|
||||
ResourceScope
|
||||
// Done ends the span and releases associated resources.
|
||||
Done()
|
||||
}
|
||||
|
||||
// ServiceScope is the interface for service resource scopes
|
||||
type ServiceScope interface {
|
||||
ResourceScope
|
||||
|
||||
// Name returns the name of this service
|
||||
Name() string
|
||||
}
|
||||
|
||||
// ProtocolScope is the interface for protocol resource scopes.
|
||||
type ProtocolScope interface {
|
||||
ResourceScope
|
||||
|
||||
// Protocol returns the protocol for this scope
|
||||
Protocol() protocol.ID
|
||||
}
|
||||
|
||||
// PeerScope is the interface for peer resource scopes.
|
||||
type PeerScope interface {
|
||||
ResourceScope
|
||||
|
||||
// Peer returns the peer ID for this scope
|
||||
Peer() peer.ID
|
||||
}
|
||||
|
||||
// ConnManagementScope is the low level interface for connection resource scopes.
|
||||
// This interface is used by the low level components of the system who create and own
|
||||
// the span of a connection scope.
|
||||
type ConnManagementScope interface {
|
||||
ResourceScopeSpan
|
||||
|
||||
// PeerScope returns the peer scope associated with this connection.
|
||||
// It returns nil if the connection is not yet associated with any peer.
|
||||
PeerScope() PeerScope
|
||||
|
||||
// SetPeer sets the peer for a previously unassociated connection
|
||||
SetPeer(peer.ID) error
|
||||
}
|
||||
|
||||
// ConnScope is the user view of a connection scope
|
||||
type ConnScope interface {
|
||||
ResourceScope
|
||||
}
|
||||
|
||||
// StreamManagementScope is the interface for stream resource scopes.
|
||||
// This interface is used by the low level components of the system who create and own
|
||||
// the span of a stream scope.
|
||||
type StreamManagementScope interface {
|
||||
ResourceScopeSpan
|
||||
|
||||
// ProtocolScope returns the protocol resource scope associated with this stream.
|
||||
// It returns nil if the stream is not associated with any protocol scope.
|
||||
ProtocolScope() ProtocolScope
|
||||
// SetProtocol sets the protocol for a previously unnegotiated stream
|
||||
SetProtocol(proto protocol.ID) error
|
||||
|
||||
// ServiceScope returns the service owning the stream, if any.
|
||||
ServiceScope() ServiceScope
|
||||
// SetService sets the service owning this stream.
|
||||
SetService(srv string) error
|
||||
|
||||
// PeerScope returns the peer resource scope associated with this stream.
|
||||
PeerScope() PeerScope
|
||||
}
|
||||
|
||||
// StreamScope is the user view of a StreamScope.
|
||||
type StreamScope interface {
|
||||
ResourceScope
|
||||
|
||||
// SetService sets the service owning this stream.
|
||||
SetService(srv string) error
|
||||
}
|
||||
|
||||
// ScopeStat is a struct containing resource accounting information.
|
||||
type ScopeStat struct {
|
||||
NumStreamsInbound int
|
||||
NumStreamsOutbound int
|
||||
NumConnsInbound int
|
||||
NumConnsOutbound int
|
||||
NumFD int
|
||||
|
||||
Memory int64
|
||||
}
|
||||
|
||||
// NullResourceManager is a stub for tests and initialization of default values
|
||||
type NullResourceManager struct{}
|
||||
|
||||
var _ ResourceScope = (*NullScope)(nil)
|
||||
var _ ResourceScopeSpan = (*NullScope)(nil)
|
||||
var _ ServiceScope = (*NullScope)(nil)
|
||||
var _ ProtocolScope = (*NullScope)(nil)
|
||||
var _ PeerScope = (*NullScope)(nil)
|
||||
var _ ConnManagementScope = (*NullScope)(nil)
|
||||
var _ ConnScope = (*NullScope)(nil)
|
||||
var _ StreamManagementScope = (*NullScope)(nil)
|
||||
var _ StreamScope = (*NullScope)(nil)
|
||||
|
||||
// NullScope is a stub for tests and initialization of default values
|
||||
type NullScope struct{}
|
||||
|
||||
func (n *NullResourceManager) ViewSystem(f func(ResourceScope) error) error {
|
||||
return f(&NullScope{})
|
||||
}
|
||||
func (n *NullResourceManager) ViewTransient(f func(ResourceScope) error) error {
|
||||
return f(&NullScope{})
|
||||
}
|
||||
func (n *NullResourceManager) ViewService(svc string, f func(ServiceScope) error) error {
|
||||
return f(&NullScope{})
|
||||
}
|
||||
func (n *NullResourceManager) ViewProtocol(p protocol.ID, f func(ProtocolScope) error) error {
|
||||
return f(&NullScope{})
|
||||
}
|
||||
func (n *NullResourceManager) ViewPeer(p peer.ID, f func(PeerScope) error) error {
|
||||
return f(&NullScope{})
|
||||
}
|
||||
func (n *NullResourceManager) OpenConnection(dir Direction, usefd bool, endpoint multiaddr.Multiaddr) (ConnManagementScope, error) {
|
||||
return &NullScope{}, nil
|
||||
}
|
||||
func (n *NullResourceManager) OpenStream(p peer.ID, dir Direction) (StreamManagementScope, error) {
|
||||
return &NullScope{}, nil
|
||||
}
|
||||
func (n *NullResourceManager) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NullScope) ReserveMemory(size int, prio uint8) error { return nil }
|
||||
func (n *NullScope) ReleaseMemory(size int) {}
|
||||
func (n *NullScope) Stat() ScopeStat { return ScopeStat{} }
|
||||
func (n *NullScope) BeginSpan() (ResourceScopeSpan, error) { return &NullScope{}, nil }
|
||||
func (n *NullScope) Done() {}
|
||||
func (n *NullScope) Name() string { return "" }
|
||||
func (n *NullScope) Protocol() protocol.ID { return "" }
|
||||
func (n *NullScope) Peer() peer.ID { return "" }
|
||||
func (n *NullScope) PeerScope() PeerScope { return &NullScope{} }
|
||||
func (n *NullScope) SetPeer(peer.ID) error { return nil }
|
||||
func (n *NullScope) ProtocolScope() ProtocolScope { return &NullScope{} }
|
||||
func (n *NullScope) SetProtocol(proto protocol.ID) error { return nil }
|
||||
func (n *NullScope) ServiceScope() ServiceScope { return &NullScope{} }
|
||||
func (n *NullScope) SetService(srv string) error { return nil }
|
||||
30
vendor/github.com/libp2p/go-libp2p/core/network/stream.go
generated
vendored
Normal file
30
vendor/github.com/libp2p/go-libp2p/core/network/stream.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
)
|
||||
|
||||
// Stream represents a bidirectional channel between two agents in
|
||||
// a libp2p network. "agent" is as granular as desired, potentially
|
||||
// being a "request -> reply" pair, or whole protocols.
|
||||
//
|
||||
// Streams are backed by a multiplexer underneath the hood.
|
||||
type Stream interface {
|
||||
MuxedStream
|
||||
|
||||
// ID returns an identifier that uniquely identifies this Stream within this
|
||||
// host, during this run. Stream IDs may repeat across restarts.
|
||||
ID() string
|
||||
|
||||
Protocol() protocol.ID
|
||||
SetProtocol(id protocol.ID) error
|
||||
|
||||
// Stat returns metadata pertaining to this stream.
|
||||
Stat() Stats
|
||||
|
||||
// Conn returns the connection this stream is part of.
|
||||
Conn() Conn
|
||||
|
||||
// Scope returns the user's view of this stream's resource scope
|
||||
Scope() StreamScope
|
||||
}
|
||||
117
vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo.go
generated
vendored
Normal file
117
vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// AddrInfo is a small struct used to pass around a peer with
|
||||
// a set of addresses (and later, keys?).
|
||||
type AddrInfo struct {
|
||||
ID ID
|
||||
Addrs []ma.Multiaddr
|
||||
}
|
||||
|
||||
var _ fmt.Stringer = AddrInfo{}
|
||||
|
||||
func (pi AddrInfo) String() string {
|
||||
return fmt.Sprintf("{%v: %v}", pi.ID, pi.Addrs)
|
||||
}
|
||||
|
||||
var ErrInvalidAddr = fmt.Errorf("invalid p2p multiaddr")
|
||||
|
||||
// AddrInfosFromP2pAddrs converts a set of Multiaddrs to a set of AddrInfos.
|
||||
func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) {
|
||||
m := make(map[ID][]ma.Multiaddr)
|
||||
for _, maddr := range maddrs {
|
||||
transport, id := SplitAddr(maddr)
|
||||
if id == "" {
|
||||
return nil, ErrInvalidAddr
|
||||
}
|
||||
if transport == nil {
|
||||
if _, ok := m[id]; !ok {
|
||||
m[id] = nil
|
||||
}
|
||||
} else {
|
||||
m[id] = append(m[id], transport)
|
||||
}
|
||||
}
|
||||
ais := make([]AddrInfo, 0, len(m))
|
||||
for id, maddrs := range m {
|
||||
ais = append(ais, AddrInfo{ID: id, Addrs: maddrs})
|
||||
}
|
||||
return ais, nil
|
||||
}
|
||||
|
||||
// SplitAddr splits a p2p Multiaddr into a transport multiaddr and a peer ID.
|
||||
//
|
||||
// * Returns a nil transport if the address only contains a /p2p part.
|
||||
// * Returns an empty peer ID if the address doesn't contain a /p2p part.
|
||||
func SplitAddr(m ma.Multiaddr) (transport ma.Multiaddr, id ID) {
|
||||
if m == nil {
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
transport, p2ppart := ma.SplitLast(m)
|
||||
if p2ppart == nil || p2ppart.Protocol().Code != ma.P_P2P {
|
||||
return m, ""
|
||||
}
|
||||
id = ID(p2ppart.RawValue()) // already validated by the multiaddr library.
|
||||
return transport, id
|
||||
}
|
||||
|
||||
// AddrInfoFromString builds an AddrInfo from the string representation of a Multiaddr
|
||||
func AddrInfoFromString(s string) (*AddrInfo, error) {
|
||||
a, err := ma.NewMultiaddr(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return AddrInfoFromP2pAddr(a)
|
||||
}
|
||||
|
||||
// AddrInfoFromP2pAddr converts a Multiaddr to an AddrInfo.
|
||||
func AddrInfoFromP2pAddr(m ma.Multiaddr) (*AddrInfo, error) {
|
||||
transport, id := SplitAddr(m)
|
||||
if id == "" {
|
||||
return nil, ErrInvalidAddr
|
||||
}
|
||||
info := &AddrInfo{ID: id}
|
||||
if transport != nil {
|
||||
info.Addrs = []ma.Multiaddr{transport}
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// AddrInfoToP2pAddrs converts an AddrInfo to a list of Multiaddrs.
|
||||
func AddrInfoToP2pAddrs(pi *AddrInfo) ([]ma.Multiaddr, error) {
|
||||
p2ppart, err := ma.NewComponent("p2p", Encode(pi.ID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pi.Addrs) == 0 {
|
||||
return []ma.Multiaddr{p2ppart}, nil
|
||||
}
|
||||
addrs := make([]ma.Multiaddr, 0, len(pi.Addrs))
|
||||
for _, addr := range pi.Addrs {
|
||||
addrs = append(addrs, addr.Encapsulate(p2ppart))
|
||||
}
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
func (pi *AddrInfo) Loggable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"peerID": pi.ID.Pretty(),
|
||||
"addrs": pi.Addrs,
|
||||
}
|
||||
}
|
||||
|
||||
// AddrInfosToIDs extracts the peer IDs from the passed AddrInfos and returns them in-order.
|
||||
func AddrInfosToIDs(pis []AddrInfo) []ID {
|
||||
ps := make([]ID, len(pis))
|
||||
for i, pi := range pis {
|
||||
ps[i] = pi.ID
|
||||
}
|
||||
return ps
|
||||
}
|
||||
48
vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo_serde.go
generated
vendored
Normal file
48
vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo_serde.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Helper struct for decoding as we can't unmarshal into an interface (Multiaddr).
|
||||
type addrInfoJson struct {
|
||||
ID ID
|
||||
Addrs []string
|
||||
}
|
||||
|
||||
func (pi AddrInfo) MarshalJSON() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p addr info marshal") }()
|
||||
|
||||
addrs := make([]string, len(pi.Addrs))
|
||||
for i, addr := range pi.Addrs {
|
||||
addrs[i] = addr.String()
|
||||
}
|
||||
return json.Marshal(&addrInfoJson{
|
||||
ID: pi.ID,
|
||||
Addrs: addrs,
|
||||
})
|
||||
}
|
||||
|
||||
func (pi *AddrInfo) UnmarshalJSON(b []byte) (err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p addr info unmarshal") }()
|
||||
var data addrInfoJson
|
||||
if err := json.Unmarshal(b, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
addrs := make([]ma.Multiaddr, len(data.Addrs))
|
||||
for i, addr := range data.Addrs {
|
||||
maddr, err := ma.NewMultiaddr(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrs[i] = maddr
|
||||
}
|
||||
|
||||
pi.ID = data.ID
|
||||
pi.Addrs = addrs
|
||||
return nil
|
||||
}
|
||||
239
vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.pb.go
generated
vendored
Normal file
239
vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.pb.go
generated
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: pb/peer_record.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// PeerRecord messages contain information that is useful to share with other peers.
|
||||
// Currently, a PeerRecord contains the public listen addresses for a peer, but this
|
||||
// is expected to expand to include other information in the future.
|
||||
//
|
||||
// PeerRecords are designed to be serialized to bytes and placed inside of
|
||||
// SignedEnvelopes before sharing with other peers.
|
||||
// See https://github.com/libp2p/go-libp2p/core/record/pb/envelope.proto for
|
||||
// the SignedEnvelope definition.
|
||||
type PeerRecord struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// peer_id contains a libp2p peer id in its binary representation.
|
||||
PeerId []byte `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"`
|
||||
// seq contains a monotonically-increasing sequence counter to order PeerRecords in time.
|
||||
Seq uint64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq,omitempty"`
|
||||
// addresses is a list of public listen addresses for the peer.
|
||||
Addresses []*PeerRecord_AddressInfo `protobuf:"bytes,3,rep,name=addresses,proto3" json:"addresses,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeerRecord) Reset() {
|
||||
*x = PeerRecord{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_peer_record_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PeerRecord) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PeerRecord) ProtoMessage() {}
|
||||
|
||||
func (x *PeerRecord) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_peer_record_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PeerRecord.ProtoReflect.Descriptor instead.
|
||||
func (*PeerRecord) Descriptor() ([]byte, []int) {
|
||||
return file_pb_peer_record_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PeerRecord) GetPeerId() []byte {
|
||||
if x != nil {
|
||||
return x.PeerId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PeerRecord) GetSeq() uint64 {
|
||||
if x != nil {
|
||||
return x.Seq
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PeerRecord) GetAddresses() []*PeerRecord_AddressInfo {
|
||||
if x != nil {
|
||||
return x.Addresses
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddressInfo is a wrapper around a binary multiaddr. It is defined as a
|
||||
// separate message to allow us to add per-address metadata in the future.
|
||||
type PeerRecord_AddressInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Multiaddr []byte `protobuf:"bytes,1,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeerRecord_AddressInfo) Reset() {
|
||||
*x = PeerRecord_AddressInfo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_peer_record_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PeerRecord_AddressInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PeerRecord_AddressInfo) ProtoMessage() {}
|
||||
|
||||
func (x *PeerRecord_AddressInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_peer_record_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PeerRecord_AddressInfo.ProtoReflect.Descriptor instead.
|
||||
func (*PeerRecord_AddressInfo) Descriptor() ([]byte, []int) {
|
||||
return file_pb_peer_record_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
func (x *PeerRecord_AddressInfo) GetMultiaddr() []byte {
|
||||
if x != nil {
|
||||
return x.Multiaddr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pb_peer_record_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pb_peer_record_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x70, 0x62, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x65, 0x65, 0x72, 0x2e, 0x70, 0x62, 0x22,
|
||||
0xa3, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x17,
|
||||
0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x64, 0x64,
|
||||
0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70,
|
||||
0x65, 0x65, 0x72, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72,
|
||||
0x64, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x61,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x1a, 0x2b, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69,
|
||||
0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74,
|
||||
0x69, 0x61, 0x64, 0x64, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pb_peer_record_proto_rawDescOnce sync.Once
|
||||
file_pb_peer_record_proto_rawDescData = file_pb_peer_record_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pb_peer_record_proto_rawDescGZIP() []byte {
|
||||
file_pb_peer_record_proto_rawDescOnce.Do(func() {
|
||||
file_pb_peer_record_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_peer_record_proto_rawDescData)
|
||||
})
|
||||
return file_pb_peer_record_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pb_peer_record_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_pb_peer_record_proto_goTypes = []interface{}{
|
||||
(*PeerRecord)(nil), // 0: peer.pb.PeerRecord
|
||||
(*PeerRecord_AddressInfo)(nil), // 1: peer.pb.PeerRecord.AddressInfo
|
||||
}
|
||||
var file_pb_peer_record_proto_depIdxs = []int32{
|
||||
1, // 0: peer.pb.PeerRecord.addresses:type_name -> peer.pb.PeerRecord.AddressInfo
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pb_peer_record_proto_init() }
|
||||
func file_pb_peer_record_proto_init() {
|
||||
if File_pb_peer_record_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pb_peer_record_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PeerRecord); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pb_peer_record_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PeerRecord_AddressInfo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_pb_peer_record_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pb_peer_record_proto_goTypes,
|
||||
DependencyIndexes: file_pb_peer_record_proto_depIdxs,
|
||||
MessageInfos: file_pb_peer_record_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pb_peer_record_proto = out.File
|
||||
file_pb_peer_record_proto_rawDesc = nil
|
||||
file_pb_peer_record_proto_goTypes = nil
|
||||
file_pb_peer_record_proto_depIdxs = nil
|
||||
}
|
||||
29
vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto
generated
vendored
Normal file
29
vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package peer.pb;
|
||||
|
||||
// PeerRecord messages contain information that is useful to share with other peers.
|
||||
// Currently, a PeerRecord contains the public listen addresses for a peer, but this
|
||||
// is expected to expand to include other information in the future.
|
||||
//
|
||||
// PeerRecords are designed to be serialized to bytes and placed inside of
|
||||
// SignedEnvelopes before sharing with other peers.
|
||||
// See https://github.com/libp2p/go-libp2p/core/record/pb/envelope.proto for
|
||||
// the SignedEnvelope definition.
|
||||
message PeerRecord {
|
||||
|
||||
// AddressInfo is a wrapper around a binary multiaddr. It is defined as a
|
||||
// separate message to allow us to add per-address metadata in the future.
|
||||
message AddressInfo {
|
||||
bytes multiaddr = 1;
|
||||
}
|
||||
|
||||
// peer_id contains a libp2p peer id in its binary representation.
|
||||
bytes peer_id = 1;
|
||||
|
||||
// seq contains a monotonically-increasing sequence counter to order PeerRecords in time.
|
||||
uint64 seq = 2;
|
||||
|
||||
// addresses is a list of public listen addresses for the peer.
|
||||
repeated AddressInfo addresses = 3;
|
||||
}
|
||||
210
vendor/github.com/libp2p/go-libp2p/core/peer/peer.go
generated
vendored
Normal file
210
vendor/github.com/libp2p/go-libp2p/core/peer/peer.go
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
// Package peer implements an object used to represent peers in the libp2p network.
|
||||
package peer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
ic "github.com/libp2p/go-libp2p/core/crypto"
|
||||
b58 "github.com/mr-tron/base58/base58"
|
||||
mc "github.com/multiformats/go-multicodec"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrEmptyPeerID is an error for empty peer ID.
|
||||
ErrEmptyPeerID = errors.New("empty peer ID")
|
||||
// ErrNoPublicKey is an error for peer IDs that don't embed public keys
|
||||
ErrNoPublicKey = errors.New("public key is not embedded in peer ID")
|
||||
)
|
||||
|
||||
// AdvancedEnableInlining enables automatically inlining keys shorter than
|
||||
// 42 bytes into the peer ID (using the "identity" multihash function).
|
||||
//
|
||||
// WARNING: This flag will likely be set to false in the future and eventually
|
||||
// be removed in favor of using a hash function specified by the key itself.
|
||||
// See: https://github.com/libp2p/specs/issues/138
|
||||
//
|
||||
// DO NOT change this flag unless you know what you're doing.
|
||||
//
|
||||
// This currently defaults to true for backwards compatibility but will likely
|
||||
// be set to false by default when an upgrade path is determined.
|
||||
var AdvancedEnableInlining = true
|
||||
|
||||
const maxInlineKeyLength = 42
|
||||
|
||||
// ID is a libp2p peer identity.
|
||||
//
|
||||
// Peer IDs are derived by hashing a peer's public key and encoding the
|
||||
// hash output as a multihash. See IDFromPublicKey for details.
|
||||
type ID string
|
||||
|
||||
// Pretty returns a base58-encoded string representation of the ID.
|
||||
// Deprecated: use String() instead.
|
||||
func (id ID) Pretty() string {
|
||||
return id.String()
|
||||
}
|
||||
|
||||
// Loggable returns a pretty peer ID string in loggable JSON format.
|
||||
func (id ID) Loggable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"peerID": id.String(),
|
||||
}
|
||||
}
|
||||
|
||||
func (id ID) String() string {
|
||||
return b58.Encode([]byte(id))
|
||||
}
|
||||
|
||||
// ShortString prints out the peer ID.
|
||||
//
|
||||
// TODO(brian): ensure correctness at ID generation and
|
||||
// enforce this by only exposing functions that generate
|
||||
// IDs safely. Then any peer.ID type found in the
|
||||
// codebase is known to be correct.
|
||||
func (id ID) ShortString() string {
|
||||
pid := id.String()
|
||||
if len(pid) <= 10 {
|
||||
return fmt.Sprintf("<peer.ID %s>", pid)
|
||||
}
|
||||
return fmt.Sprintf("<peer.ID %s*%s>", pid[:2], pid[len(pid)-6:])
|
||||
}
|
||||
|
||||
// MatchesPrivateKey tests whether this ID was derived from the secret key sk.
|
||||
func (id ID) MatchesPrivateKey(sk ic.PrivKey) bool {
|
||||
return id.MatchesPublicKey(sk.GetPublic())
|
||||
}
|
||||
|
||||
// MatchesPublicKey tests whether this ID was derived from the public key pk.
|
||||
func (id ID) MatchesPublicKey(pk ic.PubKey) bool {
|
||||
oid, err := IDFromPublicKey(pk)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return oid == id
|
||||
}
|
||||
|
||||
// ExtractPublicKey attempts to extract the public key from an ID.
|
||||
//
|
||||
// This method returns ErrNoPublicKey if the peer ID looks valid, but it can't extract
|
||||
// the public key.
|
||||
func (id ID) ExtractPublicKey() (ic.PubKey, error) {
|
||||
decoded, err := mh.Decode([]byte(id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if decoded.Code != mh.IDENTITY {
|
||||
return nil, ErrNoPublicKey
|
||||
}
|
||||
pk, err := ic.UnmarshalPublicKey(decoded.Digest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
// Validate checks if ID is empty or not.
|
||||
func (id ID) Validate() error {
|
||||
if id == ID("") {
|
||||
return ErrEmptyPeerID
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IDFromBytes casts a byte slice to the ID type, and validates
|
||||
// the value to make sure it is a multihash.
|
||||
func IDFromBytes(b []byte) (ID, error) {
|
||||
if _, err := mh.Cast(b); err != nil {
|
||||
return ID(""), err
|
||||
}
|
||||
return ID(b), nil
|
||||
}
|
||||
|
||||
// Decode accepts an encoded peer ID and returns the decoded ID if the input is
|
||||
// valid.
|
||||
//
|
||||
// The encoded peer ID can either be a CID of a key or a raw multihash (identity
|
||||
// or sha256-256).
|
||||
func Decode(s string) (ID, error) {
|
||||
if strings.HasPrefix(s, "Qm") || strings.HasPrefix(s, "1") {
|
||||
// base58 encoded sha256 or identity multihash
|
||||
m, err := mh.FromB58String(s)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse peer ID: %s", err)
|
||||
}
|
||||
return ID(m), nil
|
||||
}
|
||||
|
||||
c, err := cid.Decode(s)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse peer ID: %s", err)
|
||||
}
|
||||
return FromCid(c)
|
||||
}
|
||||
|
||||
// Encode encodes a peer ID as a string.
|
||||
//
|
||||
// At the moment, it base58 encodes the peer ID but, in the future, it will
|
||||
// switch to encoding it as a CID by default.
|
||||
//
|
||||
// Deprecated: use id.String instead.
|
||||
func Encode(id ID) string {
|
||||
return id.String()
|
||||
}
|
||||
|
||||
// FromCid converts a CID to a peer ID, if possible.
|
||||
func FromCid(c cid.Cid) (ID, error) {
|
||||
code := mc.Code(c.Type())
|
||||
if code != mc.Libp2pKey {
|
||||
return "", fmt.Errorf("can't convert CID of type %q to a peer ID", code)
|
||||
}
|
||||
return ID(c.Hash()), nil
|
||||
}
|
||||
|
||||
// ToCid encodes a peer ID as a CID of the public key.
|
||||
//
|
||||
// If the peer ID is invalid (e.g., empty), this will return the empty CID.
|
||||
func ToCid(id ID) cid.Cid {
|
||||
m, err := mh.Cast([]byte(id))
|
||||
if err != nil {
|
||||
return cid.Cid{}
|
||||
}
|
||||
return cid.NewCidV1(cid.Libp2pKey, m)
|
||||
}
|
||||
|
||||
// IDFromPublicKey returns the Peer ID corresponding to the public key pk.
|
||||
func IDFromPublicKey(pk ic.PubKey) (ID, error) {
|
||||
b, err := ic.MarshalPublicKey(pk)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var alg uint64 = mh.SHA2_256
|
||||
if AdvancedEnableInlining && len(b) <= maxInlineKeyLength {
|
||||
alg = mh.IDENTITY
|
||||
}
|
||||
hash, _ := mh.Sum(b, alg, -1)
|
||||
return ID(hash), nil
|
||||
}
|
||||
|
||||
// IDFromPrivateKey returns the Peer ID corresponding to the secret key sk.
|
||||
func IDFromPrivateKey(sk ic.PrivKey) (ID, error) {
|
||||
return IDFromPublicKey(sk.GetPublic())
|
||||
}
|
||||
|
||||
// IDSlice for sorting peers.
|
||||
type IDSlice []ID
|
||||
|
||||
func (es IDSlice) Len() int { return len(es) }
|
||||
func (es IDSlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
|
||||
func (es IDSlice) Less(i, j int) bool { return string(es[i]) < string(es[j]) }
|
||||
|
||||
func (es IDSlice) String() string {
|
||||
peersStrings := make([]string, len(es))
|
||||
for i, id := range es {
|
||||
peersStrings[i] = id.String()
|
||||
}
|
||||
return strings.Join(peersStrings, ", ")
|
||||
}
|
||||
73
vendor/github.com/libp2p/go-libp2p/core/peer/peer_serde.go
generated
vendored
Normal file
73
vendor/github.com/libp2p/go-libp2p/core/peer/peer_serde.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Package peer contains Protobuf and JSON serialization/deserialization methods for peer IDs.
|
||||
package peer
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Interface assertions commented out to avoid introducing hard dependencies to protobuf.
|
||||
// var _ proto.Marshaler = (*ID)(nil)
|
||||
// var _ proto.Unmarshaler = (*ID)(nil)
|
||||
var _ json.Marshaler = (*ID)(nil)
|
||||
var _ json.Unmarshaler = (*ID)(nil)
|
||||
|
||||
var _ encoding.BinaryMarshaler = (*ID)(nil)
|
||||
var _ encoding.BinaryUnmarshaler = (*ID)(nil)
|
||||
var _ encoding.TextMarshaler = (*ID)(nil)
|
||||
var _ encoding.TextUnmarshaler = (*ID)(nil)
|
||||
|
||||
func (id ID) Marshal() ([]byte, error) {
|
||||
return []byte(id), nil
|
||||
}
|
||||
|
||||
// MarshalBinary returns the byte representation of the peer ID.
|
||||
func (id ID) MarshalBinary() ([]byte, error) {
|
||||
return id.Marshal()
|
||||
}
|
||||
|
||||
func (id ID) MarshalTo(data []byte) (n int, err error) {
|
||||
return copy(data, []byte(id)), nil
|
||||
}
|
||||
|
||||
func (id *ID) Unmarshal(data []byte) (err error) {
|
||||
*id, err = IDFromBytes(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalBinary sets the ID from its binary representation.
|
||||
func (id *ID) UnmarshalBinary(data []byte) error {
|
||||
return id.Unmarshal(data)
|
||||
}
|
||||
|
||||
func (id ID) Size() int {
|
||||
return len([]byte(id))
|
||||
}
|
||||
|
||||
func (id ID) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(Encode(id))
|
||||
}
|
||||
|
||||
func (id *ID) UnmarshalJSON(data []byte) (err error) {
|
||||
var v string
|
||||
if err = json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
*id, err = Decode(v)
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalText returns the text encoding of the ID.
|
||||
func (id ID) MarshalText() ([]byte, error) {
|
||||
return []byte(Encode(id)), nil
|
||||
}
|
||||
|
||||
// UnmarshalText restores the ID from its text encoding.
|
||||
func (id *ID) UnmarshalText(data []byte) error {
|
||||
pid, err := Decode(string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*id = pid
|
||||
return nil
|
||||
}
|
||||
253
vendor/github.com/libp2p/go-libp2p/core/peer/record.go
generated
vendored
Normal file
253
vendor/github.com/libp2p/go-libp2p/core/peer/record.go
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
package peer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
"github.com/libp2p/go-libp2p/core/peer/pb"
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
//go:generate protoc --proto_path=$PWD:$PWD/../.. --go_out=. --go_opt=Mpb/peer_record.proto=./pb pb/peer_record.proto
|
||||
|
||||
var _ record.Record = (*PeerRecord)(nil)
|
||||
|
||||
func init() {
|
||||
record.RegisterType(&PeerRecord{})
|
||||
}
|
||||
|
||||
// PeerRecordEnvelopeDomain is the domain string used for peer records contained in an Envelope.
|
||||
const PeerRecordEnvelopeDomain = "libp2p-peer-record"
|
||||
|
||||
// PeerRecordEnvelopePayloadType is the type hint used to identify peer records in an Envelope.
|
||||
// Defined in https://github.com/multiformats/multicodec/blob/master/table.csv
|
||||
// with name "libp2p-peer-record".
|
||||
var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01}
|
||||
|
||||
// PeerRecord contains information that is broadly useful to share with other peers,
|
||||
// either through a direct exchange (as in the libp2p identify protocol), or through
|
||||
// a Peer Routing provider, such as a DHT.
|
||||
//
|
||||
// Currently, a PeerRecord contains the public listen addresses for a peer, but this
|
||||
// is expected to expand to include other information in the future.
|
||||
//
|
||||
// PeerRecords are ordered in time by their Seq field. Newer PeerRecords must have
|
||||
// greater Seq values than older records. The NewPeerRecord function will create
|
||||
// a PeerRecord with a timestamp-based Seq value. The other PeerRecord fields should
|
||||
// be set by the caller:
|
||||
//
|
||||
// rec := peer.NewPeerRecord()
|
||||
// rec.PeerID = aPeerID
|
||||
// rec.Addrs = someAddrs
|
||||
//
|
||||
// Alternatively, you can construct a PeerRecord struct directly and use the TimestampSeq
|
||||
// helper to set the Seq field:
|
||||
//
|
||||
// rec := peer.PeerRecord{PeerID: aPeerID, Addrs: someAddrs, Seq: peer.TimestampSeq()}
|
||||
//
|
||||
// Failing to set the Seq field will not result in an error, however, a PeerRecord with a
|
||||
// Seq value of zero may be ignored or rejected by other peers.
|
||||
//
|
||||
// PeerRecords are intended to be shared with other peers inside a signed
|
||||
// routing.Envelope, and PeerRecord implements the routing.Record interface
|
||||
// to facilitate this.
|
||||
//
|
||||
// To share a PeerRecord, first call Sign to wrap the record in an Envelope
|
||||
// and sign it with the local peer's private key:
|
||||
//
|
||||
// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}
|
||||
// envelope, err := rec.Sign(myPrivateKey)
|
||||
//
|
||||
// The resulting record.Envelope can be marshalled to a []byte and shared
|
||||
// publicly. As a convenience, the MarshalSigned method will produce the
|
||||
// Envelope and marshal it to a []byte in one go:
|
||||
//
|
||||
// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs}
|
||||
// recordBytes, err := rec.MarshalSigned(myPrivateKey)
|
||||
//
|
||||
// To validate and unmarshal a signed PeerRecord from a remote peer,
|
||||
// "consume" the containing envelope, which will return both the
|
||||
// routing.Envelope and the inner Record. The Record must be cast to
|
||||
// a PeerRecord pointer before use:
|
||||
//
|
||||
// envelope, untypedRecord, err := ConsumeEnvelope(envelopeBytes, PeerRecordEnvelopeDomain)
|
||||
// if err != nil {
|
||||
// handleError(err)
|
||||
// return
|
||||
// }
|
||||
// peerRec := untypedRecord.(*PeerRecord)
|
||||
type PeerRecord struct {
|
||||
// PeerID is the ID of the peer this record pertains to.
|
||||
PeerID ID
|
||||
|
||||
// Addrs contains the public addresses of the peer this record pertains to.
|
||||
Addrs []ma.Multiaddr
|
||||
|
||||
// Seq is a monotonically-increasing sequence counter that's used to order
|
||||
// PeerRecords in time. The interval between Seq values is unspecified,
|
||||
// but newer PeerRecords MUST have a greater Seq value than older records
|
||||
// for the same peer.
|
||||
Seq uint64
|
||||
}
|
||||
|
||||
// NewPeerRecord returns a PeerRecord with a timestamp-based sequence number.
|
||||
// The returned record is otherwise empty and should be populated by the caller.
|
||||
func NewPeerRecord() *PeerRecord {
|
||||
return &PeerRecord{Seq: TimestampSeq()}
|
||||
}
|
||||
|
||||
// PeerRecordFromAddrInfo creates a PeerRecord from an AddrInfo struct.
|
||||
// The returned record will have a timestamp-based sequence number.
|
||||
func PeerRecordFromAddrInfo(info AddrInfo) *PeerRecord {
|
||||
rec := NewPeerRecord()
|
||||
rec.PeerID = info.ID
|
||||
rec.Addrs = info.Addrs
|
||||
return rec
|
||||
}
|
||||
|
||||
// PeerRecordFromProtobuf creates a PeerRecord from a protobuf PeerRecord
|
||||
// struct.
|
||||
func PeerRecordFromProtobuf(msg *pb.PeerRecord) (*PeerRecord, error) {
|
||||
record := &PeerRecord{}
|
||||
|
||||
var id ID
|
||||
if err := id.UnmarshalBinary(msg.PeerId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record.PeerID = id
|
||||
record.Addrs = addrsFromProtobuf(msg.Addresses)
|
||||
record.Seq = msg.Seq
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
var (
|
||||
lastTimestampMu sync.Mutex
|
||||
lastTimestamp uint64
|
||||
)
|
||||
|
||||
// TimestampSeq is a helper to generate a timestamp-based sequence number for a PeerRecord.
|
||||
func TimestampSeq() uint64 {
|
||||
now := uint64(time.Now().UnixNano())
|
||||
lastTimestampMu.Lock()
|
||||
defer lastTimestampMu.Unlock()
|
||||
// Not all clocks are strictly increasing, but we need these sequence numbers to be strictly
|
||||
// increasing.
|
||||
if now <= lastTimestamp {
|
||||
now = lastTimestamp + 1
|
||||
}
|
||||
lastTimestamp = now
|
||||
return now
|
||||
}
|
||||
|
||||
// Domain is used when signing and validating PeerRecords contained in Envelopes.
|
||||
// It is constant for all PeerRecord instances.
|
||||
func (r *PeerRecord) Domain() string {
|
||||
return PeerRecordEnvelopeDomain
|
||||
}
|
||||
|
||||
// Codec is a binary identifier for the PeerRecord type. It is constant for all PeerRecord instances.
|
||||
func (r *PeerRecord) Codec() []byte {
|
||||
return PeerRecordEnvelopePayloadType
|
||||
}
|
||||
|
||||
// UnmarshalRecord parses a PeerRecord from a byte slice.
|
||||
// This method is called automatically when consuming a record.Envelope
|
||||
// whose PayloadType indicates that it contains a PeerRecord.
|
||||
// It is generally not necessary or recommended to call this method directly.
|
||||
func (r *PeerRecord) UnmarshalRecord(bytes []byte) (err error) {
|
||||
if r == nil {
|
||||
return fmt.Errorf("cannot unmarshal PeerRecord to nil receiver")
|
||||
}
|
||||
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p peer record unmarshal") }()
|
||||
|
||||
var msg pb.PeerRecord
|
||||
err = proto.Unmarshal(bytes, &msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rPtr, err := PeerRecordFromProtobuf(&msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = *rPtr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalRecord serializes a PeerRecord to a byte slice.
|
||||
// This method is called automatically when constructing a routing.Envelope
|
||||
// using Seal or PeerRecord.Sign.
|
||||
func (r *PeerRecord) MarshalRecord() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p peer record marshal") }()
|
||||
|
||||
msg, err := r.ToProtobuf()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Marshal(msg)
|
||||
}
|
||||
|
||||
// Equal returns true if the other PeerRecord is identical to this one.
|
||||
func (r *PeerRecord) Equal(other *PeerRecord) bool {
|
||||
if other == nil {
|
||||
return r == nil
|
||||
}
|
||||
if r.PeerID != other.PeerID {
|
||||
return false
|
||||
}
|
||||
if r.Seq != other.Seq {
|
||||
return false
|
||||
}
|
||||
if len(r.Addrs) != len(other.Addrs) {
|
||||
return false
|
||||
}
|
||||
for i := range r.Addrs {
|
||||
if !r.Addrs[i].Equal(other.Addrs[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ToProtobuf returns the equivalent Protocol Buffer struct object of a PeerRecord.
|
||||
func (r *PeerRecord) ToProtobuf() (*pb.PeerRecord, error) {
|
||||
idBytes, err := r.PeerID.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.PeerRecord{
|
||||
PeerId: idBytes,
|
||||
Addresses: addrsToProtobuf(r.Addrs),
|
||||
Seq: r.Seq,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func addrsFromProtobuf(addrs []*pb.PeerRecord_AddressInfo) []ma.Multiaddr {
|
||||
out := make([]ma.Multiaddr, 0, len(addrs))
|
||||
for _, addr := range addrs {
|
||||
a, err := ma.NewMultiaddrBytes(addr.Multiaddr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
out = append(out, a)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func addrsToProtobuf(addrs []ma.Multiaddr) []*pb.PeerRecord_AddressInfo {
|
||||
out := make([]*pb.PeerRecord_AddressInfo, 0, len(addrs))
|
||||
for _, addr := range addrs {
|
||||
out = append(out, &pb.PeerRecord_AddressInfo{Multiaddr: addr.Bytes()})
|
||||
}
|
||||
return out
|
||||
}
|
||||
14
vendor/github.com/libp2p/go-libp2p/core/peerstore/helpers.go
generated
vendored
Normal file
14
vendor/github.com/libp2p/go-libp2p/core/peerstore/helpers.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
package peerstore
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// AddrInfos returns an AddrInfo for each specified peer ID, in-order.
|
||||
func AddrInfos(ps Peerstore, peers []peer.ID) []peer.AddrInfo {
|
||||
pi := make([]peer.AddrInfo, len(peers))
|
||||
for i, p := range peers {
|
||||
pi[i] = ps.PeerInfo(p)
|
||||
}
|
||||
return pi
|
||||
}
|
||||
250
vendor/github.com/libp2p/go-libp2p/core/peerstore/peerstore.go
generated
vendored
Normal file
250
vendor/github.com/libp2p/go-libp2p/core/peerstore/peerstore.go
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
// Package peerstore provides types and interfaces for local storage of address information,
|
||||
// metadata, and public key material about libp2p peers.
|
||||
package peerstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
ic "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
var ErrNotFound = errors.New("item not found")
|
||||
|
||||
var (
|
||||
// AddressTTL is the expiration time of addresses.
|
||||
AddressTTL = time.Hour
|
||||
|
||||
// TempAddrTTL is the ttl used for a short-lived address.
|
||||
TempAddrTTL = time.Minute * 2
|
||||
|
||||
// RecentlyConnectedAddrTTL is used when we recently connected to a peer.
|
||||
// It means that we are reasonably certain of the peer's address.
|
||||
RecentlyConnectedAddrTTL = time.Minute * 30
|
||||
|
||||
// OwnObservedAddrTTL is used for our own external addresses observed by peers.
|
||||
OwnObservedAddrTTL = time.Minute * 30
|
||||
)
|
||||
|
||||
// Permanent TTLs (distinct so we can distinguish between them, constant as they
|
||||
// are, in fact, permanent)
|
||||
const (
|
||||
// PermanentAddrTTL is the ttl for a "permanent address" (e.g. bootstrap nodes).
|
||||
PermanentAddrTTL = math.MaxInt64 - iota
|
||||
|
||||
// ConnectedAddrTTL is the ttl used for the addresses of a peer to whom
|
||||
// we're connected directly. This is basically permanent, as we will
|
||||
// clear them + re-add under a TempAddrTTL after disconnecting.
|
||||
ConnectedAddrTTL
|
||||
)
|
||||
|
||||
// Peerstore provides a thread-safe store of Peer related
|
||||
// information.
|
||||
type Peerstore interface {
|
||||
io.Closer
|
||||
|
||||
AddrBook
|
||||
KeyBook
|
||||
PeerMetadata
|
||||
Metrics
|
||||
ProtoBook
|
||||
|
||||
// PeerInfo returns a peer.PeerInfo struct for given peer.ID.
|
||||
// This is a small slice of the information Peerstore has on
|
||||
// that peer, useful to other services.
|
||||
PeerInfo(peer.ID) peer.AddrInfo
|
||||
|
||||
// Peers returns all the peer IDs stored across all inner stores.
|
||||
Peers() peer.IDSlice
|
||||
}
|
||||
|
||||
// PeerMetadata can handle values of any type. Serializing values is
|
||||
// up to the implementation. Dynamic type introspection may not be
|
||||
// supported, in which case explicitly enlisting types in the
|
||||
// serializer may be required.
|
||||
//
|
||||
// Refer to the docs of the underlying implementation for more
|
||||
// information.
|
||||
type PeerMetadata interface {
|
||||
// Get / Put is a simple registry for other peer-related key/value pairs.
|
||||
// If we find something we use often, it should become its own set of
|
||||
// methods. This is a last resort.
|
||||
Get(p peer.ID, key string) (interface{}, error)
|
||||
Put(p peer.ID, key string, val interface{}) error
|
||||
|
||||
// RemovePeer removes all values stored for a peer.
|
||||
RemovePeer(peer.ID)
|
||||
}
|
||||
|
||||
// AddrBook holds the multiaddrs of peers.
|
||||
type AddrBook interface {
|
||||
// AddAddr calls AddAddrs(p, []ma.Multiaddr{addr}, ttl)
|
||||
AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)
|
||||
|
||||
// AddAddrs gives this AddrBook addresses to use, with a given ttl
|
||||
// (time-to-live), after which the address is no longer valid.
|
||||
// If the manager has a longer TTL, the operation is a no-op for that address
|
||||
AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)
|
||||
|
||||
// SetAddr calls mgr.SetAddrs(p, addr, ttl)
|
||||
SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)
|
||||
|
||||
// SetAddrs sets the ttl on addresses. This clears any TTL there previously.
|
||||
// This is used when we receive the best estimate of the validity of an address.
|
||||
SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)
|
||||
|
||||
// UpdateAddrs updates the addresses associated with the given peer that have
|
||||
// the given oldTTL to have the given newTTL.
|
||||
UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration)
|
||||
|
||||
// Addrs returns all known (and valid) addresses for a given peer.
|
||||
Addrs(p peer.ID) []ma.Multiaddr
|
||||
|
||||
// AddrStream returns a channel that gets all addresses for a given
|
||||
// peer sent on it. If new addresses are added after the call is made
|
||||
// they will be sent along through the channel as well.
|
||||
AddrStream(context.Context, peer.ID) <-chan ma.Multiaddr
|
||||
|
||||
// ClearAddresses removes all previously stored addresses.
|
||||
ClearAddrs(p peer.ID)
|
||||
|
||||
// PeersWithAddrs returns all the peer IDs stored in the AddrBook.
|
||||
PeersWithAddrs() peer.IDSlice
|
||||
}
|
||||
|
||||
// CertifiedAddrBook manages "self-certified" addresses for remote peers.
|
||||
// Self-certified addresses are contained in peer.PeerRecords
|
||||
// which are wrapped in a record.Envelope and signed by the peer
|
||||
// to whom they belong.
|
||||
//
|
||||
// Certified addresses (CA) are generally more secure than uncertified
|
||||
// addresses (UA). Consequently, CAs beat and displace UAs. When the
|
||||
// peerstore learns CAs for a peer, it will reject UAs for the same peer
|
||||
// (as long as the former haven't expired).
|
||||
// Furthermore, peer records act like sequenced snapshots of CAs. Therefore,
|
||||
// processing a peer record that's newer than the last one seen overwrites
|
||||
// all addresses with the incoming ones.
|
||||
//
|
||||
// This interface is most useful when combined with AddrBook.
|
||||
// To test whether a given AddrBook / Peerstore implementation supports
|
||||
// certified addresses, callers should use the GetCertifiedAddrBook helper or
|
||||
// type-assert on the CertifiedAddrBook interface:
|
||||
//
|
||||
// if cab, ok := aPeerstore.(CertifiedAddrBook); ok {
|
||||
// cab.ConsumePeerRecord(signedPeerRecord, aTTL)
|
||||
// }
|
||||
type CertifiedAddrBook interface {
|
||||
// ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in
|
||||
// a record.Envelope), which will expire after the given TTL.
|
||||
//
|
||||
// The 'accepted' return value indicates that the record was successfully processed
|
||||
// and integrated into the CertifiedAddrBook state. If 'accepted' is false but no
|
||||
// error is returned, it means that the record was ignored, most likely because
|
||||
// a newer record exists for the same peer.
|
||||
//
|
||||
// Signed records added via this method will be stored without
|
||||
// alteration as long as the address TTLs remain valid. The Envelopes
|
||||
// containing the PeerRecords can be retrieved by calling GetPeerRecord(peerID).
|
||||
//
|
||||
// If the signed PeerRecord belongs to a peer that already has certified
|
||||
// addresses in the CertifiedAddrBook, the new addresses will replace the
|
||||
// older ones, if the new record has a higher sequence number than the
|
||||
// existing record. Attempting to add a peer record with a
|
||||
// sequence number that's <= an existing record for the same peer will not
|
||||
// result in an error, but the record will be ignored, and the 'accepted'
|
||||
// bool return value will be false.
|
||||
//
|
||||
// If the CertifiedAddrBook is also an AddrBook (which is most likely the case),
|
||||
// adding certified addresses for a peer will *replace* any
|
||||
// existing non-certified addresses for that peer, and only the certified
|
||||
// addresses will be returned from AddrBook.Addrs thereafter.
|
||||
//
|
||||
// Likewise, once certified addresses have been added for a given peer,
|
||||
// any non-certified addresses added via AddrBook.AddAddrs or
|
||||
// AddrBook.SetAddrs will be ignored. AddrBook.SetAddrs may still be used
|
||||
// to update the TTL of certified addresses that have previously been
|
||||
// added via ConsumePeerRecord.
|
||||
ConsumePeerRecord(s *record.Envelope, ttl time.Duration) (accepted bool, err error)
|
||||
|
||||
// GetPeerRecord returns an Envelope containing a PeerRecord for the
|
||||
// given peer id, if one exists.
|
||||
// Returns nil if no signed PeerRecord exists for the peer.
|
||||
GetPeerRecord(p peer.ID) *record.Envelope
|
||||
}
|
||||
|
||||
// GetCertifiedAddrBook is a helper to "upcast" an AddrBook to a
|
||||
// CertifiedAddrBook by using type assertion. If the given AddrBook
|
||||
// is also a CertifiedAddrBook, it will be returned, and the ok return
|
||||
// value will be true. Returns (nil, false) if the AddrBook is not a
|
||||
// CertifiedAddrBook.
|
||||
//
|
||||
// Note that since Peerstore embeds the AddrBook interface, you can also
|
||||
// call GetCertifiedAddrBook(myPeerstore).
|
||||
func GetCertifiedAddrBook(ab AddrBook) (cab CertifiedAddrBook, ok bool) {
|
||||
cab, ok = ab.(CertifiedAddrBook)
|
||||
return cab, ok
|
||||
}
|
||||
|
||||
// KeyBook tracks the keys of Peers.
|
||||
type KeyBook interface {
|
||||
// PubKey stores the public key of a peer.
|
||||
PubKey(peer.ID) ic.PubKey
|
||||
|
||||
// AddPubKey stores the public key of a peer.
|
||||
AddPubKey(peer.ID, ic.PubKey) error
|
||||
|
||||
// PrivKey returns the private key of a peer, if known. Generally this might only be our own
|
||||
// private key, see
|
||||
// https://discuss.libp2p.io/t/what-is-the-purpose-of-having-map-peer-id-privatekey-in-peerstore/74.
|
||||
PrivKey(peer.ID) ic.PrivKey
|
||||
|
||||
// AddPrivKey stores the private key of a peer.
|
||||
AddPrivKey(peer.ID, ic.PrivKey) error
|
||||
|
||||
// PeersWithKeys returns all the peer IDs stored in the KeyBook.
|
||||
PeersWithKeys() peer.IDSlice
|
||||
|
||||
// RemovePeer removes all keys associated with a peer.
|
||||
RemovePeer(peer.ID)
|
||||
}
|
||||
|
||||
// Metrics tracks metrics across a set of peers.
|
||||
type Metrics interface {
|
||||
// RecordLatency records a new latency measurement
|
||||
RecordLatency(peer.ID, time.Duration)
|
||||
|
||||
// LatencyEWMA returns an exponentially-weighted moving avg.
|
||||
// of all measurements of a peer's latency.
|
||||
LatencyEWMA(peer.ID) time.Duration
|
||||
|
||||
// RemovePeer removes all metrics stored for a peer.
|
||||
RemovePeer(peer.ID)
|
||||
}
|
||||
|
||||
// ProtoBook tracks the protocols supported by peers.
|
||||
type ProtoBook interface {
|
||||
GetProtocols(peer.ID) ([]protocol.ID, error)
|
||||
AddProtocols(peer.ID, ...protocol.ID) error
|
||||
SetProtocols(peer.ID, ...protocol.ID) error
|
||||
RemoveProtocols(peer.ID, ...protocol.ID) error
|
||||
|
||||
// SupportsProtocols returns the set of protocols the peer supports from among the given protocols.
|
||||
// If the returned error is not nil, the result is indeterminate.
|
||||
SupportsProtocols(peer.ID, ...protocol.ID) ([]protocol.ID, error)
|
||||
|
||||
// FirstSupportedProtocol returns the first protocol that the peer supports among the given protocols.
|
||||
// If the peer does not support any of the given protocols, this function will return an empty protocol.ID and a nil error.
|
||||
// If the returned error is not nil, the result is indeterminate.
|
||||
FirstSupportedProtocol(peer.ID, ...protocol.ID) (protocol.ID, error)
|
||||
|
||||
// RemovePeer removes all protocols associated with a peer.
|
||||
RemovePeer(peer.ID)
|
||||
}
|
||||
66
vendor/github.com/libp2p/go-libp2p/core/pnet/codec.go
generated
vendored
Normal file
66
vendor/github.com/libp2p/go-libp2p/core/pnet/codec.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
package pnet
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
pathPSKv1 = []byte("/key/swarm/psk/1.0.0/")
|
||||
pathBin = "/bin/"
|
||||
pathBase16 = "/base16/"
|
||||
pathBase64 = "/base64/"
|
||||
)
|
||||
|
||||
func readHeader(r *bufio.Reader) ([]byte, error) {
|
||||
header, err := r.ReadBytes('\n')
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes.TrimRight(header, "\r\n"), nil
|
||||
}
|
||||
|
||||
func expectHeader(r *bufio.Reader, expected []byte) error {
|
||||
header, err := readHeader(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !bytes.Equal(header, expected) {
|
||||
return fmt.Errorf("expected file header %s, got: %s", expected, header)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecodeV1PSK reads a Multicodec encoded V1 PSK.
|
||||
func DecodeV1PSK(in io.Reader) (PSK, error) {
|
||||
reader := bufio.NewReader(in)
|
||||
if err := expectHeader(reader, pathPSKv1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
header, err := readHeader(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var decoder io.Reader
|
||||
switch string(header) {
|
||||
case pathBase16:
|
||||
decoder = hex.NewDecoder(reader)
|
||||
case pathBase64:
|
||||
decoder = base64.NewDecoder(base64.StdEncoding, reader)
|
||||
case pathBin:
|
||||
decoder = reader
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown encoding: %s", header)
|
||||
}
|
||||
out := make([]byte, 32)
|
||||
if _, err = io.ReadFull(decoder, out[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
19
vendor/github.com/libp2p/go-libp2p/core/pnet/env.go
generated
vendored
Normal file
19
vendor/github.com/libp2p/go-libp2p/core/pnet/env.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package pnet
|
||||
|
||||
import "os"
|
||||
|
||||
// EnvKey defines environment variable name for forcing usage of PNet in libp2p
|
||||
// When environment variable of this name is set to "1" the ForcePrivateNetwork
|
||||
// variable will be set to true.
|
||||
const EnvKey = "LIBP2P_FORCE_PNET"
|
||||
|
||||
// ForcePrivateNetwork is boolean variable that forces usage of PNet in libp2p
|
||||
// Setting this variable to true or setting LIBP2P_FORCE_PNET environment variable
|
||||
// to true will make libp2p to require private network protector.
|
||||
// If no network protector is provided and this variable is set to true libp2p will
|
||||
// refuse to connect.
|
||||
var ForcePrivateNetwork = false
|
||||
|
||||
func init() {
|
||||
ForcePrivateNetwork = os.Getenv(EnvKey) == "1"
|
||||
}
|
||||
34
vendor/github.com/libp2p/go-libp2p/core/pnet/error.go
generated
vendored
Normal file
34
vendor/github.com/libp2p/go-libp2p/core/pnet/error.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package pnet
|
||||
|
||||
// ErrNotInPrivateNetwork is an error that should be returned by libp2p when it
|
||||
// tries to dial with ForcePrivateNetwork set and no PNet Protector
|
||||
var ErrNotInPrivateNetwork = NewError("private network was not configured but" +
|
||||
" is enforced by the environment")
|
||||
|
||||
// Error is error type for ease of detecting PNet errors
|
||||
type Error interface {
|
||||
IsPNetError() bool
|
||||
}
|
||||
|
||||
// NewError creates new Error
|
||||
func NewError(err string) error {
|
||||
return pnetErr("privnet: " + err)
|
||||
}
|
||||
|
||||
// IsPNetError checks if given error is PNet Error
|
||||
func IsPNetError(err error) bool {
|
||||
v, ok := err.(Error)
|
||||
return ok && v.IsPNetError()
|
||||
}
|
||||
|
||||
type pnetErr string
|
||||
|
||||
var _ Error = (*pnetErr)(nil)
|
||||
|
||||
func (p pnetErr) Error() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (pnetErr) IsPNetError() bool {
|
||||
return true
|
||||
}
|
||||
7
vendor/github.com/libp2p/go-libp2p/core/pnet/protector.go
generated
vendored
Normal file
7
vendor/github.com/libp2p/go-libp2p/core/pnet/protector.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Package pnet provides interfaces for private networking in libp2p.
|
||||
package pnet
|
||||
|
||||
// A PSK enables private network implementation to be transparent in libp2p.
|
||||
// It is used to ensure that peers can only establish connections to other peers
|
||||
// that are using the same PSK.
|
||||
type PSK []byte
|
||||
29
vendor/github.com/libp2p/go-libp2p/core/protocol/id.go
generated
vendored
Normal file
29
vendor/github.com/libp2p/go-libp2p/core/protocol/id.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
package protocol
|
||||
|
||||
// ID is an identifier used to write protocol headers in streams.
|
||||
type ID string
|
||||
|
||||
// These are reserved protocol.IDs.
|
||||
const (
|
||||
TestingID ID = "/p2p/_testing"
|
||||
)
|
||||
|
||||
// ConvertFromStrings is a convenience function that takes a slice of strings and
|
||||
// converts it to a slice of protocol.ID.
|
||||
func ConvertFromStrings(ids []string) (res []ID) {
|
||||
res = make([]ID, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
res = append(res, ID(id))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// ConvertToStrings is a convenience function that takes a slice of protocol.ID and
|
||||
// converts it to a slice of strings.
|
||||
func ConvertToStrings(ids []ID) (res []string) {
|
||||
res = make([]string, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
res = append(res, string(id))
|
||||
}
|
||||
return res
|
||||
}
|
||||
73
vendor/github.com/libp2p/go-libp2p/core/protocol/switch.go
generated
vendored
Normal file
73
vendor/github.com/libp2p/go-libp2p/core/protocol/switch.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Package protocol provides core interfaces for protocol routing and negotiation in libp2p.
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/multiformats/go-multistream"
|
||||
)
|
||||
|
||||
// HandlerFunc is a user-provided function used by the Router to
|
||||
// handle a protocol/stream.
|
||||
//
|
||||
// Will be invoked with the protocol ID string as the first argument,
|
||||
// which may differ from the ID used for registration if the handler
|
||||
// was registered using a match function.
|
||||
type HandlerFunc = multistream.HandlerFunc[ID]
|
||||
|
||||
// Router is an interface that allows users to add and remove protocol handlers,
|
||||
// which will be invoked when incoming stream requests for registered protocols
|
||||
// are accepted.
|
||||
//
|
||||
// Upon receiving an incoming stream request, the Router will check all registered
|
||||
// protocol handlers to determine which (if any) is capable of handling the stream.
|
||||
// The handlers are checked in order of registration; if multiple handlers are
|
||||
// eligible, only the first to be registered will be invoked.
|
||||
type Router interface {
|
||||
|
||||
// AddHandler registers the given handler to be invoked for
|
||||
// an exact literal match of the given protocol ID string.
|
||||
AddHandler(protocol ID, handler HandlerFunc)
|
||||
|
||||
// AddHandlerWithFunc registers the given handler to be invoked
|
||||
// when the provided match function returns true.
|
||||
//
|
||||
// The match function will be invoked with an incoming protocol
|
||||
// ID string, and should return true if the handler supports
|
||||
// the protocol. Note that the protocol ID argument is not
|
||||
// used for matching; if you want to match the protocol ID
|
||||
// string exactly, you must check for it in your match function.
|
||||
AddHandlerWithFunc(protocol ID, match func(ID) bool, handler HandlerFunc)
|
||||
|
||||
// RemoveHandler removes the registered handler (if any) for the
|
||||
// given protocol ID string.
|
||||
RemoveHandler(protocol ID)
|
||||
|
||||
// Protocols returns a list of all registered protocol ID strings.
|
||||
// Note that the Router may be able to handle protocol IDs not
|
||||
// included in this list if handlers were added with match functions
|
||||
// using AddHandlerWithFunc.
|
||||
Protocols() []ID
|
||||
}
|
||||
|
||||
// Negotiator is a component capable of reaching agreement over what protocols
|
||||
// to use for inbound streams of communication.
|
||||
type Negotiator interface {
|
||||
// Negotiate will return the registered protocol handler to use for a given
|
||||
// inbound stream, returning after the protocol has been determined and the
|
||||
// Negotiator has finished using the stream for negotiation. Returns an
|
||||
// error if negotiation fails.
|
||||
Negotiate(rwc io.ReadWriteCloser) (ID, HandlerFunc, error)
|
||||
|
||||
// Handle calls Negotiate to determine which protocol handler to use for an
|
||||
// inbound stream, then invokes the protocol handler function, passing it
|
||||
// the protocol ID and the stream. Returns an error if negotiation fails.
|
||||
Handle(rwc io.ReadWriteCloser) error
|
||||
}
|
||||
|
||||
// Switch is the component responsible for "dispatching" incoming stream requests to
|
||||
// their corresponding stream handlers. It is both a Negotiator and a Router.
|
||||
type Switch interface {
|
||||
Router
|
||||
Negotiator
|
||||
}
|
||||
296
vendor/github.com/libp2p/go-libp2p/core/record/envelope.go
generated
vendored
Normal file
296
vendor/github.com/libp2p/go-libp2p/core/record/envelope.go
generated
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
"github.com/libp2p/go-libp2p/core/record/pb"
|
||||
|
||||
pool "github.com/libp2p/go-buffer-pool"
|
||||
|
||||
"github.com/multiformats/go-varint"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
//go:generate protoc --proto_path=$PWD:$PWD/../.. --go_out=. --go_opt=Mpb/envelope.proto=./pb pb/envelope.proto
|
||||
|
||||
// Envelope contains an arbitrary []byte payload, signed by a libp2p peer.
|
||||
//
|
||||
// Envelopes are signed in the context of a particular "domain", which is a
|
||||
// string specified when creating and verifying the envelope. You must know the
|
||||
// domain string used to produce the envelope in order to verify the signature
|
||||
// and access the payload.
|
||||
type Envelope struct {
|
||||
// The public key that can be used to verify the signature and derive the peer id of the signer.
|
||||
PublicKey crypto.PubKey
|
||||
|
||||
// A binary identifier that indicates what kind of data is contained in the payload.
|
||||
// TODO(yusef): enforce multicodec prefix
|
||||
PayloadType []byte
|
||||
|
||||
// The envelope payload.
|
||||
RawPayload []byte
|
||||
|
||||
// The signature of the domain string :: type hint :: payload.
|
||||
signature []byte
|
||||
|
||||
// the unmarshalled payload as a Record, cached on first access via the Record accessor method
|
||||
cached Record
|
||||
unmarshalError error
|
||||
unmarshalOnce sync.Once
|
||||
}
|
||||
|
||||
var ErrEmptyDomain = errors.New("envelope domain must not be empty")
|
||||
var ErrEmptyPayloadType = errors.New("payloadType must not be empty")
|
||||
var ErrInvalidSignature = errors.New("invalid signature or incorrect domain")
|
||||
|
||||
// Seal marshals the given Record, places the marshaled bytes inside an Envelope,
|
||||
// and signs with the given private key.
|
||||
func Seal(rec Record, privateKey crypto.PrivKey) (*Envelope, error) {
|
||||
payload, err := rec.MarshalRecord()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshaling record: %v", err)
|
||||
}
|
||||
|
||||
domain := rec.Domain()
|
||||
payloadType := rec.Codec()
|
||||
if domain == "" {
|
||||
return nil, ErrEmptyDomain
|
||||
}
|
||||
|
||||
if len(payloadType) == 0 {
|
||||
return nil, ErrEmptyPayloadType
|
||||
}
|
||||
|
||||
unsigned, err := makeUnsigned(domain, payloadType, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer pool.Put(unsigned)
|
||||
|
||||
sig, err := privateKey.Sign(unsigned)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Envelope{
|
||||
PublicKey: privateKey.GetPublic(),
|
||||
PayloadType: payloadType,
|
||||
RawPayload: payload,
|
||||
signature: sig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ConsumeEnvelope unmarshals a serialized Envelope and validates its
|
||||
// signature using the provided 'domain' string. If validation fails, an error
|
||||
// is returned, along with the unmarshalled envelope, so it can be inspected.
|
||||
//
|
||||
// On success, ConsumeEnvelope returns the Envelope itself, as well as the inner payload,
|
||||
// unmarshalled into a concrete Record type. The actual type of the returned Record depends
|
||||
// on what has been registered for the Envelope's PayloadType (see RegisterType for details).
|
||||
//
|
||||
// You can type assert on the returned Record to convert it to an instance of the concrete
|
||||
// Record type:
|
||||
//
|
||||
// envelope, rec, err := ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain)
|
||||
// if err != nil {
|
||||
// handleError(envelope, err) // envelope may be non-nil, even if errors occur!
|
||||
// return
|
||||
// }
|
||||
// peerRec, ok := rec.(*peer.PeerRecord)
|
||||
// if ok {
|
||||
// doSomethingWithPeerRecord(peerRec)
|
||||
// }
|
||||
//
|
||||
// If the Envelope signature is valid, but no Record type is registered for the Envelope's
|
||||
// PayloadType, ErrPayloadTypeNotRegistered will be returned, along with the Envelope and
|
||||
// a nil Record.
|
||||
func ConsumeEnvelope(data []byte, domain string) (envelope *Envelope, rec Record, err error) {
|
||||
e, err := UnmarshalEnvelope(data)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed when unmarshalling the envelope: %w", err)
|
||||
}
|
||||
|
||||
err = e.validate(domain)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to validate envelope: %w", err)
|
||||
}
|
||||
|
||||
rec, err = e.Record()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to unmarshal envelope payload: %w", err)
|
||||
}
|
||||
return e, rec, nil
|
||||
}
|
||||
|
||||
// ConsumeTypedEnvelope unmarshals a serialized Envelope and validates its
|
||||
// signature. If validation fails, an error is returned, along with the unmarshalled
|
||||
// envelope, so it can be inspected.
|
||||
//
|
||||
// Unlike ConsumeEnvelope, ConsumeTypedEnvelope does not try to automatically determine
|
||||
// the type of Record to unmarshal the Envelope's payload into. Instead, the caller provides
|
||||
// a destination Record instance, which will unmarshal the Envelope payload. It is the caller's
|
||||
// responsibility to determine whether the given Record type is able to unmarshal the payload
|
||||
// correctly.
|
||||
//
|
||||
// rec := &MyRecordType{}
|
||||
// envelope, err := ConsumeTypedEnvelope(envelopeBytes, rec)
|
||||
// if err != nil {
|
||||
// handleError(envelope, err)
|
||||
// }
|
||||
// doSomethingWithRecord(rec)
|
||||
//
|
||||
// Important: you MUST check the error value before using the returned Envelope. In some error
|
||||
// cases, including when the envelope signature is invalid, both the Envelope and an error will
|
||||
// be returned. This allows you to inspect the unmarshalled but invalid Envelope. As a result,
|
||||
// you must not assume that any non-nil Envelope returned from this function is valid.
|
||||
func ConsumeTypedEnvelope(data []byte, destRecord Record) (envelope *Envelope, err error) {
|
||||
e, err := UnmarshalEnvelope(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed when unmarshalling the envelope: %w", err)
|
||||
}
|
||||
|
||||
err = e.validate(destRecord.Domain())
|
||||
if err != nil {
|
||||
return e, fmt.Errorf("failed to validate envelope: %w", err)
|
||||
}
|
||||
|
||||
err = destRecord.UnmarshalRecord(e.RawPayload)
|
||||
if err != nil {
|
||||
return e, fmt.Errorf("failed to unmarshal envelope payload: %w", err)
|
||||
}
|
||||
e.cached = destRecord
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// UnmarshalEnvelope unmarshals a serialized Envelope protobuf message,
|
||||
// without validating its contents. Most users should use ConsumeEnvelope.
|
||||
func UnmarshalEnvelope(data []byte) (*Envelope, error) {
|
||||
var e pb.Envelope
|
||||
if err := proto.Unmarshal(data, &e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, err := crypto.PublicKeyFromProto(e.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Envelope{
|
||||
PublicKey: key,
|
||||
PayloadType: e.PayloadType,
|
||||
RawPayload: e.Payload,
|
||||
signature: e.Signature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Marshal returns a byte slice containing a serialized protobuf representation
|
||||
// of an Envelope.
|
||||
func (e *Envelope) Marshal() (res []byte, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p envelope marshal") }()
|
||||
key, err := crypto.PublicKeyToProto(e.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg := pb.Envelope{
|
||||
PublicKey: key,
|
||||
PayloadType: e.PayloadType,
|
||||
Payload: e.RawPayload,
|
||||
Signature: e.signature,
|
||||
}
|
||||
return proto.Marshal(&msg)
|
||||
}
|
||||
|
||||
// Equal returns true if the other Envelope has the same public key,
|
||||
// payload, payload type, and signature. This implies that they were also
|
||||
// created with the same domain string.
|
||||
func (e *Envelope) Equal(other *Envelope) bool {
|
||||
if other == nil {
|
||||
return e == nil
|
||||
}
|
||||
return e.PublicKey.Equals(other.PublicKey) &&
|
||||
bytes.Equal(e.PayloadType, other.PayloadType) &&
|
||||
bytes.Equal(e.signature, other.signature) &&
|
||||
bytes.Equal(e.RawPayload, other.RawPayload)
|
||||
}
|
||||
|
||||
// Record returns the Envelope's payload unmarshalled as a Record.
|
||||
// The concrete type of the returned Record depends on which Record
|
||||
// type was registered for the Envelope's PayloadType - see record.RegisterType.
|
||||
//
|
||||
// Once unmarshalled, the Record is cached for future access.
|
||||
func (e *Envelope) Record() (Record, error) {
|
||||
e.unmarshalOnce.Do(func() {
|
||||
if e.cached != nil {
|
||||
return
|
||||
}
|
||||
e.cached, e.unmarshalError = unmarshalRecordPayload(e.PayloadType, e.RawPayload)
|
||||
})
|
||||
return e.cached, e.unmarshalError
|
||||
}
|
||||
|
||||
// TypedRecord unmarshals the Envelope's payload to the given Record instance.
|
||||
// It is the caller's responsibility to ensure that the Record type is capable
|
||||
// of unmarshalling the Envelope payload. Callers can inspect the Envelope's
|
||||
// PayloadType field to determine the correct type of Record to use.
|
||||
//
|
||||
// This method will always unmarshal the Envelope payload even if a cached record
|
||||
// exists.
|
||||
func (e *Envelope) TypedRecord(dest Record) error {
|
||||
return dest.UnmarshalRecord(e.RawPayload)
|
||||
}
|
||||
|
||||
// validate returns nil if the envelope signature is valid for the given 'domain',
|
||||
// or an error if signature validation fails.
|
||||
func (e *Envelope) validate(domain string) error {
|
||||
unsigned, err := makeUnsigned(domain, e.PayloadType, e.RawPayload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer pool.Put(unsigned)
|
||||
|
||||
valid, err := e.PublicKey.Verify(unsigned, e.signature)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed while verifying signature: %w", err)
|
||||
}
|
||||
if !valid {
|
||||
return ErrInvalidSignature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeUnsigned is a helper function that prepares a buffer to sign or verify.
|
||||
// It returns a byte slice from a pool. The caller MUST return this slice to the
|
||||
// pool.
|
||||
func makeUnsigned(domain string, payloadType []byte, payload []byte) ([]byte, error) {
|
||||
var (
|
||||
fields = [][]byte{[]byte(domain), payloadType, payload}
|
||||
|
||||
// fields are prefixed with their length as an unsigned varint. we
|
||||
// compute the lengths before allocating the sig buffer, so we know how
|
||||
// much space to add for the lengths
|
||||
flen = make([][]byte, len(fields))
|
||||
size = 0
|
||||
)
|
||||
|
||||
for i, f := range fields {
|
||||
l := len(f)
|
||||
flen[i] = varint.ToUvarint(uint64(l))
|
||||
size += l + len(flen[i])
|
||||
}
|
||||
|
||||
b := pool.Get(size)
|
||||
|
||||
var s int
|
||||
for i, f := range fields {
|
||||
s += copy(b[s:], flen[i])
|
||||
s += copy(b[s:], f)
|
||||
}
|
||||
|
||||
return b[:s], nil
|
||||
}
|
||||
192
vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.pb.go
generated
vendored
Normal file
192
vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.pb.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: pb/envelope.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Envelope encloses a signed payload produced by a peer, along with the public
|
||||
// key of the keypair it was signed with so that it can be statelessly validated
|
||||
// by the receiver.
|
||||
//
|
||||
// The payload is prefixed with a byte string that determines the type, so it
|
||||
// can be deserialized deterministically. Often, this byte string is a
|
||||
// multicodec.
|
||||
type Envelope struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// public_key is the public key of the keypair the enclosed payload was
|
||||
// signed with.
|
||||
PublicKey *pb.PublicKey `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
// payload_type encodes the type of payload, so that it can be deserialized
|
||||
// deterministically.
|
||||
PayloadType []byte `protobuf:"bytes,2,opt,name=payload_type,json=payloadType,proto3" json:"payload_type,omitempty"`
|
||||
// payload is the actual payload carried inside this envelope.
|
||||
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
// signature is the signature produced by the private key corresponding to
|
||||
// the enclosed public key, over the payload, prefixing a domain string for
|
||||
// additional security.
|
||||
Signature []byte `protobuf:"bytes,5,opt,name=signature,proto3" json:"signature,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Envelope) Reset() {
|
||||
*x = Envelope{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_envelope_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Envelope) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Envelope) ProtoMessage() {}
|
||||
|
||||
func (x *Envelope) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_envelope_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Envelope.ProtoReflect.Descriptor instead.
|
||||
func (*Envelope) Descriptor() ([]byte, []int) {
|
||||
return file_pb_envelope_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Envelope) GetPublicKey() *pb.PublicKey {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Envelope) GetPayloadType() []byte {
|
||||
if x != nil {
|
||||
return x.PayloadType
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Envelope) GetPayload() []byte {
|
||||
if x != nil {
|
||||
return x.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Envelope) GetSignature() []byte {
|
||||
if x != nil {
|
||||
return x.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pb_envelope_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pb_envelope_proto_rawDesc = []byte{
|
||||
0x0a, 0x11, 0x70, 0x62, 0x2f, 0x65, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x12, 0x09, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x62, 0x1a, 0x1b,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x63,
|
||||
0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, 0x01, 0x0a, 0x08,
|
||||
0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63,
|
||||
0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
|
||||
0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a,
|
||||
0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pb_envelope_proto_rawDescOnce sync.Once
|
||||
file_pb_envelope_proto_rawDescData = file_pb_envelope_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pb_envelope_proto_rawDescGZIP() []byte {
|
||||
file_pb_envelope_proto_rawDescOnce.Do(func() {
|
||||
file_pb_envelope_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_envelope_proto_rawDescData)
|
||||
})
|
||||
return file_pb_envelope_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pb_envelope_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_pb_envelope_proto_goTypes = []interface{}{
|
||||
(*Envelope)(nil), // 0: record.pb.Envelope
|
||||
(*pb.PublicKey)(nil), // 1: crypto.pb.PublicKey
|
||||
}
|
||||
var file_pb_envelope_proto_depIdxs = []int32{
|
||||
1, // 0: record.pb.Envelope.public_key:type_name -> crypto.pb.PublicKey
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pb_envelope_proto_init() }
|
||||
func file_pb_envelope_proto_init() {
|
||||
if File_pb_envelope_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pb_envelope_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Envelope); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_pb_envelope_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pb_envelope_proto_goTypes,
|
||||
DependencyIndexes: file_pb_envelope_proto_depIdxs,
|
||||
MessageInfos: file_pb_envelope_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pb_envelope_proto = out.File
|
||||
file_pb_envelope_proto_rawDesc = nil
|
||||
file_pb_envelope_proto_goTypes = nil
|
||||
file_pb_envelope_proto_depIdxs = nil
|
||||
}
|
||||
30
vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.proto
generated
vendored
Normal file
30
vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.proto
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package record.pb;
|
||||
|
||||
import "core/crypto/pb/crypto.proto";
|
||||
|
||||
// Envelope encloses a signed payload produced by a peer, along with the public
|
||||
// key of the keypair it was signed with so that it can be statelessly validated
|
||||
// by the receiver.
|
||||
//
|
||||
// The payload is prefixed with a byte string that determines the type, so it
|
||||
// can be deserialized deterministically. Often, this byte string is a
|
||||
// multicodec.
|
||||
message Envelope {
|
||||
// public_key is the public key of the keypair the enclosed payload was
|
||||
// signed with.
|
||||
crypto.pb.PublicKey public_key = 1;
|
||||
|
||||
// payload_type encodes the type of payload, so that it can be deserialized
|
||||
// deterministically.
|
||||
bytes payload_type = 2;
|
||||
|
||||
// payload is the actual payload carried inside this envelope.
|
||||
bytes payload = 3;
|
||||
|
||||
// signature is the signature produced by the private key corresponding to
|
||||
// the enclosed public key, over the payload, prefixing a domain string for
|
||||
// additional security.
|
||||
bytes signature = 5;
|
||||
}
|
||||
105
vendor/github.com/libp2p/go-libp2p/core/record/record.go
generated
vendored
Normal file
105
vendor/github.com/libp2p/go-libp2p/core/record/record.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrPayloadTypeNotRegistered is returned from ConsumeEnvelope when the Envelope's
|
||||
// PayloadType does not match any registered Record types.
|
||||
ErrPayloadTypeNotRegistered = errors.New("payload type is not registered")
|
||||
|
||||
payloadTypeRegistry = make(map[string]reflect.Type)
|
||||
)
|
||||
|
||||
// Record represents a data type that can be used as the payload of an Envelope.
|
||||
// The Record interface defines the methods used to marshal and unmarshal a Record
|
||||
// type to a byte slice.
|
||||
//
|
||||
// Record types may be "registered" as the default for a given Envelope.PayloadType
|
||||
// using the RegisterType function. Once a Record type has been registered,
|
||||
// an instance of that type will be created and used to unmarshal the payload of
|
||||
// any Envelope with the registered PayloadType when the Envelope is opened using
|
||||
// the ConsumeEnvelope function.
|
||||
//
|
||||
// To use an unregistered Record type instead, use ConsumeTypedEnvelope and pass in
|
||||
// an instance of the Record type that you'd like the Envelope's payload to be
|
||||
// unmarshaled into.
|
||||
type Record interface {
|
||||
|
||||
// Domain is the "signature domain" used when signing and verifying a particular
|
||||
// Record type. The Domain string should be unique to your Record type, and all
|
||||
// instances of the Record type must have the same Domain string.
|
||||
Domain() string
|
||||
|
||||
// Codec is a binary identifier for this type of record, ideally a registered multicodec
|
||||
// (see https://github.com/multiformats/multicodec).
|
||||
// When a Record is put into an Envelope (see record.Seal), the Codec value will be used
|
||||
// as the Envelope's PayloadType. When the Envelope is later unsealed, the PayloadType
|
||||
// will be used to look up the correct Record type to unmarshal the Envelope payload into.
|
||||
Codec() []byte
|
||||
|
||||
// MarshalRecord converts a Record instance to a []byte, so that it can be used as an
|
||||
// Envelope payload.
|
||||
MarshalRecord() ([]byte, error)
|
||||
|
||||
// UnmarshalRecord unmarshals a []byte payload into an instance of a particular Record type.
|
||||
UnmarshalRecord([]byte) error
|
||||
}
|
||||
|
||||
// RegisterType associates a binary payload type identifier with a concrete
|
||||
// Record type. This is used to automatically unmarshal Record payloads from Envelopes
|
||||
// when using ConsumeEnvelope, and to automatically marshal Records and determine the
|
||||
// correct PayloadType when calling Seal.
|
||||
//
|
||||
// Callers must provide an instance of the record type to be registered, which must be
|
||||
// a pointer type. Registration should be done in the init function of the package
|
||||
// where the Record type is defined:
|
||||
//
|
||||
// package hello_record
|
||||
// import record "github.com/libp2p/go-libp2p/core/record"
|
||||
//
|
||||
// func init() {
|
||||
// record.RegisterType(&HelloRecord{})
|
||||
// }
|
||||
//
|
||||
// type HelloRecord struct { } // etc..
|
||||
func RegisterType(prototype Record) {
|
||||
payloadTypeRegistry[string(prototype.Codec())] = getValueType(prototype)
|
||||
}
|
||||
|
||||
func unmarshalRecordPayload(payloadType []byte, payloadBytes []byte) (_rec Record, err error) {
|
||||
defer func() { catch.HandlePanic(recover(), &err, "libp2p envelope record unmarshal") }()
|
||||
|
||||
rec, err := blankRecordForPayloadType(payloadType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = rec.UnmarshalRecord(payloadBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rec, nil
|
||||
}
|
||||
|
||||
func blankRecordForPayloadType(payloadType []byte) (Record, error) {
|
||||
valueType, ok := payloadTypeRegistry[string(payloadType)]
|
||||
if !ok {
|
||||
return nil, ErrPayloadTypeNotRegistered
|
||||
}
|
||||
|
||||
val := reflect.New(valueType)
|
||||
asRecord := val.Interface().(Record)
|
||||
return asRecord, nil
|
||||
}
|
||||
|
||||
func getValueType(i interface{}) reflect.Type {
|
||||
valueType := reflect.TypeOf(i)
|
||||
if valueType.Kind() == reflect.Ptr {
|
||||
valueType = valueType.Elem()
|
||||
}
|
||||
return valueType
|
||||
}
|
||||
50
vendor/github.com/libp2p/go-libp2p/core/routing/options.go
generated
vendored
Normal file
50
vendor/github.com/libp2p/go-libp2p/core/routing/options.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
package routing
|
||||
|
||||
// Option is a single routing option.
|
||||
type Option func(opts *Options) error
|
||||
|
||||
// Options is a set of routing options
|
||||
type Options struct {
|
||||
// Allow expired values.
|
||||
Expired bool
|
||||
Offline bool
|
||||
// Other (ValueStore implementation specific) options.
|
||||
Other map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// Apply applies the given options to this Options
|
||||
func (opts *Options) Apply(options ...Option) error {
|
||||
for _, o := range options {
|
||||
if err := o(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToOption converts this Options to a single Option.
|
||||
func (opts *Options) ToOption() Option {
|
||||
return func(nopts *Options) error {
|
||||
*nopts = *opts
|
||||
if opts.Other != nil {
|
||||
nopts.Other = make(map[interface{}]interface{}, len(opts.Other))
|
||||
for k, v := range opts.Other {
|
||||
nopts.Other[k] = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Expired is an option that tells the routing system to return expired records
|
||||
// when no newer records are known.
|
||||
var Expired Option = func(opts *Options) error {
|
||||
opts.Expired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Offline is an option that tells the routing system to operate offline (i.e., rely on cached/local data only).
|
||||
var Offline Option = func(opts *Options) error {
|
||||
opts.Offline = true
|
||||
return nil
|
||||
}
|
||||
111
vendor/github.com/libp2p/go-libp2p/core/routing/query.go
generated
vendored
Normal file
111
vendor/github.com/libp2p/go-libp2p/core/routing/query.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
// QueryEventType indicates the query event's type.
|
||||
type QueryEventType int
|
||||
|
||||
// Number of events to buffer.
|
||||
var QueryEventBufferSize = 16
|
||||
|
||||
const (
|
||||
// Sending a query to a peer.
|
||||
SendingQuery QueryEventType = iota
|
||||
// Got a response from a peer.
|
||||
PeerResponse
|
||||
// Found a "closest" peer (not currently used).
|
||||
FinalPeer
|
||||
// Got an error when querying.
|
||||
QueryError
|
||||
// Found a provider.
|
||||
Provider
|
||||
// Found a value.
|
||||
Value
|
||||
// Adding a peer to the query.
|
||||
AddingPeer
|
||||
// Dialing a peer.
|
||||
DialingPeer
|
||||
)
|
||||
|
||||
// QueryEvent is emitted for every notable event that happens during a DHT query.
|
||||
type QueryEvent struct {
|
||||
ID peer.ID
|
||||
Type QueryEventType
|
||||
Responses []*peer.AddrInfo
|
||||
Extra string
|
||||
}
|
||||
|
||||
type routingQueryKey struct{}
|
||||
type eventChannel struct {
|
||||
mu sync.Mutex
|
||||
ctx context.Context
|
||||
ch chan<- *QueryEvent
|
||||
}
|
||||
|
||||
// waitThenClose is spawned in a goroutine when the channel is registered. This
|
||||
// safely cleans up the channel when the context has been canceled.
|
||||
func (e *eventChannel) waitThenClose() {
|
||||
<-e.ctx.Done()
|
||||
e.mu.Lock()
|
||||
close(e.ch)
|
||||
// 1. Signals that we're done.
|
||||
// 2. Frees memory (in case we end up hanging on to this for a while).
|
||||
e.ch = nil
|
||||
e.mu.Unlock()
|
||||
}
|
||||
|
||||
// send sends an event on the event channel, aborting if either the passed or
|
||||
// the internal context expire.
|
||||
func (e *eventChannel) send(ctx context.Context, ev *QueryEvent) {
|
||||
e.mu.Lock()
|
||||
// Closed.
|
||||
if e.ch == nil {
|
||||
e.mu.Unlock()
|
||||
return
|
||||
}
|
||||
// in case the passed context is unrelated, wait on both.
|
||||
select {
|
||||
case e.ch <- ev:
|
||||
case <-e.ctx.Done():
|
||||
case <-ctx.Done():
|
||||
}
|
||||
e.mu.Unlock()
|
||||
}
|
||||
|
||||
// RegisterForQueryEvents registers a query event channel with the given
|
||||
// context. The returned context can be passed to DHT queries to receive query
|
||||
// events on the returned channels.
|
||||
//
|
||||
// The passed context MUST be canceled when the caller is no longer interested
|
||||
// in query events.
|
||||
func RegisterForQueryEvents(ctx context.Context) (context.Context, <-chan *QueryEvent) {
|
||||
ch := make(chan *QueryEvent, QueryEventBufferSize)
|
||||
ech := &eventChannel{ch: ch, ctx: ctx}
|
||||
go ech.waitThenClose()
|
||||
return context.WithValue(ctx, routingQueryKey{}, ech), ch
|
||||
}
|
||||
|
||||
// PublishQueryEvent publishes a query event to the query event channel
|
||||
// associated with the given context, if any.
|
||||
func PublishQueryEvent(ctx context.Context, ev *QueryEvent) {
|
||||
ich := ctx.Value(routingQueryKey{})
|
||||
if ich == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// We *want* to panic here.
|
||||
ech := ich.(*eventChannel)
|
||||
ech.send(ctx, ev)
|
||||
}
|
||||
|
||||
// SubscribesToQueryEvents returns true if the context subscribes to query
|
||||
// events. If this function returns false, calling `PublishQueryEvent` on the
|
||||
// context will be a no-op.
|
||||
func SubscribesToQueryEvents(ctx context.Context) bool {
|
||||
return ctx.Value(routingQueryKey{}) != nil
|
||||
}
|
||||
40
vendor/github.com/libp2p/go-libp2p/core/routing/query_serde.go
generated
vendored
Normal file
40
vendor/github.com/libp2p/go-libp2p/core/routing/query_serde.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
)
|
||||
|
||||
func (qe *QueryEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"ID": qe.ID.String(),
|
||||
"Type": int(qe.Type),
|
||||
"Responses": qe.Responses,
|
||||
"Extra": qe.Extra,
|
||||
})
|
||||
}
|
||||
|
||||
func (qe *QueryEvent) UnmarshalJSON(b []byte) error {
|
||||
temp := struct {
|
||||
ID string
|
||||
Type int
|
||||
Responses []*peer.AddrInfo
|
||||
Extra string
|
||||
}{}
|
||||
err := json.Unmarshal(b, &temp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(temp.ID) > 0 {
|
||||
pid, err := peer.Decode(temp.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
qe.ID = pid
|
||||
}
|
||||
qe.Type = QueryEventType(temp.Type)
|
||||
qe.Responses = temp.Responses
|
||||
qe.Extra = temp.Extra
|
||||
return nil
|
||||
}
|
||||
127
vendor/github.com/libp2p/go-libp2p/core/routing/routing.go
generated
vendored
Normal file
127
vendor/github.com/libp2p/go-libp2p/core/routing/routing.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Package routing provides interfaces for peer routing and content routing in libp2p.
|
||||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
ci "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
)
|
||||
|
||||
// ErrNotFound is returned when the router fails to find the requested record.
|
||||
var ErrNotFound = errors.New("routing: not found")
|
||||
|
||||
// ErrNotSupported is returned when the router doesn't support the given record
|
||||
// type/operation.
|
||||
var ErrNotSupported = errors.New("routing: operation or key not supported")
|
||||
|
||||
// ContentRouting is a value provider layer of indirection. It is used to find
|
||||
// information about who has what content.
|
||||
//
|
||||
// Content is identified by CID (content identifier), which encodes a hash
|
||||
// of the identified content in a future-proof manner.
|
||||
type ContentRouting interface {
|
||||
// Provide adds the given cid to the content routing system. If 'true' is
|
||||
// passed, it also announces it, otherwise it is just kept in the local
|
||||
// accounting of which objects are being provided.
|
||||
Provide(context.Context, cid.Cid, bool) error
|
||||
|
||||
// Search for peers who are able to provide a given key
|
||||
//
|
||||
// When count is 0, this method will return an unbounded number of
|
||||
// results.
|
||||
FindProvidersAsync(context.Context, cid.Cid, int) <-chan peer.AddrInfo
|
||||
}
|
||||
|
||||
// PeerRouting is a way to find address information about certain peers.
|
||||
// This can be implemented by a simple lookup table, a tracking server,
|
||||
// or even a DHT.
|
||||
type PeerRouting interface {
|
||||
// FindPeer searches for a peer with given ID, returns a peer.AddrInfo
|
||||
// with relevant addresses.
|
||||
FindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
|
||||
}
|
||||
|
||||
// ValueStore is a basic Put/Get interface.
|
||||
type ValueStore interface {
|
||||
|
||||
// PutValue adds value corresponding to given Key.
|
||||
PutValue(context.Context, string, []byte, ...Option) error
|
||||
|
||||
// GetValue searches for the value corresponding to given Key.
|
||||
GetValue(context.Context, string, ...Option) ([]byte, error)
|
||||
|
||||
// SearchValue searches for better and better values from this value
|
||||
// store corresponding to the given Key. By default, implementations must
|
||||
// stop the search after a good value is found. A 'good' value is a value
|
||||
// that would be returned from GetValue.
|
||||
//
|
||||
// Useful when you want a result *now* but still want to hear about
|
||||
// better/newer results.
|
||||
//
|
||||
// Implementations of this methods won't return ErrNotFound. When a value
|
||||
// couldn't be found, the channel will get closed without passing any results
|
||||
SearchValue(context.Context, string, ...Option) (<-chan []byte, error)
|
||||
}
|
||||
|
||||
// Routing is the combination of different routing types supported by libp2p.
|
||||
// It can be satisfied by a single item (such as a DHT) or multiple different
|
||||
// pieces that are more optimized to each task.
|
||||
type Routing interface {
|
||||
ContentRouting
|
||||
PeerRouting
|
||||
ValueStore
|
||||
|
||||
// Bootstrap allows callers to hint to the routing system to get into a
|
||||
// Boostrapped state and remain there. It is not a synchronous call.
|
||||
Bootstrap(context.Context) error
|
||||
|
||||
// TODO expose io.Closer or plain-old Close error
|
||||
}
|
||||
|
||||
// PubKeyFetcher is an interfaces that should be implemented by value stores
|
||||
// that can optimize retrieval of public keys.
|
||||
//
|
||||
// TODO(steb): Consider removing, see https://github.com/libp2p/go-libp2p-routing/issues/22.
|
||||
type PubKeyFetcher interface {
|
||||
// GetPublicKey returns the public key for the given peer.
|
||||
GetPublicKey(context.Context, peer.ID) (ci.PubKey, error)
|
||||
}
|
||||
|
||||
// KeyForPublicKey returns the key used to retrieve public keys
|
||||
// from a value store.
|
||||
func KeyForPublicKey(id peer.ID) string {
|
||||
return "/pk/" + string(id)
|
||||
}
|
||||
|
||||
// GetPublicKey retrieves the public key associated with the given peer ID from
|
||||
// the value store.
|
||||
//
|
||||
// If the ValueStore is also a PubKeyFetcher, this method will call GetPublicKey
|
||||
// (which may be better optimized) instead of GetValue.
|
||||
func GetPublicKey(r ValueStore, ctx context.Context, p peer.ID) (ci.PubKey, error) {
|
||||
switch k, err := p.ExtractPublicKey(); err {
|
||||
case peer.ErrNoPublicKey:
|
||||
// check the datastore
|
||||
case nil:
|
||||
return k, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dht, ok := r.(PubKeyFetcher); ok {
|
||||
// If we have a DHT as our routing system, use optimized fetcher
|
||||
return dht.GetPublicKey(ctx, p)
|
||||
}
|
||||
key := KeyForPublicKey(p)
|
||||
pkval, err := r.GetValue(ctx, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get PublicKey from node.Data
|
||||
return ci.UnmarshalPublicKey(pkval)
|
||||
}
|
||||
233
vendor/github.com/libp2p/go-libp2p/core/sec/insecure/insecure.go
generated
vendored
Normal file
233
vendor/github.com/libp2p/go-libp2p/core/sec/insecure/insecure.go
generated
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
// Package insecure provides an insecure, unencrypted implementation of the SecureConn and SecureTransport interfaces.
|
||||
//
|
||||
// Recommended only for testing and other non-production usage.
|
||||
package insecure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
ci "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/libp2p/go-libp2p/core/sec"
|
||||
"github.com/libp2p/go-libp2p/core/sec/insecure/pb"
|
||||
|
||||
"github.com/libp2p/go-msgio"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/plaintext.proto=./pb pb/plaintext.proto
|
||||
|
||||
// ID is the multistream-select protocol ID that should be used when identifying
|
||||
// this security transport.
|
||||
const ID = "/plaintext/2.0.0"
|
||||
|
||||
// Transport is a no-op stream security transport. It provides no
|
||||
// security and simply mocks the security methods. Identity methods
|
||||
// return the local peer's ID and private key, and whatever the remote
|
||||
// peer presents as their ID and public key.
|
||||
// No authentication of the remote identity is performed.
|
||||
type Transport struct {
|
||||
id peer.ID
|
||||
key ci.PrivKey
|
||||
protocolID protocol.ID
|
||||
}
|
||||
|
||||
var _ sec.SecureTransport = &Transport{}
|
||||
|
||||
// NewWithIdentity constructs a new insecure transport. The public key is sent to
|
||||
// remote peers. No security is provided.
|
||||
func NewWithIdentity(protocolID protocol.ID, id peer.ID, key ci.PrivKey) *Transport {
|
||||
return &Transport{
|
||||
protocolID: protocolID,
|
||||
id: id,
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
|
||||
// LocalPeer returns the transport's local peer ID.
|
||||
func (t *Transport) LocalPeer() peer.ID {
|
||||
return t.id
|
||||
}
|
||||
|
||||
// SecureInbound *pretends to secure* an inbound connection to the given peer.
|
||||
// It sends the local peer's ID and public key, and receives the same from the remote peer.
|
||||
// No validation is performed as to the authenticity or ownership of the provided public key,
|
||||
// and the key exchange provides no security.
|
||||
//
|
||||
// SecureInbound may fail if the remote peer sends an ID and public key that are inconsistent
|
||||
// with each other, or if a network error occurs during the ID exchange.
|
||||
func (t *Transport) SecureInbound(_ context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) {
|
||||
conn := &Conn{
|
||||
Conn: insecure,
|
||||
local: t.id,
|
||||
localPubKey: t.key.GetPublic(),
|
||||
}
|
||||
|
||||
if err := conn.runHandshakeSync(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p != "" && p != conn.remote {
|
||||
return nil, fmt.Errorf("remote peer sent unexpected peer ID. expected=%s received=%s", p, conn.remote)
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// SecureOutbound *pretends to secure* an outbound connection to the given peer.
|
||||
// It sends the local peer's ID and public key, and receives the same from the remote peer.
|
||||
// No validation is performed as to the authenticity or ownership of the provided public key,
|
||||
// and the key exchange provides no security.
|
||||
//
|
||||
// SecureOutbound may fail if the remote peer sends an ID and public key that are inconsistent
|
||||
// with each other, or if the ID sent by the remote peer does not match the one dialed. It may
|
||||
// also fail if a network error occurs during the ID exchange.
|
||||
func (t *Transport) SecureOutbound(_ context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) {
|
||||
conn := &Conn{
|
||||
Conn: insecure,
|
||||
local: t.id,
|
||||
localPubKey: t.key.GetPublic(),
|
||||
}
|
||||
|
||||
if err := conn.runHandshakeSync(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p != conn.remote {
|
||||
return nil, fmt.Errorf("remote peer sent unexpected peer ID. expected=%s received=%s",
|
||||
p, conn.remote)
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (t *Transport) ID() protocol.ID { return t.protocolID }
|
||||
|
||||
// Conn is the connection type returned by the insecure transport.
|
||||
type Conn struct {
|
||||
net.Conn
|
||||
|
||||
local, remote peer.ID
|
||||
localPubKey, remotePubKey ci.PubKey
|
||||
}
|
||||
|
||||
func makeExchangeMessage(pubkey ci.PubKey) (*pb.Exchange, error) {
|
||||
keyMsg, err := ci.PublicKeyToProto(pubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id, err := peer.IDFromPublicKey(pubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.Exchange{
|
||||
Id: []byte(id),
|
||||
Pubkey: keyMsg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ic *Conn) runHandshakeSync() error {
|
||||
// If we were initialized without keys, behave as in plaintext/1.0.0 (do nothing)
|
||||
if ic.localPubKey == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate an Exchange message
|
||||
msg, err := makeExchangeMessage(ic.localPubKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Send our Exchange and read theirs
|
||||
remoteMsg, err := readWriteMsg(ic.Conn, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Pull remote ID and public key from message
|
||||
remotePubkey, err := ci.PublicKeyFromProto(remoteMsg.Pubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remoteID, err := peer.IDFromBytes(remoteMsg.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate that ID matches public key
|
||||
if !remoteID.MatchesPublicKey(remotePubkey) {
|
||||
calculatedID, _ := peer.IDFromPublicKey(remotePubkey)
|
||||
return fmt.Errorf("remote peer id does not match public key. id=%s calculated_id=%s",
|
||||
remoteID, calculatedID)
|
||||
}
|
||||
|
||||
// Add remote ID and key to conn state
|
||||
ic.remotePubKey = remotePubkey
|
||||
ic.remote = remoteID
|
||||
return nil
|
||||
}
|
||||
|
||||
// read and write a message at the same time.
|
||||
func readWriteMsg(rw io.ReadWriter, out *pb.Exchange) (*pb.Exchange, error) {
|
||||
const maxMessageSize = 1 << 16
|
||||
|
||||
outBytes, err := proto.Marshal(out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wresult := make(chan error)
|
||||
go func() {
|
||||
w := msgio.NewVarintWriter(rw)
|
||||
wresult <- w.WriteMsg(outBytes)
|
||||
}()
|
||||
|
||||
r := msgio.NewVarintReaderSize(rw, maxMessageSize)
|
||||
b, err1 := r.ReadMsg()
|
||||
|
||||
// Always wait for the read to finish.
|
||||
err2 := <-wresult
|
||||
|
||||
if err1 != nil {
|
||||
return nil, err1
|
||||
}
|
||||
if err2 != nil {
|
||||
r.ReleaseMsg(b)
|
||||
return nil, err2
|
||||
}
|
||||
inMsg := new(pb.Exchange)
|
||||
err = proto.Unmarshal(b, inMsg)
|
||||
return inMsg, err
|
||||
}
|
||||
|
||||
// LocalPeer returns the local peer ID.
|
||||
func (ic *Conn) LocalPeer() peer.ID {
|
||||
return ic.local
|
||||
}
|
||||
|
||||
// RemotePeer returns the remote peer ID if we initiated the dial. Otherwise, it
|
||||
// returns "" (because this connection isn't actually secure).
|
||||
func (ic *Conn) RemotePeer() peer.ID {
|
||||
return ic.remote
|
||||
}
|
||||
|
||||
// RemotePublicKey returns whatever public key was given by the remote peer.
|
||||
// Note that no verification of ownership is done, as this connection is not secure.
|
||||
func (ic *Conn) RemotePublicKey() ci.PubKey {
|
||||
return ic.remotePubKey
|
||||
}
|
||||
|
||||
// ConnState returns the security connection's state information.
|
||||
func (ic *Conn) ConnState() network.ConnectionState {
|
||||
return network.ConnectionState{}
|
||||
}
|
||||
|
||||
var _ sec.SecureTransport = (*Transport)(nil)
|
||||
var _ sec.SecureConn = (*Conn)(nil)
|
||||
156
vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.pb.go
generated
vendored
Normal file
156
vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.pb.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: pb/plaintext.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Exchange struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
|
||||
Pubkey *pb.PublicKey `protobuf:"bytes,2,opt,name=pubkey" json:"pubkey,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Exchange) Reset() {
|
||||
*x = Exchange{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_plaintext_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Exchange) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Exchange) ProtoMessage() {}
|
||||
|
||||
func (x *Exchange) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_plaintext_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Exchange.ProtoReflect.Descriptor instead.
|
||||
func (*Exchange) Descriptor() ([]byte, []int) {
|
||||
return file_pb_plaintext_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Exchange) GetId() []byte {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Exchange) GetPubkey() *pb.PublicKey {
|
||||
if x != nil {
|
||||
return x.Pubkey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pb_plaintext_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pb_plaintext_proto_rawDesc = []byte{
|
||||
0x0a, 0x12, 0x70, 0x62, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e,
|
||||
0x70, 0x62, 0x1a, 0x1b, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2f,
|
||||
0x70, 0x62, 0x2f, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
|
||||
0x48, 0x0a, 0x08, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x06, 0x70,
|
||||
0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x72,
|
||||
0x79, 0x70, 0x74, 0x6f, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
|
||||
0x79, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pb_plaintext_proto_rawDescOnce sync.Once
|
||||
file_pb_plaintext_proto_rawDescData = file_pb_plaintext_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pb_plaintext_proto_rawDescGZIP() []byte {
|
||||
file_pb_plaintext_proto_rawDescOnce.Do(func() {
|
||||
file_pb_plaintext_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_plaintext_proto_rawDescData)
|
||||
})
|
||||
return file_pb_plaintext_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pb_plaintext_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_pb_plaintext_proto_goTypes = []interface{}{
|
||||
(*Exchange)(nil), // 0: plaintext.pb.Exchange
|
||||
(*pb.PublicKey)(nil), // 1: crypto.pb.PublicKey
|
||||
}
|
||||
var file_pb_plaintext_proto_depIdxs = []int32{
|
||||
1, // 0: plaintext.pb.Exchange.pubkey:type_name -> crypto.pb.PublicKey
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pb_plaintext_proto_init() }
|
||||
func file_pb_plaintext_proto_init() {
|
||||
if File_pb_plaintext_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pb_plaintext_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Exchange); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_pb_plaintext_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pb_plaintext_proto_goTypes,
|
||||
DependencyIndexes: file_pb_plaintext_proto_depIdxs,
|
||||
MessageInfos: file_pb_plaintext_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pb_plaintext_proto = out.File
|
||||
file_pb_plaintext_proto_rawDesc = nil
|
||||
file_pb_plaintext_proto_goTypes = nil
|
||||
file_pb_plaintext_proto_depIdxs = nil
|
||||
}
|
||||
10
vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.proto
generated
vendored
Normal file
10
vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.proto
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package plaintext.pb;
|
||||
|
||||
import "core/crypto/pb/crypto.proto";
|
||||
|
||||
message Exchange {
|
||||
optional bytes id = 1;
|
||||
optional crypto.pb.PublicKey pubkey = 2;
|
||||
}
|
||||
31
vendor/github.com/libp2p/go-libp2p/core/sec/security.go
generated
vendored
Normal file
31
vendor/github.com/libp2p/go-libp2p/core/sec/security.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Package sec provides secure connection and transport interfaces for libp2p.
|
||||
package sec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
)
|
||||
|
||||
// SecureConn is an authenticated, encrypted connection.
|
||||
type SecureConn interface {
|
||||
net.Conn
|
||||
network.ConnSecurity
|
||||
}
|
||||
|
||||
// A SecureTransport turns inbound and outbound unauthenticated,
|
||||
// plain-text, native connections into authenticated, encrypted connections.
|
||||
type SecureTransport interface {
|
||||
// SecureInbound secures an inbound connection.
|
||||
// If p is empty, connections from any peer are accepted.
|
||||
SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (SecureConn, error)
|
||||
|
||||
// SecureOutbound secures an outbound connection.
|
||||
SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (SecureConn, error)
|
||||
|
||||
// ID is the protocol ID of the security protocol.
|
||||
ID() protocol.ID
|
||||
}
|
||||
126
vendor/github.com/libp2p/go-libp2p/core/transport/transport.go
generated
vendored
Normal file
126
vendor/github.com/libp2p/go-libp2p/core/transport/transport.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// Package transport provides the Transport interface, which represents
|
||||
// the devices and network protocols used to send and receive data.
|
||||
package transport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
// A CapableConn represents a connection that has offers the basic
|
||||
// capabilities required by libp2p: stream multiplexing, encryption and
|
||||
// peer authentication.
|
||||
//
|
||||
// These capabilities may be natively provided by the transport, or they
|
||||
// may be shimmed via the "connection upgrade" process, which converts a
|
||||
// "raw" network connection into one that supports such capabilities by
|
||||
// layering an encryption channel and a stream multiplexer.
|
||||
//
|
||||
// CapableConn provides accessors for the local and remote multiaddrs used to
|
||||
// establish the connection and an accessor for the underlying Transport.
|
||||
type CapableConn interface {
|
||||
network.MuxedConn
|
||||
network.ConnSecurity
|
||||
network.ConnMultiaddrs
|
||||
network.ConnScoper
|
||||
|
||||
// Transport returns the transport to which this connection belongs.
|
||||
Transport() Transport
|
||||
}
|
||||
|
||||
// Transport represents any device by which you can connect to and accept
|
||||
// connections from other peers.
|
||||
//
|
||||
// The Transport interface allows you to open connections to other peers
|
||||
// by dialing them, and also lets you listen for incoming connections.
|
||||
//
|
||||
// Connections returned by Dial and passed into Listeners are of type
|
||||
// CapableConn, which means that they have been upgraded to support
|
||||
// stream multiplexing and connection security (encryption and authentication).
|
||||
//
|
||||
// If a transport implements `io.Closer` (optional), libp2p will call `Close` on
|
||||
// shutdown. NOTE: `Dial` and `Listen` may be called after or concurrently with
|
||||
// `Close`.
|
||||
//
|
||||
// For a conceptual overview, see https://docs.libp2p.io/concepts/transport/
|
||||
type Transport interface {
|
||||
// Dial dials a remote peer. It should try to reuse local listener
|
||||
// addresses if possible, but it may choose not to.
|
||||
Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (CapableConn, error)
|
||||
|
||||
// CanDial returns true if this transport knows how to dial the given
|
||||
// multiaddr.
|
||||
//
|
||||
// Returning true does not guarantee that dialing this multiaddr will
|
||||
// succeed. This function should *only* be used to preemptively filter
|
||||
// out addresses that we can't dial.
|
||||
CanDial(addr ma.Multiaddr) bool
|
||||
|
||||
// Listen listens on the passed multiaddr.
|
||||
Listen(laddr ma.Multiaddr) (Listener, error)
|
||||
|
||||
// Protocol returns the set of protocols handled by this transport.
|
||||
//
|
||||
// See the Network interface for an explanation of how this is used.
|
||||
Protocols() []int
|
||||
|
||||
// Proxy returns true if this is a proxy transport.
|
||||
//
|
||||
// See the Network interface for an explanation of how this is used.
|
||||
// TODO: Make this a part of the go-multiaddr protocol instead?
|
||||
Proxy() bool
|
||||
}
|
||||
|
||||
// Resolver can be optionally implemented by transports that want to resolve or transform the
|
||||
// multiaddr.
|
||||
type Resolver interface {
|
||||
Resolve(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error)
|
||||
}
|
||||
|
||||
// Listener is an interface closely resembling the net.Listener interface. The
|
||||
// only real difference is that Accept() returns Conn's of the type in this
|
||||
// package, and also exposes a Multiaddr method as opposed to a regular Addr
|
||||
// method
|
||||
type Listener interface {
|
||||
Accept() (CapableConn, error)
|
||||
Close() error
|
||||
Addr() net.Addr
|
||||
Multiaddr() ma.Multiaddr
|
||||
}
|
||||
|
||||
// ErrListenerClosed is returned by Listener.Accept when the listener is gracefully closed.
|
||||
var ErrListenerClosed = errors.New("listener closed")
|
||||
|
||||
// TransportNetwork is an inet.Network with methods for managing transports.
|
||||
type TransportNetwork interface {
|
||||
network.Network
|
||||
|
||||
// AddTransport adds a transport to this Network.
|
||||
//
|
||||
// When dialing, this Network will iterate over the protocols in the
|
||||
// remote multiaddr and pick the first protocol registered with a proxy
|
||||
// transport, if any. Otherwise, it'll pick the transport registered to
|
||||
// handle the last protocol in the multiaddr.
|
||||
//
|
||||
// When listening, this Network will iterate over the protocols in the
|
||||
// local multiaddr and pick the *last* protocol registered with a proxy
|
||||
// transport, if any. Otherwise, it'll pick the transport registered to
|
||||
// handle the last protocol in the multiaddr.
|
||||
AddTransport(t Transport) error
|
||||
}
|
||||
|
||||
// Upgrader is a multistream upgrader that can upgrade an underlying connection
|
||||
// to a full transport connection (secure and multiplexed).
|
||||
type Upgrader interface {
|
||||
// UpgradeListener upgrades the passed multiaddr-net listener into a full libp2p-transport listener.
|
||||
UpgradeListener(Transport, manet.Listener) Listener
|
||||
// Upgrade upgrades the multiaddr/net connection into a full libp2p-transport connection.
|
||||
Upgrade(ctx context.Context, t Transport, maconn manet.Conn, dir network.Direction, p peer.ID, scope network.ConnManagementScope) (CapableConn, error)
|
||||
}
|
||||
Reference in New Issue
Block a user