diff --git a/config/config.go b/config/config.go index 405d6d97eb..6561d8522b 100644 --- a/config/config.go +++ b/config/config.go @@ -5,18 +5,17 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/metrics" - "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/pnet" - "github.com/libp2p/go-libp2p-core/routing" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" - + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/metrics" + "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/pnet" + "github.com/libp2p/go-libp2p/core/routing" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/host/autonat" "github.com/libp2p/go-libp2p/p2p/host/autorelay" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" diff --git a/config/constructor_types.go b/config/constructor_types.go index 631a44cda6..7cb24464b4 100644 --- a/config/constructor_types.go +++ b/config/constructor_types.go @@ -4,15 +4,15 @@ import ( "fmt" "reflect" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "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/pnet" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "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/pnet" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" ) var ( diff --git a/config/muxer.go b/config/muxer.go index 2b3e857083..651dea76b6 100644 --- a/config/muxer.go +++ b/config/muxer.go @@ -3,11 +3,9 @@ package config import ( "fmt" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" msmux "github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream" - - "github.com/libp2p/go-libp2p-core/network" - - "github.com/libp2p/go-libp2p-core/host" ) // MuxC is a stream multiplex transport constructor. diff --git a/config/muxer_test.go b/config/muxer_test.go index 4b00d64c99..772b43294c 100644 --- a/config/muxer_test.go +++ b/config/muxer_test.go @@ -3,13 +3,12 @@ package config import ( "testing" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" ) func TestMuxerSimple(t *testing.T) { diff --git a/config/reflection_magic.go b/config/reflection_magic.go index b086f85e4d..407e585056 100644 --- a/config/reflection_magic.go +++ b/config/reflection_magic.go @@ -6,13 +6,11 @@ import ( "reflect" "runtime" - "github.com/libp2p/go-libp2p-core/network" - - "github.com/libp2p/go-libp2p-core/pnet" - - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/transport" ) var errorType = reflect.TypeOf((*error)(nil)).Elem() diff --git a/config/security.go b/config/security.go index bac3eb2185..a98d761a89 100644 --- a/config/security.go +++ b/config/security.go @@ -3,13 +3,12 @@ package config import ( "fmt" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/sec/insecure" csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" - - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/sec/insecure" ) // SecC is a security transport constructor. diff --git a/config/transport.go b/config/transport.go index c1a5f4ef90..9006683a09 100644 --- a/config/transport.go +++ b/config/transport.go @@ -1,11 +1,11 @@ package config import ( - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/transport" ) // TptC is the type for libp2p transport constructors. You probably won't ever diff --git a/config/transport_test.go b/config/transport_test.go index 9cb5c9a3e0..1af9c169d9 100644 --- a/config/transport_test.go +++ b/config/transport_test.go @@ -3,11 +3,10 @@ package config import ( "testing" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/transport/tcp" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - "github.com/stretchr/testify/require" ) diff --git a/core/alias.go b/core/alias.go new file mode 100644 index 0000000000..515083bb71 --- /dev/null +++ b/core/alias.go @@ -0,0 +1,51 @@ +// Package core provides convenient access to foundational, central go-libp2p primitives via type aliases. +package core + +import ( + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + + "github.com/multiformats/go-multiaddr" +) + +// Multiaddr aliases the Multiaddr type from github.com/multiformats/go-multiaddr. +// +// Refer to the docs on that type for more info. +type Multiaddr = multiaddr.Multiaddr + +// PeerID aliases peer.ID. +// +// Refer to the docs on that type for more info. +type PeerID = peer.ID + +// ProtocolID aliases protocol.ID. +// +// Refer to the docs on that type for more info. +type ProtocolID = protocol.ID + +// PeerAddrInfo aliases peer.AddrInfo. +// +// Refer to the docs on that type for more info. +type PeerAddrInfo = peer.AddrInfo + +// Host aliases host.Host. +// +// Refer to the docs on that type for more info. +type Host = host.Host + +// Network aliases network.Network. +// +// Refer to the docs on that type for more info. +type Network = network.Network + +// Conn aliases network.Conn. +// +// Refer to the docs on that type for more info. +type Conn = network.Conn + +// Stream aliases network.Stream. +// +// Refer to the docs on that type for more info. +type Stream = network.Stream diff --git a/core/canonicallog/canonicallog.go b/core/canonicallog/canonicallog.go new file mode 100644 index 0000000000..3e021ef28d --- /dev/null +++ b/core/canonicallog/canonicallog.go @@ -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()) + } +} diff --git a/core/canonicallog/canonicallog_test.go b/core/canonicallog/canonicallog_test.go new file mode 100644 index 0000000000..fc03a6a30f --- /dev/null +++ b/core/canonicallog/canonicallog_test.go @@ -0,0 +1,26 @@ +package canonicallog + +import ( + "fmt" + "net" + "testing" + + "github.com/libp2p/go-libp2p/core/test" + + logging "github.com/ipfs/go-log/v2" + "github.com/multiformats/go-multiaddr" +) + +func TestLogs(t *testing.T) { + err := logging.SetLogLevel("canonical-log", "info") + if err != nil { + t.Fatal(err) + } + + LogMisbehavingPeer(test.RandPeerIDFatal(t), multiaddr.StringCast("/ip4/1.2.3.4"), "somecomponent", fmt.Errorf("something"), "hi") + + netAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 80} + LogMisbehavingPeerNetAddr(test.RandPeerIDFatal(t), netAddr, "somecomponent", fmt.Errorf("something"), "hello \"world\"") + + LogPeerStatus(1, test.RandPeerIDFatal(t), multiaddr.StringCast("/ip4/1.2.3.4"), "extra", "info") +} diff --git a/core/connmgr/decay.go b/core/connmgr/decay.go new file mode 100644 index 0000000000..783a06c3a8 --- /dev/null +++ b/core/connmgr/decay.go @@ -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 +} diff --git a/core/connmgr/gater.go b/core/connmgr/gater.go new file mode 100644 index 0000000000..672aef9528 --- /dev/null +++ b/core/connmgr/gater.go @@ -0,0 +1,90 @@ +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) +} diff --git a/core/connmgr/manager.go b/core/connmgr/manager.go new file mode 100644 index 0000000000..e0d6c52012 --- /dev/null +++ b/core/connmgr/manager.go @@ -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 +} diff --git a/core/connmgr/null.go b/core/connmgr/null.go new file mode 100644 index 0000000000..25743f4ec7 --- /dev/null +++ b/core/connmgr/null.go @@ -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 } diff --git a/core/connmgr/presets.go b/core/connmgr/presets.go new file mode 100644 index 0000000000..34bd1c077c --- /dev/null +++ b/core/connmgr/presets.go @@ -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 + } +} diff --git a/core/control/disconnect.go b/core/control/disconnect.go new file mode 100644 index 0000000000..ad1fc5b8a6 --- /dev/null +++ b/core/control/disconnect.go @@ -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 diff --git a/core/crypto/bench_test.go b/core/crypto/bench_test.go new file mode 100644 index 0000000000..1001fe39af --- /dev/null +++ b/core/crypto/bench_test.go @@ -0,0 +1,84 @@ +package crypto + +import "testing" + +func BenchmarkSignRSA1B(b *testing.B) { RunBenchmarkSignRSA(b, 1) } +func BenchmarkSignRSA10B(b *testing.B) { RunBenchmarkSignRSA(b, 10) } +func BenchmarkSignRSA100B(b *testing.B) { RunBenchmarkSignRSA(b, 100) } +func BenchmarkSignRSA1000B(b *testing.B) { RunBenchmarkSignRSA(b, 1000) } +func BenchmarkSignRSA10000B(b *testing.B) { RunBenchmarkSignRSA(b, 10000) } +func BenchmarkSignRSA100000B(b *testing.B) { RunBenchmarkSignRSA(b, 100000) } + +func BenchmarkVerifyRSA1B(b *testing.B) { RunBenchmarkVerifyRSA(b, 1) } +func BenchmarkVerifyRSA10B(b *testing.B) { RunBenchmarkVerifyRSA(b, 10) } +func BenchmarkVerifyRSA100B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100) } +func BenchmarkVerifyRSA1000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 1000) } +func BenchmarkVerifyRSA10000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 10000) } +func BenchmarkVerifyRSA100000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100000) } + +func BenchmarkSignEd255191B(b *testing.B) { RunBenchmarkSignEd25519(b, 1) } +func BenchmarkSignEd2551910B(b *testing.B) { RunBenchmarkSignEd25519(b, 10) } +func BenchmarkSignEd25519100B(b *testing.B) { RunBenchmarkSignEd25519(b, 100) } +func BenchmarkSignEd255191000B(b *testing.B) { RunBenchmarkSignEd25519(b, 1000) } +func BenchmarkSignEd2551910000B(b *testing.B) { RunBenchmarkSignEd25519(b, 10000) } +func BenchmarkSignEd25519100000B(b *testing.B) { RunBenchmarkSignEd25519(b, 100000) } + +func BenchmarkVerifyEd255191B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 1) } +func BenchmarkVerifyEd2551910B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 10) } +func BenchmarkVerifyEd25519100B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100) } +func BenchmarkVerifyEd255191000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 1000) } +func BenchmarkVerifyEd2551910000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 10000) } +func BenchmarkVerifyEd25519100000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100000) } + +func RunBenchmarkSignRSA(b *testing.B, numBytes int) { + runBenchmarkSign(b, numBytes, RSA) +} + +func RunBenchmarkSignEd25519(b *testing.B, numBytes int) { + runBenchmarkSign(b, numBytes, Ed25519) +} + +func runBenchmarkSign(b *testing.B, numBytes int, t int) { + secret, _, err := GenerateKeyPair(t, 1024) + if err != nil { + b.Fatal(err) + } + someData := make([]byte, numBytes) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := secret.Sign(someData) + if err != nil { + b.Fatal(err) + } + } +} + +func RunBenchmarkVerifyRSA(b *testing.B, numBytes int) { + runBenchmarkVerify(b, numBytes, RSA) +} + +func RunBenchmarkVerifyEd25519(b *testing.B, numBytes int) { + runBenchmarkVerify(b, numBytes, Ed25519) +} + +func runBenchmarkVerify(b *testing.B, numBytes int, t int) { + secret, public, err := GenerateKeyPair(t, 1024) + if err != nil { + b.Fatal(err) + } + someData := make([]byte, numBytes) + signature, err := secret.Sign(someData) + if err != nil { + b.Fatal(err) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + valid, err := public.Verify(someData, signature) + if err != nil { + b.Fatal(err) + } + if !valid { + b.Fatal("signature should be valid") + } + } +} diff --git a/core/crypto/ecdsa.go b/core/crypto/ecdsa.go new file mode 100644 index 0000000000..318dcac2b4 --- /dev/null +++ b/core/crypto/ecdsa.go @@ -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 speicified 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 +} diff --git a/core/crypto/ecdsa_test.go b/core/crypto/ecdsa_test.go new file mode 100644 index 0000000000..cc75d5740a --- /dev/null +++ b/core/crypto/ecdsa_test.go @@ -0,0 +1,142 @@ +package crypto + +import ( + "crypto/ecdsa" + "crypto/rand" + "testing" +) + +func TestECDSABasicSignAndVerify(t *testing.T) { + priv, pub, err := GenerateECDSAKeyPair(rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := []byte("hello! and welcome to some awesome crypto primitives") + + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if !ok { + t.Fatal("signature didnt match") + } + + // change data + data[0] = ^data[0] + ok, err = pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if ok { + t.Fatal("signature matched and shouldn't") + } +} + +func TestECDSASignZero(t *testing.T) { + priv, pub, err := GenerateECDSAKeyPair(rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := make([]byte, 0) + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal("signature didn't match") + } +} + +func TestECDSAMarshalLoop(t *testing.T) { + priv, pub, err := GenerateECDSAKeyPair(rand.Reader) + if err != nil { + t.Fatal(err) + } + + privB, err := MarshalPrivateKey(priv) + if err != nil { + t.Fatal(err) + } + + privNew, err := UnmarshalPrivateKey(privB) + if err != nil { + t.Fatal(err) + } + + if !priv.Equals(privNew) || !privNew.Equals(priv) { + t.Fatal("keys are not equal") + } + + pubB, err := MarshalPublicKey(pub) + if err != nil { + t.Fatal(err) + } + pubNew, err := UnmarshalPublicKey(pubB) + if err != nil { + t.Fatal(err) + } + + if !pub.Equals(pubNew) || !pubNew.Equals(pub) { + t.Fatal("keys are not equal") + } + +} + +func TestECDSAPublicKeyFromPubKey(t *testing.T) { + ecdsaPrivK, err := ecdsa.GenerateKey(ECDSACurve, rand.Reader) + if err != nil { + t.Fatal(err) + } + + privK, _, err := ECDSAKeyPairFromKey(ecdsaPrivK) + if err != nil { + t.Fatal(err) + } + + data := []byte("Hello world!") + signature, err := privK.Sign(data) + if err != nil { + t.Fatal(err) + } + + pubKey, err := ECDSAPublicKeyFromPubKey(ecdsaPrivK.PublicKey) + if err != nil { + t.Fatal(err) + } + + ok, err := pubKey.Verify(data, signature) + if err != nil { + t.Fatal(err) + } + + if !ok { + t.Fatal("signature didn't match") + } + + pubB, err := MarshalPublicKey(pubKey) + if err != nil { + t.Fatal(err) + } + pubNew, err := UnmarshalPublicKey(pubB) + if err != nil { + t.Fatal(err) + } + + if !pubKey.Equals(pubNew) || !pubNew.Equals(pubKey) { + t.Fatal("keys are not equal") + } +} diff --git a/core/crypto/ed25519.go b/core/crypto/ed25519.go new file mode 100644 index 0000000000..7cd72efbce --- /dev/null +++ b/core/crypto/ed25519.go @@ -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 agains 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 +} diff --git a/core/crypto/ed25519_test.go b/core/crypto/ed25519_test.go new file mode 100644 index 0000000000..78a2fa8839 --- /dev/null +++ b/core/crypto/ed25519_test.go @@ -0,0 +1,217 @@ +package crypto + +import ( + "crypto/ed25519" + "crypto/rand" + "testing" + + pb "github.com/libp2p/go-libp2p/core/crypto/pb" +) + +func TestBasicSignAndVerify(t *testing.T) { + priv, pub, err := GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := []byte("hello! and welcome to some awesome crypto primitives") + + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if !ok { + t.Fatal("signature didn't match") + } + + // change data + data[0] = ^data[0] + ok, err = pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if ok { + t.Fatal("signature matched and shouldn't") + } +} + +func TestSignZero(t *testing.T) { + priv, pub, err := GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := make([]byte, 0) + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal("signature didn't match") + } +} + +func TestMarshalLoop(t *testing.T) { + priv, pub, err := GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + t.Run("PrivateKey", func(t *testing.T) { + for name, f := range map[string]func() ([]byte, error){ + "Marshal": func() ([]byte, error) { + return MarshalPrivateKey(priv) + }, + "Redundant": func() ([]byte, error) { + // See issue #36. + // Ed25519 private keys used to contain the public key twice. + // For backwards-compatibility, we need to continue supporting + // that scenario. + pbmes := new(pb.PrivateKey) + pbmes.Type = priv.Type() + data, err := priv.Raw() + if err != nil { + t.Fatal(err) + } + + pbmes.Data = append(data, data[len(data)-ed25519.PublicKeySize:]...) + return pbmes.Marshal() + }, + } { + t.Run(name, func(t *testing.T) { + bts, err := f() + if err != nil { + t.Fatal(err) + } + + privNew, err := UnmarshalPrivateKey(bts) + if err != nil { + t.Fatal(err) + } + + if !priv.Equals(privNew) || !privNew.Equals(priv) { + t.Fatal("keys are not equal") + } + + msg := []byte("My child, my sister,\nThink of the rapture\nOf living together there!") + signed, err := privNew.Sign(msg) + if err != nil { + t.Fatal(err) + } + + ok, err := privNew.GetPublic().Verify(msg, signed) + if err != nil { + t.Fatal(err) + } + + if !ok { + t.Fatal("signature didn't match") + } + }) + } + }) + + t.Run("PublicKey", func(t *testing.T) { + for name, f := range map[string]func() ([]byte, error){ + "Marshal": func() ([]byte, error) { + return MarshalPublicKey(pub) + }, + } { + t.Run(name, func(t *testing.T) { + bts, err := f() + if err != nil { + t.Fatal(err) + } + pubNew, err := UnmarshalPublicKey(bts) + if err != nil { + t.Fatal(err) + } + + if !pub.Equals(pubNew) || !pubNew.Equals(pub) { + t.Fatal("keys are not equal") + } + }) + } + }) +} + +func TestUnmarshalErrors(t *testing.T) { + t.Run("PublicKey", func(t *testing.T) { + t.Run("Invalid data length", func(t *testing.T) { + pbmes := &pb.PublicKey{ + Type: pb.KeyType_Ed25519, + Data: []byte{42}, + } + + data, err := pbmes.Marshal() + if err != nil { + t.Fatal(err) + } + + _, err = UnmarshalPublicKey(data) + if err == nil { + t.Fatal("expected an error") + } + }) + }) + + t.Run("PrivateKey", func(t *testing.T) { + t.Run("Redundant public key mismatch", func(t *testing.T) { + priv, _, err := GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + pbmes := new(pb.PrivateKey) + pbmes.Type = priv.Type() + data, err := priv.Raw() + if err != nil { + t.Fatal(err) + } + + // Append the private key instead of the public key. + pbmes.Data = append(data, data[:ed25519.PublicKeySize]...) + b, err := pbmes.Marshal() + if err != nil { + t.Fatal(err) + } + + _, err = UnmarshalPrivateKey(b) + if err == nil { + t.Fatal("expected an error") + } + if err.Error() != "expected redundant ed25519 public key to be redundant" { + t.Fatalf("invalid error received: %s", err.Error()) + } + }) + + t.Run("Invalid data length", func(t *testing.T) { + pbmes := &pb.PrivateKey{ + Type: pb.KeyType_Ed25519, + Data: []byte{42}, + } + + data, err := pbmes.Marshal() + if err != nil { + t.Fatal(err) + } + + _, err = UnmarshalPrivateKey(data) + if err == nil { + t.Fatal("expected an error") + } + }) + }) +} diff --git a/core/crypto/fixture_test.go b/core/crypto/fixture_test.go new file mode 100644 index 0000000000..aa4f51bcc6 --- /dev/null +++ b/core/crypto/fixture_test.go @@ -0,0 +1,132 @@ +package crypto_test + +import ( + "bytes" + "crypto/rand" + "fmt" + "io" + "os" + "testing" + + "github.com/libp2p/go-libp2p/core/crypto" + crypto_pb "github.com/libp2p/go-libp2p/core/crypto/pb" +) + +var message = []byte("Libp2p is the _best_!") + +type testCase struct { + keyType crypto_pb.KeyType + gen func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error) + sigDeterministic bool +} + +var keyTypes = []testCase{ + { + keyType: crypto_pb.KeyType_ECDSA, + gen: crypto.GenerateECDSAKeyPair, + }, + { + keyType: crypto_pb.KeyType_Secp256k1, + sigDeterministic: true, + gen: crypto.GenerateSecp256k1Key, + }, + { + keyType: crypto_pb.KeyType_RSA, + sigDeterministic: true, + gen: func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error) { + return crypto.GenerateRSAKeyPair(2048, i) + }, + }, +} + +func fname(kt crypto_pb.KeyType, ext string) string { + return fmt.Sprintf("test_data/%d.%s", kt, ext) +} + +func TestFixtures(t *testing.T) { + for _, tc := range keyTypes { + t.Run(tc.keyType.String(), func(t *testing.T) { + pubBytes, err := os.ReadFile(fname(tc.keyType, "pub")) + if err != nil { + t.Fatal(err) + } + privBytes, err := os.ReadFile(fname(tc.keyType, "priv")) + if err != nil { + t.Fatal(err) + } + sigBytes, err := os.ReadFile(fname(tc.keyType, "sig")) + if err != nil { + t.Fatal(err) + } + pub, err := crypto.UnmarshalPublicKey(pubBytes) + if err != nil { + t.Fatal(err) + } + pubBytes2, err := crypto.MarshalPublicKey(pub) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(pubBytes2, pubBytes) { + t.Fatal("encoding round-trip failed") + } + priv, err := crypto.UnmarshalPrivateKey(privBytes) + if err != nil { + t.Fatal(err) + } + privBytes2, err := crypto.MarshalPrivateKey(priv) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(privBytes2, privBytes) { + t.Fatal("encoding round-trip failed") + } + ok, err := pub.Verify(message, sigBytes) + if !ok || err != nil { + t.Fatal("failed to validate signature with public key") + } + + if tc.sigDeterministic { + sigBytes2, err := priv.Sign(message) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(sigBytes2, sigBytes) { + t.Fatal("signature not deterministic") + } + } + }) + } +} + +func init() { + // set to true to re-generate test data + if false { + generate() + panic("generated") + } +} + +// generate re-generates test data +func generate() { + for _, tc := range keyTypes { + priv, pub, err := tc.gen(rand.Reader) + if err != nil { + panic(err) + } + pubb, err := crypto.MarshalPublicKey(pub) + if err != nil { + panic(err) + } + privb, err := crypto.MarshalPrivateKey(priv) + if err != nil { + panic(err) + } + sig, err := priv.Sign(message) + if err != nil { + panic(err) + } + os.WriteFile(fname(tc.keyType, "pub"), pubb, 0666) + os.WriteFile(fname(tc.keyType, "priv"), privb, 0666) + os.WriteFile(fname(tc.keyType, "sig"), sig, 0666) + } +} diff --git a/core/crypto/key.go b/core/crypto/key.go new file mode 100644 index 0000000000..3d7b39a229 --- /dev/null +++ b/core/crypto/key.go @@ -0,0 +1,290 @@ +// 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" + + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + + "github.com/gogo/protobuf/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 verifiy 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 bitsize +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, _ = pmes.Marshal() + } + + 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) { + pbmes := new(pb.PublicKey) + pbmes.Type = k.Type() + data, err := k.Raw() + if err != nil { + return nil, err + } + pbmes.Data = data + return pbmes, 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) { + pbmes := new(pb.PrivateKey) + pbmes.Type = k.Type() + data, err := k.Raw() + if err != nil { + return nil, err + } + + pbmes.Data = data + return proto.Marshal(pbmes) +} + +// 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 +} diff --git a/core/crypto/key_not_openssl.go b/core/crypto/key_not_openssl.go new file mode 100644 index 0000000000..0f446c0fd8 --- /dev/null +++ b/core/crypto/key_not_openssl.go @@ -0,0 +1,81 @@ +//go:build !openssl +// +build !openssl + +package crypto + +import ( + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" + + "github.com/btcsuite/btcd/btcec/v2" +) + +// 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 *btcec.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 + } +} diff --git a/core/crypto/key_openssl.go b/core/crypto/key_openssl.go new file mode 100644 index 0000000000..b88ea5a713 --- /dev/null +++ b/core/crypto/key_openssl.go @@ -0,0 +1,101 @@ +//go:build openssl +// +build openssl + +package crypto + +import ( + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" + "crypto/x509" + + "github.com/libp2p/go-libp2p/core/internal/catch" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/libp2p/go-openssl" +) + +// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p/core/crypto keys +func KeyPairFromStdKey(priv crypto.PrivateKey) (_priv PrivKey, _pub PubKey, err error) { + if priv == nil { + return nil, nil, ErrNilPrivateKey + } + + switch p := priv.(type) { + case *rsa.PrivateKey: + defer func() { catch.HandlePanic(recover(), &err, "x509 private key marshaling") }() + pk, err := openssl.LoadPrivateKeyFromDER(x509.MarshalPKCS1PrivateKey(p)) + if err != nil { + return nil, nil, err + } + + return &opensslPrivateKey{pk}, &opensslPublicKey{key: pk}, 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 *btcec.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) (_priv crypto.PrivateKey, err error) { + if priv == nil { + return nil, ErrNilPrivateKey + } + switch p := priv.(type) { + case *opensslPrivateKey: + defer func() { catch.HandlePanic(recover(), &err, "x509 private key parsing") }() + raw, err := p.Raw() + if err != nil { + return nil, err + } + return x509.ParsePKCS1PrivateKey(raw) + 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) (key crypto.PublicKey, err error) { + if pub == nil { + return nil, ErrNilPublicKey + } + + switch p := pub.(type) { + case *opensslPublicKey: + defer func() { catch.HandlePanic(recover(), &err, "x509 public key parsing") }() + + raw, err := p.Raw() + if err != nil { + return nil, err + } + return x509.ParsePKIXPublicKey(raw) + case *ECDSAPublicKey: + return p.pub, nil + case *Ed25519PublicKey: + return p.k, nil + case *Secp256k1PublicKey: + return p, nil + default: + return nil, ErrBadKeyType + } +} diff --git a/core/crypto/key_test.go b/core/crypto/key_test.go new file mode 100644 index 0000000000..1d6e2bdbb2 --- /dev/null +++ b/core/crypto/key_test.go @@ -0,0 +1,305 @@ +package crypto_test + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "fmt" + "reflect" + "testing" + + . "github.com/libp2p/go-libp2p/core/crypto" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/libp2p/go-libp2p/core/test" + + "github.com/btcsuite/btcd/btcec/v2" + btcececdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" + "github.com/minio/sha256-simd" +) + +func TestKeys(t *testing.T) { + for _, typ := range KeyTypes { + testKeyType(typ, t) + } +} + +func TestKeyPairFromKey(t *testing.T) { + var ( + data = []byte(`hello world`) + hashed = sha256.Sum256(data) + ) + + privk, err := btcec.NewPrivateKey() + if err != nil { + t.Fatalf("err generating btcec priv key:\n%v", err) + } + sigK := btcececdsa.Sign(privk, hashed[:]) + + eKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatalf("err generating ecdsa priv key:\n%v", err) + } + sigE, err := eKey.Sign(rand.Reader, hashed[:], crypto.SHA256) + if err != nil { + t.Fatalf("err generating ecdsa sig:\n%v", err) + } + + rKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatalf("err generating rsa priv key:\n%v", err) + } + sigR, err := rKey.Sign(rand.Reader, hashed[:], crypto.SHA256) + if err != nil { + t.Fatalf("err generating rsa sig:\n%v", err) + } + + _, edKey, err := ed25519.GenerateKey(rand.Reader) + sigEd := ed25519.Sign(edKey, data[:]) + if err != nil { + t.Fatalf("err generating ed25519 sig:\n%v", err) + } + + for i, tt := range []struct { + in crypto.PrivateKey + typ pb.KeyType + sig []byte + }{ + { + eKey, + ECDSA, + sigE, + }, + { + privk, + Secp256k1, + sigK.Serialize(), + }, + { + rKey, + RSA, + sigR, + }, + { + &edKey, + Ed25519, + sigEd, + }, + } { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + priv, pub, err := KeyPairFromStdKey(tt.in) + if err != nil { + t.Fatal(err) + } + + if priv == nil || pub == nil { + t.Errorf("received nil private key or public key: %v, %v", priv, pub) + } + + if priv == nil || priv.Type() != tt.typ { + t.Errorf("want %v; got %v", tt.typ, priv.Type()) + } + + v, err := pub.Verify(data[:], tt.sig) + if err != nil { + t.Error(err) + } + + if !v { + t.Error("signature was not verified") + } + + stdPub, err := PubKeyToStdKey(pub) + if stdPub == nil { + t.Errorf("err getting std public key from key: %v", err) + } + + var stdPubBytes []byte + + switch p := stdPub.(type) { + case *Secp256k1PublicKey: + stdPubBytes, err = p.Raw() + case ed25519.PublicKey: + stdPubBytes = []byte(p) + default: + stdPubBytes, err = x509.MarshalPKIXPublicKey(stdPub) + } + + if err != nil { + t.Errorf("Error while marshaling %v key: %v", reflect.TypeOf(stdPub), err) + } + + pubBytes, err := pub.Raw() + if err != nil { + t.Errorf("err getting raw bytes for %v key: %v", reflect.TypeOf(pub), err) + } + if !bytes.Equal(stdPubBytes, pubBytes) { + t.Errorf("err roundtripping %v key", reflect.TypeOf(pub)) + } + + stdPriv, err := PrivKeyToStdKey(priv) + if stdPub == nil { + t.Errorf("err getting std private key from key: %v", err) + } + + var stdPrivBytes []byte + + switch p := stdPriv.(type) { + case *Secp256k1PrivateKey: + stdPrivBytes, err = p.Raw() + case *ecdsa.PrivateKey: + stdPrivBytes, err = x509.MarshalECPrivateKey(p) + case *ed25519.PrivateKey: + stdPrivBytes = *p + case *rsa.PrivateKey: + stdPrivBytes = x509.MarshalPKCS1PrivateKey(p) + } + + if err != nil { + t.Errorf("err marshaling %v key: %v", reflect.TypeOf(stdPriv), err) + } + + privBytes, err := priv.Raw() + if err != nil { + t.Errorf("err getting raw bytes for %v key: %v", reflect.TypeOf(priv), err) + } + + if !bytes.Equal(stdPrivBytes, privBytes) { + t.Errorf("err roundtripping %v key", reflect.TypeOf(priv)) + } + }) + } +} + +func testKeyType(typ int, t *testing.T) { + bits := 512 + if typ == RSA { + bits = 2048 + } + sk, pk, err := test.RandTestKeyPair(typ, bits) + if err != nil { + t.Fatal(err) + } + + testKeySignature(t, sk) + testKeyEncoding(t, sk) + testKeyEquals(t, sk) + testKeyEquals(t, pk) +} + +func testKeySignature(t *testing.T, sk PrivKey) { + pk := sk.GetPublic() + + text := make([]byte, 16) + if _, err := rand.Read(text); err != nil { + t.Fatal(err) + } + + sig, err := sk.Sign(text) + if err != nil { + t.Fatal(err) + } + + valid, err := pk.Verify(text, sig) + if err != nil { + t.Fatal(err) + } + + if !valid { + t.Fatal("Invalid signature.") + } +} + +func testKeyEncoding(t *testing.T, sk PrivKey) { + skbm, err := MarshalPrivateKey(sk) + if err != nil { + t.Fatal(err) + } + + sk2, err := UnmarshalPrivateKey(skbm) + if err != nil { + t.Fatal(err) + } + + if !sk.Equals(sk2) { + t.Error("Unmarshaled private key didn't match original.\n") + } + + skbm2, err := MarshalPrivateKey(sk2) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(skbm, skbm2) { + t.Error("skb -> marshal -> unmarshal -> skb failed.\n", skbm, "\n", skbm2) + } + + pk := sk.GetPublic() + pkbm, err := MarshalPublicKey(pk) + if err != nil { + t.Fatal(err) + } + + pk2, err := UnmarshalPublicKey(pkbm) + if err != nil { + t.Fatal(err) + } + + if !pk.Equals(pk2) { + t.Error("Unmarshaled public key didn't match original.\n") + } + + pkbm2, err := MarshalPublicKey(pk) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(pkbm, pkbm2) { + t.Error("skb -> marshal -> unmarshal -> skb failed.\n", pkbm, "\n", pkbm2) + } +} + +func testKeyEquals(t *testing.T, k Key) { + // kb, err := k.Raw() + // if err != nil { + // t.Fatal(err) + // } + + if !KeyEqual(k, k) { + t.Fatal("Key not equal to itself.") + } + + // bad test, relies on deep internals.. + // if !KeyEqual(k, testkey(kb)) { + // t.Fatal("Key not equal to key with same bytes.") + // } + + sk, pk, err := test.RandTestKeyPair(RSA, 2048) + if err != nil { + t.Fatal(err) + } + + if KeyEqual(k, sk) { + t.Fatal("Keys should not equal.") + } + + if KeyEqual(k, pk) { + t.Fatal("Keys should not equal.") + } +} + +func TestUnknownCurveErrors(t *testing.T) { + _, _, err := GenerateEKeyPair("P-256") + if err != nil { + t.Fatal(err) + } + + _, _, err = GenerateEKeyPair("error-please") + if err == nil { + t.Fatal("expected invalid key type to error") + } +} diff --git a/core/crypto/openssl_common.go b/core/crypto/openssl_common.go new file mode 100644 index 0000000000..d97eb08b84 --- /dev/null +++ b/core/crypto/openssl_common.go @@ -0,0 +1,104 @@ +//go:build openssl +// +build openssl + +package crypto + +import ( + "sync" + + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + + "github.com/libp2p/go-openssl" +) + +// define these as separate types so we can add more key types later and reuse +// code. + +type opensslPublicKey struct { + key openssl.PublicKey + + cacheLk sync.Mutex + cached []byte +} + +type opensslPrivateKey struct { + key openssl.PrivateKey +} + +func unmarshalOpensslPrivateKey(b []byte) (opensslPrivateKey, error) { + sk, err := openssl.LoadPrivateKeyFromDER(b) + if err != nil { + return opensslPrivateKey{}, err + } + return opensslPrivateKey{sk}, nil +} + +func unmarshalOpensslPublicKey(b []byte) (opensslPublicKey, error) { + sk, err := openssl.LoadPublicKeyFromDER(b) + if err != nil { + return opensslPublicKey{}, err + } + return opensslPublicKey{key: sk, cached: b}, nil +} + +// Verify compares a signature against input data +func (pk *opensslPublicKey) Verify(data, sig []byte) (bool, error) { + err := pk.key.VerifyPKCS1v15(openssl.SHA256_Method, data, sig) + return err == nil, err +} + +func (pk *opensslPublicKey) Type() pb.KeyType { + switch pk.key.KeyType() { + case openssl.KeyTypeRSA: + return pb.KeyType_RSA + default: + return -1 + } +} + +func (pk *opensslPublicKey) Raw() ([]byte, error) { + return pk.key.MarshalPKIXPublicKeyDER() +} + +// Equals checks whether this key is equal to another +func (pk *opensslPublicKey) Equals(k Key) bool { + k0, ok := k.(*RsaPublicKey) + if !ok { + return basicEquals(pk, k) + } + + return pk.key.Equal(k0.opensslPublicKey.key) +} + +// Sign returns a signature of the input data +func (sk *opensslPrivateKey) Sign(message []byte) ([]byte, error) { + return sk.key.SignPKCS1v15(openssl.SHA256_Method, message) +} + +// GetPublic returns a public key +func (sk *opensslPrivateKey) GetPublic() PubKey { + return &opensslPublicKey{key: sk.key} +} + +func (sk *opensslPrivateKey) Type() pb.KeyType { + switch sk.key.KeyType() { + case openssl.KeyTypeRSA: + return pb.KeyType_RSA + default: + return -1 + } +} + +func (sk *opensslPrivateKey) Raw() ([]byte, error) { + return sk.key.MarshalPKCS1PrivateKeyDER() +} + +// Equals checks whether this key is equal to another +func (sk *opensslPrivateKey) Equals(k Key) bool { + k0, ok := k.(*RsaPrivateKey) + if !ok { + return basicEquals(sk, k) + } + + return sk.key.Equal(k0.opensslPrivateKey.key) +} diff --git a/core/crypto/pb/Makefile b/core/crypto/pb/Makefile new file mode 100644 index 0000000000..8af2dd8177 --- /dev/null +++ b/core/crypto/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(PWD)/../..:. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/core/crypto/pb/crypto.pb.go b/core/crypto/pb/crypto.pb.go new file mode 100644 index 0000000000..072fad9c93 --- /dev/null +++ b/core/crypto/pb/crypto.pb.go @@ -0,0 +1,625 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: crypto.proto + +package crypto_pb + +import ( + fmt "fmt" + github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type KeyType int32 + +const ( + KeyType_RSA KeyType = 0 + KeyType_Ed25519 KeyType = 1 + KeyType_Secp256k1 KeyType = 2 + KeyType_ECDSA KeyType = 3 +) + +var KeyType_name = map[int32]string{ + 0: "RSA", + 1: "Ed25519", + 2: "Secp256k1", + 3: "ECDSA", +} + +var 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 proto.EnumName(KeyType_name, int32(x)) +} + +func (x *KeyType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(KeyType_value, data, "KeyType") + if err != nil { + return err + } + *x = KeyType(value) + return nil +} + +func (KeyType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_527278fb02d03321, []int{0} +} + +type PublicKey struct { + Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"` + Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"` +} + +func (m *PublicKey) Reset() { *m = PublicKey{} } +func (m *PublicKey) String() string { return proto.CompactTextString(m) } +func (*PublicKey) ProtoMessage() {} +func (*PublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_527278fb02d03321, []int{0} +} +func (m *PublicKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PublicKey.Merge(m, src) +} +func (m *PublicKey) XXX_Size() int { + return m.Size() +} +func (m *PublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_PublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_PublicKey proto.InternalMessageInfo + +func (m *PublicKey) GetType() KeyType { + if m != nil { + return m.Type + } + return KeyType_RSA +} + +func (m *PublicKey) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +type PrivateKey struct { + Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"` + Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"` +} + +func (m *PrivateKey) Reset() { *m = PrivateKey{} } +func (m *PrivateKey) String() string { return proto.CompactTextString(m) } +func (*PrivateKey) ProtoMessage() {} +func (*PrivateKey) Descriptor() ([]byte, []int) { + return fileDescriptor_527278fb02d03321, []int{1} +} +func (m *PrivateKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PrivateKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PrivateKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PrivateKey.Merge(m, src) +} +func (m *PrivateKey) XXX_Size() int { + return m.Size() +} +func (m *PrivateKey) XXX_DiscardUnknown() { + xxx_messageInfo_PrivateKey.DiscardUnknown(m) +} + +var xxx_messageInfo_PrivateKey proto.InternalMessageInfo + +func (m *PrivateKey) GetType() KeyType { + if m != nil { + return m.Type + } + return KeyType_RSA +} + +func (m *PrivateKey) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func init() { + proto.RegisterEnum("crypto.pb.KeyType", KeyType_name, KeyType_value) + proto.RegisterType((*PublicKey)(nil), "crypto.pb.PublicKey") + proto.RegisterType((*PrivateKey)(nil), "crypto.pb.PrivateKey") +} + +func init() { proto.RegisterFile("crypto.proto", fileDescriptor_527278fb02d03321) } + +var fileDescriptor_527278fb02d03321 = []byte{ + // 203 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2e, 0xaa, 0x2c, + 0x28, 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0x94, 0x82, 0xb9, + 0x38, 0x03, 0x4a, 0x93, 0x72, 0x32, 0x93, 0xbd, 0x53, 0x2b, 0x85, 0x74, 0xb8, 0x58, 0x42, 0x2a, + 0x0b, 0x52, 0x25, 0x18, 0x15, 0x98, 0x34, 0xf8, 0x8c, 0x84, 0xf4, 0xe0, 0xca, 0xf4, 0xbc, 0x53, + 0x2b, 0x41, 0x32, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x81, 0x55, 0x09, 0x49, 0x70, 0xb1, + 0xb8, 0x24, 0x96, 0x24, 0x4a, 0x30, 0x29, 0x30, 0x69, 0xf0, 0xc0, 0x64, 0x40, 0x22, 0x4a, 0x21, + 0x5c, 0x5c, 0x01, 0x45, 0x99, 0x65, 0x89, 0x25, 0xa9, 0x54, 0x34, 0x55, 0xcb, 0x92, 0x8b, 0x1d, + 0xaa, 0x41, 0x88, 0x9d, 0x8b, 0x39, 0x28, 0xd8, 0x51, 0x80, 0x41, 0x88, 0x9b, 0x8b, 0xdd, 0x35, + 0xc5, 0xc8, 0xd4, 0xd4, 0xd0, 0x52, 0x80, 0x51, 0x88, 0x97, 0x8b, 0x33, 0x38, 0x35, 0xb9, 0xc0, + 0xc8, 0xd4, 0x2c, 0xdb, 0x50, 0x80, 0x49, 0x88, 0x93, 0x8b, 0xd5, 0xd5, 0xd9, 0x25, 0xd8, 0x51, + 0x80, 0xd9, 0x49, 0xe2, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, + 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x13, 0xbe, 0xd4, 0xff, 0x19, 0x01, 0x00, 0x00, +} + +func (m *PublicKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PublicKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Data != nil { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + } + i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + +func (m *PrivateKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PrivateKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Data != nil { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + } + i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + +func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int { + offset -= sovCrypto(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PublicKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovCrypto(uint64(m.Type)) + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + +func (m *PrivateKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovCrypto(uint64(m.Type)) + if m.Data != nil { + l = len(m.Data) + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + +func sovCrypto(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozCrypto(x uint64) (n int) { + return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PublicKey) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= KeyType(b&0x7F) << shift + if b < 0x80 { + break + } + } + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCrypto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipCrypto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PrivateKey) Unmarshal(dAtA []byte) error { + var hasFields [1]uint64 + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PrivateKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= KeyType(b&0x7F) << shift + if b < 0x80 { + break + } + } + hasFields[0] |= uint64(0x00000001) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthCrypto + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + hasFields[0] |= uint64(0x00000002) + default: + iNdEx = preIndex + skippy, err := skipCrypto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + if hasFields[0]&uint64(0x00000001) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type") + } + if hasFields[0]&uint64(0x00000002) == 0 { + return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data") + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipCrypto(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthCrypto + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupCrypto + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthCrypto + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupCrypto = fmt.Errorf("proto: unexpected end of group") +) diff --git a/core/crypto/pb/crypto.proto b/core/crypto/pb/crypto.proto new file mode 100644 index 0000000000..44e504423b --- /dev/null +++ b/core/crypto/pb/crypto.proto @@ -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; +} diff --git a/core/crypto/rsa_common.go b/core/crypto/rsa_common.go new file mode 100644 index 0000000000..c7e305439a --- /dev/null +++ b/core/crypto/rsa_common.go @@ -0,0 +1,25 @@ +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 + +// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key +// that's smaller than MinRsaKeyBits bits. In test +var ErrRsaKeyTooSmall error + +func init() { + if _, ok := os.LookupEnv(WeakRsaKeyEnv); ok { + MinRsaKeyBits = 512 + } + + ErrRsaKeyTooSmall = fmt.Errorf("rsa keys must be >= %d bits to be useful", MinRsaKeyBits) +} diff --git a/core/crypto/rsa_go.go b/core/crypto/rsa_go.go new file mode 100644 index 0000000000..1324447d2e --- /dev/null +++ b/core/crypto/rsa_go.go @@ -0,0 +1,149 @@ +//go:build !openssl +// +build !openssl + +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 an rsa private key +type RsaPrivateKey struct { + sk rsa.PrivateKey +} + +// RsaPublicKey is an 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 + } + 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 an 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 an 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 + } + 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 + } + + return &RsaPublicKey{k: *pk}, nil +} diff --git a/core/crypto/rsa_openssl.go b/core/crypto/rsa_openssl.go new file mode 100644 index 0000000000..4e8269ff49 --- /dev/null +++ b/core/crypto/rsa_openssl.go @@ -0,0 +1,69 @@ +//go:build openssl +// +build openssl + +package crypto + +import ( + "errors" + "io" + + openssl "github.com/libp2p/go-openssl" +) + +// RsaPrivateKey is an rsa private key +type RsaPrivateKey struct { + opensslPrivateKey +} + +// RsaPublicKey is an rsa public key +type RsaPublicKey struct { + opensslPublicKey +} + +// GenerateRSAKeyPair generates a new rsa private and public key +func GenerateRSAKeyPair(bits int, _ io.Reader) (PrivKey, PubKey, error) { + if bits < MinRsaKeyBits { + return nil, nil, ErrRsaKeyTooSmall + } + + key, err := openssl.GenerateRSAKey(bits) + if err != nil { + return nil, nil, err + } + return &RsaPrivateKey{opensslPrivateKey{key}}, &RsaPublicKey{opensslPublicKey{key: key}}, nil +} + +// GetPublic returns a public key +func (sk *RsaPrivateKey) GetPublic() PubKey { + return &RsaPublicKey{opensslPublicKey{key: sk.opensslPrivateKey.key}} +} + +// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes +func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { + key, err := unmarshalOpensslPrivateKey(b) + if err != nil { + return nil, err + } + if 8*key.key.Size() < MinRsaKeyBits { + return nil, ErrRsaKeyTooSmall + } + if key.Type() != RSA { + return nil, errors.New("not actually an rsa public key") + } + return &RsaPrivateKey{key}, nil +} + +// UnmarshalRsaPublicKey returns a public key from the input x509 bytes +func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { + key, err := unmarshalOpensslPublicKey(b) + if err != nil { + return nil, err + } + if 8*key.key.Size() < MinRsaKeyBits { + return nil, ErrRsaKeyTooSmall + } + if key.Type() != RSA { + return nil, errors.New("not actually an rsa public key") + } + return &RsaPublicKey{key}, nil +} diff --git a/core/crypto/rsa_test.go b/core/crypto/rsa_test.go new file mode 100644 index 0000000000..69151b86c9 --- /dev/null +++ b/core/crypto/rsa_test.go @@ -0,0 +1,124 @@ +package crypto + +import ( + "crypto/rand" + "testing" +) + +func TestRSABasicSignAndVerify(t *testing.T) { + priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := []byte("hello! and welcome to some awesome crypto primitives") + + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if !ok { + t.Fatal("signature didnt match") + } + + // change data + data[0] = ^data[0] + ok, err = pub.Verify(data, sig) + if err == nil { + t.Fatal("should have produced a verification error") + } + + if ok { + t.Fatal("signature matched and shouldn't") + } +} + +func TestRSASmallKey(t *testing.T) { + _, _, err := GenerateRSAKeyPair(MinRsaKeyBits/2, rand.Reader) + if err != ErrRsaKeyTooSmall { + t.Fatal("should have refused to create small RSA key") + } + MinRsaKeyBits /= 2 + badPriv, badPub, err := GenerateRSAKeyPair(MinRsaKeyBits, rand.Reader) + if err != nil { + t.Fatalf("should have succeeded, got: %s", err) + } + pubBytes, err := MarshalPublicKey(badPub) + if err != nil { + t.Fatal(err) + } + privBytes, err := MarshalPrivateKey(badPriv) + if err != nil { + t.Fatal(err) + } + MinRsaKeyBits *= 2 + _, err = UnmarshalPublicKey(pubBytes) + if err != ErrRsaKeyTooSmall { + t.Fatal("should have refused to unmarshal a weak key") + } + _, err = UnmarshalPrivateKey(privBytes) + if err != ErrRsaKeyTooSmall { + t.Fatal("should have refused to unmarshal a weak key") + } +} + +func TestRSASignZero(t *testing.T) { + priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := make([]byte, 0) + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal("signature didn't match") + } +} + +func TestRSAMarshalLoop(t *testing.T) { + priv, pub, err := GenerateRSAKeyPair(2048, rand.Reader) + if err != nil { + t.Fatal(err) + } + + privB, err := MarshalPrivateKey(priv) + if err != nil { + t.Fatal(err) + } + + privNew, err := UnmarshalPrivateKey(privB) + if err != nil { + t.Fatal(err) + } + + if !priv.Equals(privNew) || !privNew.Equals(priv) { + t.Fatal("keys are not equal") + } + + pubB, err := MarshalPublicKey(pub) + if err != nil { + t.Fatal(err) + } + pubNew, err := UnmarshalPublicKey(pubB) + if err != nil { + t.Fatal(err) + } + + if !pub.Equals(pubNew) || !pubNew.Equals(pub) { + t.Fatal("keys are not equal") + } +} diff --git a/core/crypto/secp256k1.go b/core/crypto/secp256k1.go new file mode 100644 index 0000000000..fbae309661 --- /dev/null +++ b/core/crypto/secp256k1.go @@ -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" + + btcec "github.com/btcsuite/btcd/btcec/v2" + btcececdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" + "github.com/minio/sha256-simd" +) + +// Secp256k1PrivateKey is an Secp256k1 private key +type Secp256k1PrivateKey btcec.PrivateKey + +// Secp256k1PublicKey is an Secp256k1 public key +type Secp256k1PublicKey btcec.PublicKey + +// GenerateSecp256k1Key generates a new Secp256k1 private and public key pair +func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { + privk, err := btcec.NewPrivateKey() + 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) != btcec.PrivKeyBytesLen { + return nil, fmt.Errorf("expected secp256k1 data size to be %d", btcec.PrivKeyBytesLen) + } + defer func() { catch.HandlePanic(recover(), &err, "secp256k1 private-key unmarshal") }() + + privk, _ := btcec.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 := btcec.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 (*btcec.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 := (*btcec.PrivateKey)(k) + hash := sha256.Sum256(data) + sig := btcececdsa.Sign(key, hash[:]) + + return sig.Serialize(), nil +} + +// GetPublic returns a public key +func (k *Secp256k1PrivateKey) GetPublic() PubKey { + return (*Secp256k1PublicKey)((*btcec.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 (*btcec.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 (*btcec.PublicKey)(k).IsEqual((*btcec.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 := btcececdsa.ParseDERSignature(sigStr) + if err != nil { + return false, err + } + + hash := sha256.Sum256(data) + return sig.Verify(hash[:], (*btcec.PublicKey)(k)), nil +} diff --git a/core/crypto/secp256k1_test.go b/core/crypto/secp256k1_test.go new file mode 100644 index 0000000000..81f2f57884 --- /dev/null +++ b/core/crypto/secp256k1_test.go @@ -0,0 +1,96 @@ +package crypto + +import ( + "crypto/rand" + "testing" +) + +func TestSecp256k1BasicSignAndVerify(t *testing.T) { + priv, pub, err := GenerateSecp256k1Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := []byte("hello! and welcome to some awesome crypto primitives") + + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if !ok { + t.Fatal("signature didnt match") + } + + // change data + data[0] = ^data[0] + ok, err = pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + + if ok { + t.Fatal("signature matched and shouldn't") + } +} + +func TestSecp256k1SignZero(t *testing.T) { + priv, pub, err := GenerateSecp256k1Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + data := make([]byte, 0) + sig, err := priv.Sign(data) + if err != nil { + t.Fatal(err) + } + + ok, err := pub.Verify(data, sig) + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal("signature didn't match") + } +} + +func TestSecp256k1MarshalLoop(t *testing.T) { + priv, pub, err := GenerateSecp256k1Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + privB, err := MarshalPrivateKey(priv) + if err != nil { + t.Fatal(err) + } + + privNew, err := UnmarshalPrivateKey(privB) + if err != nil { + t.Fatal(err) + } + + if !priv.Equals(privNew) || !privNew.Equals(priv) { + t.Fatal("keys are not equal") + } + + pubB, err := MarshalPublicKey(pub) + if err != nil { + t.Fatal(err) + } + pubNew, err := UnmarshalPublicKey(pubB) + if err != nil { + t.Fatal(err) + } + + if !pub.Equals(pubNew) || !pubNew.Equals(pub) { + t.Fatal("keys are not equal") + } + +} diff --git a/core/crypto/test_data/0.priv b/core/crypto/test_data/0.priv new file mode 100644 index 0000000000..9047d5d95d Binary files /dev/null and b/core/crypto/test_data/0.priv differ diff --git a/core/crypto/test_data/0.pub b/core/crypto/test_data/0.pub new file mode 100644 index 0000000000..d4295e8893 Binary files /dev/null and b/core/crypto/test_data/0.pub differ diff --git a/core/crypto/test_data/0.sig b/core/crypto/test_data/0.sig new file mode 100644 index 0000000000..2f16825274 Binary files /dev/null and b/core/crypto/test_data/0.sig differ diff --git a/core/crypto/test_data/2.priv b/core/crypto/test_data/2.priv new file mode 100644 index 0000000000..1004ab9153 --- /dev/null +++ b/core/crypto/test_data/2.priv @@ -0,0 +1 @@ + 1A½`jPLDò4”ØóNò[¹µ-ªÐX¾ƒ¶àF±X \ No newline at end of file diff --git a/core/crypto/test_data/2.pub b/core/crypto/test_data/2.pub new file mode 100644 index 0000000000..dd984bdcc8 --- /dev/null +++ b/core/crypto/test_data/2.pub @@ -0,0 +1 @@ +!5@­„*ø¤5Q©Mƒƒ¥U©’&PkˆùSÒ磡³Ö¢ \ No newline at end of file diff --git a/core/crypto/test_data/2.sig b/core/crypto/test_data/2.sig new file mode 100644 index 0000000000..b96001bc8b --- /dev/null +++ b/core/crypto/test_data/2.sig @@ -0,0 +1 @@ +0D 1§Ö3ÂóäZCuú¨Ü›¢@’Åõ³ÊÒÈþLóˆò Iê!ŸE†ƒÒGuÕCê²pCGû5I<@;ÂÂY²ž \ No newline at end of file diff --git a/core/crypto/test_data/3.priv b/core/crypto/test_data/3.priv new file mode 100644 index 0000000000..7a05f359f8 Binary files /dev/null and b/core/crypto/test_data/3.priv differ diff --git a/core/crypto/test_data/3.pub b/core/crypto/test_data/3.pub new file mode 100644 index 0000000000..f4551f8811 Binary files /dev/null and b/core/crypto/test_data/3.pub differ diff --git a/core/crypto/test_data/3.sig b/core/crypto/test_data/3.sig new file mode 100644 index 0000000000..253c09f6d7 Binary files /dev/null and b/core/crypto/test_data/3.sig differ diff --git a/core/discovery/discovery.go b/core/discovery/discovery.go new file mode 100644 index 0000000000..feeb2c7970 --- /dev/null +++ b/core/discovery/discovery.go @@ -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 +} diff --git a/core/discovery/options.go b/core/discovery/options.go new file mode 100644 index 0000000000..7b28305268 --- /dev/null +++ b/core/discovery/options.go @@ -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 + } +} diff --git a/core/event/addrs.go b/core/event/addrs.go new file mode 100644 index 0000000000..67026d1783 --- /dev/null +++ b/core/event/addrs.go @@ -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 +} diff --git a/core/event/bus.go b/core/event/bus.go new file mode 100644 index 0000000000..0cd8d2ff7c --- /dev/null +++ b/core/event/bus.go @@ -0,0 +1,97 @@ +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 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{} +} + +// 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 +} diff --git a/core/event/dht.go b/core/event/dht.go new file mode 100644 index 0000000000..e01953f1d2 --- /dev/null +++ b/core/event/dht.go @@ -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 occured. + Type string + + // Raw is the raw JSON representation of the event payload. + Raw RawJSON +} diff --git a/core/event/doc.go b/core/event/doc.go new file mode 100644 index 0000000000..7ba4bd6f45 --- /dev/null +++ b/core/event/doc.go @@ -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 diff --git a/core/event/identify.go b/core/event/identify.go new file mode 100644 index 0000000000..ff14995872 --- /dev/null +++ b/core/event/identify.go @@ -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 +} diff --git a/core/event/nattype.go b/core/event/nattype.go new file mode 100644 index 0000000000..21ecdebd5f --- /dev/null +++ b/core/event/nattype.go @@ -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 +} diff --git a/core/event/network.go b/core/event/network.go new file mode 100644 index 0000000000..37e9177d2f --- /dev/null +++ b/core/event/network.go @@ -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 of 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 re-try network requests. +type EvtPeerConnectednessChanged struct { + // Peer is the remote peer who's connectedness has changed. + Peer peer.ID + // Connectedness is the new connectedness state. + Connectedness network.Connectedness +} diff --git a/core/event/protocol.go b/core/event/protocol.go new file mode 100644 index 0000000000..b8f1fe637c --- /dev/null +++ b/core/event/protocol.go @@ -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 +} diff --git a/core/event/reachability.go b/core/event/reachability.go new file mode 100644 index 0000000000..6ab4523851 --- /dev/null +++ b/core/event/reachability.go @@ -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 +} diff --git a/core/host/helpers.go b/core/host/helpers.go new file mode 100644 index 0000000000..e57f326a7c --- /dev/null +++ b/core/host/helpers.go @@ -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(), + } +} diff --git a/core/host/host.go b/core/host/host.go new file mode 100644 index 0000000000..cfea91e5ba --- /dev/null +++ b/core/host/host.go @@ -0,0 +1,89 @@ +// 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/introspection" + "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) + // (Threadsafe) + 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(string) 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. + // (Threadsafe) + 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 +} + +// IntrospectableHost is implemented by Host implementations that are +// introspectable, that is, that may have introspection capability. +type IntrospectableHost interface { + // Introspector returns the introspector, or nil if one hasn't been + // registered. With it, the call can register data providers, and can fetch + // introspection data. + Introspector() introspection.Introspector + + // IntrospectionEndpoint returns the introspection endpoint, or nil if one + // hasn't been registered. + IntrospectionEndpoint() introspection.Endpoint +} diff --git a/core/internal/catch/catch.go b/core/internal/catch/catch.go new file mode 100644 index 0000000000..c61ee2aa3d --- /dev/null +++ b/core/internal/catch/catch.go @@ -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) + } +} diff --git a/core/internal/catch/catch_test.go b/core/internal/catch/catch_test.go new file mode 100644 index 0000000000..1674f4f4df --- /dev/null +++ b/core/internal/catch/catch_test.go @@ -0,0 +1,28 @@ +package catch + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCatch(t *testing.T) { + buf := new(bytes.Buffer) + + oldPanicWriter := panicWriter + t.Cleanup(func() { panicWriter = oldPanicWriter }) + panicWriter = buf + + panicAndCatch := func() (err error) { + defer func() { HandlePanic(recover(), &err, "somewhere") }() + + panic("here") + } + + err := panicAndCatch() + require.Error(t, err) + require.Contains(t, err.Error(), "panic in somewhere: here") + + require.Contains(t, buf.String(), "caught panic: here") +} diff --git a/core/introspection/doc.go b/core/introspection/doc.go new file mode 100644 index 0000000000..302c23f4cb --- /dev/null +++ b/core/introspection/doc.go @@ -0,0 +1,7 @@ +// Package introspection is EXPERIMENTAL. It is subject to heavy change, and it +// WILL change. For now, it is the simplest implementation to power the +// proof-of-concept of the libp2p introspection framework. +// +// Package introspect contains the abstract skeleton of the introspection system +// of go-libp2p, and holds the introspection data schema. +package introspection diff --git a/core/introspection/endpoint.go b/core/introspection/endpoint.go new file mode 100644 index 0000000000..51596a4644 --- /dev/null +++ b/core/introspection/endpoint.go @@ -0,0 +1,30 @@ +package introspection + +// Endpoint is the interface to be implemented by introspection endpoints. +// +// An introspection endpoint makes introspection data accessible to external +// consumers, over, for example, WebSockets, or TCP, or libp2p itself. +// +// Experimental. +type Endpoint interface { + // Start starts the introspection endpoint. It must only be called once, and + // once the server is started, subsequent calls made without first calling + // Close will error. + Start() error + + // Close stops the introspection endpoint. Calls to Close on an already + // closed endpoint (or an unstarted endpoint) must noop. + Close() error + + // ListenAddrs returns the listen addresses of this endpoint. + ListenAddrs() []string + + // Sessions returns the ongoing sessions of this endpoint. + Sessions() []*Session +} + +// Session represents an introspection session. +type Session struct { + // RemoteAddr is the remote address of the session. + RemoteAddr string +} diff --git a/core/introspection/introspector.go b/core/introspection/introspector.go new file mode 100644 index 0000000000..e39f9673bb --- /dev/null +++ b/core/introspection/introspector.go @@ -0,0 +1,39 @@ +package introspection + +import ( + "io" + + "github.com/libp2p/go-libp2p/core/introspection/pb" +) + +// Introspector is the interface to be satisfied by components that are capable +// of spelunking the state of the system, and representing in accordance with +// the introspection schema. +// +// It's very rare to build a custom implementation of this interface; +// it exists mostly for mocking. In most cases, you'll end up using the +// default introspector. +// +// Introspector implementations are usually injected in introspection endpoints +// to serve the data to clients, but they can also be used separately for +// embedding or testing. +// +// Experimental. +type Introspector interface { + io.Closer + + // FetchRuntime returns the runtime information of the system. + FetchRuntime() (*pb.Runtime, error) + + // FetchFullState returns the full state cross-cut of the running system. + FetchFullState() (*pb.State, error) + + // EventChan returns the channel where all eventbus events are dumped, + // decorated with their corresponding event metadata, ready to send over + // the wire. + EventChan() <-chan *pb.Event + + // EventMetadata returns the metadata of all events known to the + // Introspector. + EventMetadata() []*pb.EventType +} diff --git a/core/introspection/pb/Makefile b/core/introspection/pb/Makefile new file mode 100644 index 0000000000..731317654d --- /dev/null +++ b/core/introspection/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(PWD):$(PWD)/../..:$(GOPATH)/src --gogofaster_out=Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types:. $< + +clean: + rm -f *.pb.go + rm -f *.go \ No newline at end of file diff --git a/core/introspection/pb/doc.go b/core/introspection/pb/doc.go new file mode 100644 index 0000000000..58f6c50db2 --- /dev/null +++ b/core/introspection/pb/doc.go @@ -0,0 +1,3 @@ +// Package introspection/pb contains the protobuf definitions and objects for +// that form the libp2p introspection protocol. +package pb diff --git a/core/introspection/pb/introspection.pb.go b/core/introspection/pb/introspection.pb.go new file mode 100644 index 0000000000..b8c609d82c --- /dev/null +++ b/core/introspection/pb/introspection.pb.go @@ -0,0 +1,9718 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: introspection.proto + +package pb + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// The status of a connection or stream. +type Status int32 + +const ( + Status_ACTIVE Status = 0 + Status_CLOSED Status = 1 + Status_OPENING Status = 2 + Status_CLOSING Status = 3 + Status_ERROR Status = 4 +) + +var Status_name = map[int32]string{ + 0: "ACTIVE", + 1: "CLOSED", + 2: "OPENING", + 3: "CLOSING", + 4: "ERROR", +} + +var Status_value = map[string]int32{ + "ACTIVE": 0, + "CLOSED": 1, + "OPENING": 2, + "CLOSING": 3, + "ERROR": 4, +} + +func (x Status) String() string { + return proto.EnumName(Status_name, int32(x)) +} + +func (Status) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{0} +} + +// Our role in a connection or stream. +type Role int32 + +const ( + Role_INITIATOR Role = 0 + Role_RESPONDER Role = 1 +) + +var Role_name = map[int32]string{ + 0: "INITIATOR", + 1: "RESPONDER", +} + +var Role_value = map[string]int32{ + "INITIATOR": 0, + "RESPONDER": 1, +} + +func (x Role) String() string { + return proto.EnumName(Role_name, int32(x)) +} + +func (Role) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{1} +} + +// tells client how to sort, filter or display known content properties +type EventType_EventProperty_PropertyType int32 + +const ( + // for properties to treat as a simple primitive + EventType_EventProperty_STRING EventType_EventProperty_PropertyType = 0 + EventType_EventProperty_NUMBER EventType_EventProperty_PropertyType = 1 + // for properties with special human-readable formatting + EventType_EventProperty_TIME EventType_EventProperty_PropertyType = 10 + EventType_EventProperty_PEERID EventType_EventProperty_PropertyType = 11 + EventType_EventProperty_MULTIADDR EventType_EventProperty_PropertyType = 12 + // for complex structures like nested arrays, object trees etc + EventType_EventProperty_JSON EventType_EventProperty_PropertyType = 90 +) + +var EventType_EventProperty_PropertyType_name = map[int32]string{ + 0: "STRING", + 1: "NUMBER", + 10: "TIME", + 11: "PEERID", + 12: "MULTIADDR", + 90: "JSON", +} + +var EventType_EventProperty_PropertyType_value = map[string]int32{ + "STRING": 0, + "NUMBER": 1, + "TIME": 10, + "PEERID": 11, + "MULTIADDR": 12, + "JSON": 90, +} + +func (x EventType_EventProperty_PropertyType) String() string { + return proto.EnumName(EventType_EventProperty_PropertyType_name, int32(x)) +} + +func (EventType_EventProperty_PropertyType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{4, 0, 0} +} + +// The DHT's relationship with this peer +type DHT_PeerInDHT_Status int32 + +const ( + // Connected, in a bucket, ready to send/receive queries + DHT_PeerInDHT_ACTIVE DHT_PeerInDHT_Status = 0 + // Not currently connected, still "in" a bucket (e.g. temporarily disconnected) + DHT_PeerInDHT_MISSING DHT_PeerInDHT_Status = 1 + // Removed from a bucket or candidate list (e.g. connection lost or too slow) + DHT_PeerInDHT_REJECTED DHT_PeerInDHT_Status = 2 + // Was reachable when last checked, waiting to join a currently-full bucket + DHT_PeerInDHT_CANDIDATE DHT_PeerInDHT_Status = 3 +) + +var DHT_PeerInDHT_Status_name = map[int32]string{ + 0: "ACTIVE", + 1: "MISSING", + 2: "REJECTED", + 3: "CANDIDATE", +} + +var DHT_PeerInDHT_Status_value = map[string]int32{ + "ACTIVE": 0, + "MISSING": 1, + "REJECTED": 2, + "CANDIDATE": 3, +} + +func (x DHT_PeerInDHT_Status) String() string { + return proto.EnumName(DHT_PeerInDHT_Status_name, int32(x)) +} + +func (DHT_PeerInDHT_Status) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{11, 1, 0} +} + +type ClientCommand_Source int32 + +const ( + ClientCommand_STATE ClientCommand_Source = 0 + ClientCommand_RUNTIME ClientCommand_Source = 1 + ClientCommand_EVENTS ClientCommand_Source = 2 +) + +var ClientCommand_Source_name = map[int32]string{ + 0: "STATE", + 1: "RUNTIME", + 2: "EVENTS", +} + +var ClientCommand_Source_value = map[string]int32{ + "STATE": 0, + "RUNTIME": 1, + "EVENTS": 2, +} + +func (x ClientCommand_Source) String() string { + return proto.EnumName(ClientCommand_Source_name, int32(x)) +} + +func (ClientCommand_Source) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{17, 0} +} + +type ClientCommand_Command int32 + +const ( + // HELLO is the first command that a client must send to greet the server. + // Connections that do not respect this invariant will be terminated. + ClientCommand_HELLO ClientCommand_Command = 0 + // REQUEST is applicable to STATE and RUNTIME sources. + ClientCommand_REQUEST ClientCommand_Command = 1 + // PUSH streams can only be started for STATE and EVENTS sources. + ClientCommand_PUSH_ENABLE ClientCommand_Command = 2 + ClientCommand_PUSH_DISABLE ClientCommand_Command = 3 + ClientCommand_PUSH_PAUSE ClientCommand_Command = 4 + ClientCommand_PUSH_RESUME ClientCommand_Command = 5 + // UPDATE_CONFIG requests a configuration update. The config field is + // compulsory. + // + // The server reserves the right to override the requested values, and + // will return the effective configuration in the response. + ClientCommand_UPDATE_CONFIG ClientCommand_Command = 7 +) + +var ClientCommand_Command_name = map[int32]string{ + 0: "HELLO", + 1: "REQUEST", + 2: "PUSH_ENABLE", + 3: "PUSH_DISABLE", + 4: "PUSH_PAUSE", + 5: "PUSH_RESUME", + 7: "UPDATE_CONFIG", +} + +var ClientCommand_Command_value = map[string]int32{ + "HELLO": 0, + "REQUEST": 1, + "PUSH_ENABLE": 2, + "PUSH_DISABLE": 3, + "PUSH_PAUSE": 4, + "PUSH_RESUME": 5, + "UPDATE_CONFIG": 7, +} + +func (x ClientCommand_Command) String() string { + return proto.EnumName(ClientCommand_Command_name, int32(x)) +} + +func (ClientCommand_Command) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{17, 1} +} + +type CommandResponse_Result int32 + +const ( + CommandResponse_OK CommandResponse_Result = 0 + CommandResponse_ERR CommandResponse_Result = 1 +) + +var CommandResponse_Result_name = map[int32]string{ + 0: "OK", + 1: "ERR", +} + +var CommandResponse_Result_value = map[string]int32{ + "OK": 0, + "ERR": 1, +} + +func (x CommandResponse_Result) String() string { + return proto.EnumName(CommandResponse_Result_name, int32(x)) +} + +func (CommandResponse_Result) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{18, 0} +} + +type ServerNotice_Kind int32 + +const ( + ServerNotice_DISCARDING_EVENTS ServerNotice_Kind = 0 +) + +var ServerNotice_Kind_name = map[int32]string{ + 0: "DISCARDING_EVENTS", +} + +var ServerNotice_Kind_value = map[string]int32{ + "DISCARDING_EVENTS": 0, +} + +func (x ServerNotice_Kind) String() string { + return proto.EnumName(ServerNotice_Kind_name, int32(x)) +} + +func (ServerNotice_Kind) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{19, 0} +} + +// Version of schema +type Version struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` +} + +func (m *Version) Reset() { *m = Version{} } +func (m *Version) String() string { return proto.CompactTextString(m) } +func (*Version) ProtoMessage() {} +func (*Version) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{0} +} +func (m *Version) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Version.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Version) XXX_Merge(src proto.Message) { + xxx_messageInfo_Version.Merge(m, src) +} +func (m *Version) XXX_Size() int { + return m.Size() +} +func (m *Version) XXX_DiscardUnknown() { + xxx_messageInfo_Version.DiscardUnknown(m) +} + +var xxx_messageInfo_Version proto.InternalMessageInfo + +func (m *Version) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +// ResultCounter is a monotonically increasing counter that reports an ok/err breakdown of the total. +type ResultCounter struct { + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + Ok uint32 `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"` + Err uint32 `protobuf:"varint,3,opt,name=err,proto3" json:"err,omitempty"` +} + +func (m *ResultCounter) Reset() { *m = ResultCounter{} } +func (m *ResultCounter) String() string { return proto.CompactTextString(m) } +func (*ResultCounter) ProtoMessage() {} +func (*ResultCounter) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{1} +} +func (m *ResultCounter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResultCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ResultCounter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ResultCounter) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResultCounter.Merge(m, src) +} +func (m *ResultCounter) XXX_Size() int { + return m.Size() +} +func (m *ResultCounter) XXX_DiscardUnknown() { + xxx_messageInfo_ResultCounter.DiscardUnknown(m) +} + +var xxx_messageInfo_ResultCounter proto.InternalMessageInfo + +func (m *ResultCounter) GetTotal() uint32 { + if m != nil { + return m.Total + } + return 0 +} + +func (m *ResultCounter) GetOk() uint32 { + if m != nil { + return m.Ok + } + return 0 +} + +func (m *ResultCounter) GetErr() uint32 { + if m != nil { + return m.Err + } + return 0 +} + +// Moving totals over sliding time windows. Models sensible time windows, +// we don't have to populate them all at once. +// +// Graphical example: +// +// time past -> present an event 16 min ago +// ======================================================X================>> +// +// | | 1m +// | |---| 5m +// | |-------------| 15m +// |------------X---------------| 30m +// |------------------------------------------X---------------| 60m +type SlidingCounter struct { + Over_1M uint32 `protobuf:"varint,1,opt,name=over_1m,json=over1m,proto3" json:"over_1m,omitempty"` + Over_5M uint32 `protobuf:"varint,2,opt,name=over_5m,json=over5m,proto3" json:"over_5m,omitempty"` + Over_15M uint32 `protobuf:"varint,3,opt,name=over_15m,json=over15m,proto3" json:"over_15m,omitempty"` + Over_30M uint32 `protobuf:"varint,4,opt,name=over_30m,json=over30m,proto3" json:"over_30m,omitempty"` + Over_1Hr uint32 `protobuf:"varint,5,opt,name=over_1hr,json=over1hr,proto3" json:"over_1hr,omitempty"` + Over_2Hr uint32 `protobuf:"varint,6,opt,name=over_2hr,json=over2hr,proto3" json:"over_2hr,omitempty"` + Over_4Hr uint32 `protobuf:"varint,7,opt,name=over_4hr,json=over4hr,proto3" json:"over_4hr,omitempty"` + Over_8Hr uint32 `protobuf:"varint,8,opt,name=over_8hr,json=over8hr,proto3" json:"over_8hr,omitempty"` + Over_12Hr uint32 `protobuf:"varint,9,opt,name=over_12hr,json=over12hr,proto3" json:"over_12hr,omitempty"` + Over_24Hr uint32 `protobuf:"varint,10,opt,name=over_24hr,json=over24hr,proto3" json:"over_24hr,omitempty"` +} + +func (m *SlidingCounter) Reset() { *m = SlidingCounter{} } +func (m *SlidingCounter) String() string { return proto.CompactTextString(m) } +func (*SlidingCounter) ProtoMessage() {} +func (*SlidingCounter) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{2} +} +func (m *SlidingCounter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SlidingCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SlidingCounter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SlidingCounter) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlidingCounter.Merge(m, src) +} +func (m *SlidingCounter) XXX_Size() int { + return m.Size() +} +func (m *SlidingCounter) XXX_DiscardUnknown() { + xxx_messageInfo_SlidingCounter.DiscardUnknown(m) +} + +var xxx_messageInfo_SlidingCounter proto.InternalMessageInfo + +func (m *SlidingCounter) GetOver_1M() uint32 { + if m != nil { + return m.Over_1M + } + return 0 +} + +func (m *SlidingCounter) GetOver_5M() uint32 { + if m != nil { + return m.Over_5M + } + return 0 +} + +func (m *SlidingCounter) GetOver_15M() uint32 { + if m != nil { + return m.Over_15M + } + return 0 +} + +func (m *SlidingCounter) GetOver_30M() uint32 { + if m != nil { + return m.Over_30M + } + return 0 +} + +func (m *SlidingCounter) GetOver_1Hr() uint32 { + if m != nil { + return m.Over_1Hr + } + return 0 +} + +func (m *SlidingCounter) GetOver_2Hr() uint32 { + if m != nil { + return m.Over_2Hr + } + return 0 +} + +func (m *SlidingCounter) GetOver_4Hr() uint32 { + if m != nil { + return m.Over_4Hr + } + return 0 +} + +func (m *SlidingCounter) GetOver_8Hr() uint32 { + if m != nil { + return m.Over_8Hr + } + return 0 +} + +func (m *SlidingCounter) GetOver_12Hr() uint32 { + if m != nil { + return m.Over_12Hr + } + return 0 +} + +func (m *SlidingCounter) GetOver_24Hr() uint32 { + if m != nil { + return m.Over_24Hr + } + return 0 +} + +// DataGauge reports stats for data traffic in a given direction. +type DataGauge struct { + // Cumulative bytes. + CumBytes uint64 `protobuf:"varint,1,opt,name=cum_bytes,json=cumBytes,proto3" json:"cum_bytes,omitempty"` + // Cumulative packets. + CumPackets uint64 `protobuf:"varint,2,opt,name=cum_packets,json=cumPackets,proto3" json:"cum_packets,omitempty"` + // Instantaneous bandwidth measurement (bytes/second). + InstBw uint64 `protobuf:"varint,3,opt,name=inst_bw,json=instBw,proto3" json:"inst_bw,omitempty"` +} + +func (m *DataGauge) Reset() { *m = DataGauge{} } +func (m *DataGauge) String() string { return proto.CompactTextString(m) } +func (*DataGauge) ProtoMessage() {} +func (*DataGauge) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{3} +} +func (m *DataGauge) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DataGauge) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DataGauge.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DataGauge) XXX_Merge(src proto.Message) { + xxx_messageInfo_DataGauge.Merge(m, src) +} +func (m *DataGauge) XXX_Size() int { + return m.Size() +} +func (m *DataGauge) XXX_DiscardUnknown() { + xxx_messageInfo_DataGauge.DiscardUnknown(m) +} + +var xxx_messageInfo_DataGauge proto.InternalMessageInfo + +func (m *DataGauge) GetCumBytes() uint64 { + if m != nil { + return m.CumBytes + } + return 0 +} + +func (m *DataGauge) GetCumPackets() uint64 { + if m != nil { + return m.CumPackets + } + return 0 +} + +func (m *DataGauge) GetInstBw() uint64 { + if m != nil { + return m.InstBw + } + return 0 +} + +// describes a type of event +type EventType struct { + // name of event type, e.g. PeerConnecting + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // for runtime, send property_types for all events already seen in events list + // for events, only send property_types in the first event of a type not in runtime + PropertyTypes []*EventType_EventProperty `protobuf:"bytes,2,rep,name=property_types,json=propertyTypes,proto3" json:"property_types,omitempty"` +} + +func (m *EventType) Reset() { *m = EventType{} } +func (m *EventType) String() string { return proto.CompactTextString(m) } +func (*EventType) ProtoMessage() {} +func (*EventType) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{4} +} +func (m *EventType) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventType.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventType) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventType.Merge(m, src) +} +func (m *EventType) XXX_Size() int { + return m.Size() +} +func (m *EventType) XXX_DiscardUnknown() { + xxx_messageInfo_EventType.DiscardUnknown(m) +} + +var xxx_messageInfo_EventType proto.InternalMessageInfo + +func (m *EventType) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *EventType) GetPropertyTypes() []*EventType_EventProperty { + if m != nil { + return m.PropertyTypes + } + return nil +} + +// metadata about content types in event's top-level content JSON +type EventType_EventProperty struct { + // property name of content e.g. openTs + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // type to interpret content value as + Type EventType_EventProperty_PropertyType `protobuf:"varint,2,opt,name=type,proto3,enum=pb.EventType_EventProperty_PropertyType" json:"type,omitempty"` + // if true, expect an array of values of `type`; else, singular + HasMultiple bool `protobuf:"varint,3,opt,name=has_multiple,json=hasMultiple,proto3" json:"has_multiple,omitempty"` +} + +func (m *EventType_EventProperty) Reset() { *m = EventType_EventProperty{} } +func (m *EventType_EventProperty) String() string { return proto.CompactTextString(m) } +func (*EventType_EventProperty) ProtoMessage() {} +func (*EventType_EventProperty) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{4, 0} +} +func (m *EventType_EventProperty) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventType_EventProperty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventType_EventProperty.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EventType_EventProperty) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventType_EventProperty.Merge(m, src) +} +func (m *EventType_EventProperty) XXX_Size() int { + return m.Size() +} +func (m *EventType_EventProperty) XXX_DiscardUnknown() { + xxx_messageInfo_EventType_EventProperty.DiscardUnknown(m) +} + +var xxx_messageInfo_EventType_EventProperty proto.InternalMessageInfo + +func (m *EventType_EventProperty) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *EventType_EventProperty) GetType() EventType_EventProperty_PropertyType { + if m != nil { + return m.Type + } + return EventType_EventProperty_STRING +} + +func (m *EventType_EventProperty) GetHasMultiple() bool { + if m != nil { + return m.HasMultiple + } + return false +} + +// Runtime encapsulates runtime info about a node. +type Runtime struct { + // e.g. go-libp2p, js-libp2p, rust-libp2p, etc. + Implementation string `protobuf:"bytes,1,opt,name=implementation,proto3" json:"implementation,omitempty"` + // e.g. 1.2.3. + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + // e.g. Windows, Unix, macOS, Chrome, Mozilla, etc. + Platform string `protobuf:"bytes,3,opt,name=platform,proto3" json:"platform,omitempty"` + // our peer id - the peer id of the host system + PeerId string `protobuf:"bytes,4,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + // metadata describing configured event types + EventTypes []*EventType `protobuf:"bytes,7,rep,name=event_types,json=eventTypes,proto3" json:"event_types,omitempty"` +} + +func (m *Runtime) Reset() { *m = Runtime{} } +func (m *Runtime) String() string { return proto.CompactTextString(m) } +func (*Runtime) ProtoMessage() {} +func (*Runtime) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{5} +} +func (m *Runtime) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Runtime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Runtime.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Runtime) XXX_Merge(src proto.Message) { + xxx_messageInfo_Runtime.Merge(m, src) +} +func (m *Runtime) XXX_Size() int { + return m.Size() +} +func (m *Runtime) XXX_DiscardUnknown() { + xxx_messageInfo_Runtime.DiscardUnknown(m) +} + +var xxx_messageInfo_Runtime proto.InternalMessageInfo + +func (m *Runtime) GetImplementation() string { + if m != nil { + return m.Implementation + } + return "" +} + +func (m *Runtime) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *Runtime) GetPlatform() string { + if m != nil { + return m.Platform + } + return "" +} + +func (m *Runtime) GetPeerId() string { + if m != nil { + return m.PeerId + } + return "" +} + +func (m *Runtime) GetEventTypes() []*EventType { + if m != nil { + return m.EventTypes + } + return nil +} + +// EndpointPair is a pair of multiaddrs. +type EndpointPair struct { + // the source multiaddr. + SrcMultiaddr string `protobuf:"bytes,1,opt,name=src_multiaddr,json=srcMultiaddr,proto3" json:"src_multiaddr,omitempty"` + // the destination multiaddr. + DstMultiaddr string `protobuf:"bytes,2,opt,name=dst_multiaddr,json=dstMultiaddr,proto3" json:"dst_multiaddr,omitempty"` +} + +func (m *EndpointPair) Reset() { *m = EndpointPair{} } +func (m *EndpointPair) String() string { return proto.CompactTextString(m) } +func (*EndpointPair) ProtoMessage() {} +func (*EndpointPair) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{6} +} +func (m *EndpointPair) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EndpointPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EndpointPair.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EndpointPair) XXX_Merge(src proto.Message) { + xxx_messageInfo_EndpointPair.Merge(m, src) +} +func (m *EndpointPair) XXX_Size() int { + return m.Size() +} +func (m *EndpointPair) XXX_DiscardUnknown() { + xxx_messageInfo_EndpointPair.DiscardUnknown(m) +} + +var xxx_messageInfo_EndpointPair proto.InternalMessageInfo + +func (m *EndpointPair) GetSrcMultiaddr() string { + if m != nil { + return m.SrcMultiaddr + } + return "" +} + +func (m *EndpointPair) GetDstMultiaddr() string { + if m != nil { + return m.DstMultiaddr + } + return "" +} + +// Traffic encloses data transfer statistics. +type Traffic struct { + // snapshot of the data in metrics. + TrafficIn *DataGauge `protobuf:"bytes,1,opt,name=traffic_in,json=trafficIn,proto3" json:"traffic_in,omitempty"` + // snapshot of the data out metrics. + TrafficOut *DataGauge `protobuf:"bytes,2,opt,name=traffic_out,json=trafficOut,proto3" json:"traffic_out,omitempty"` +} + +func (m *Traffic) Reset() { *m = Traffic{} } +func (m *Traffic) String() string { return proto.CompactTextString(m) } +func (*Traffic) ProtoMessage() {} +func (*Traffic) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{7} +} +func (m *Traffic) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Traffic) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Traffic.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Traffic) XXX_Merge(src proto.Message) { + xxx_messageInfo_Traffic.Merge(m, src) +} +func (m *Traffic) XXX_Size() int { + return m.Size() +} +func (m *Traffic) XXX_DiscardUnknown() { + xxx_messageInfo_Traffic.DiscardUnknown(m) +} + +var xxx_messageInfo_Traffic proto.InternalMessageInfo + +func (m *Traffic) GetTrafficIn() *DataGauge { + if m != nil { + return m.TrafficIn + } + return nil +} + +func (m *Traffic) GetTrafficOut() *DataGauge { + if m != nil { + return m.TrafficOut + } + return nil +} + +// a list of streams, by reference or inlined. +type StreamList struct { + // NOTE: only one of the next 2 fields can appear, but proto3 + // doesn't support combining oneof and repeated. + // + // streams within this connection by reference. + StreamIds [][]byte `protobuf:"bytes,1,rep,name=stream_ids,json=streamIds,proto3" json:"stream_ids,omitempty"` + // streams within this connection by inlining. + Streams []*Stream `protobuf:"bytes,2,rep,name=streams,proto3" json:"streams,omitempty"` +} + +func (m *StreamList) Reset() { *m = StreamList{} } +func (m *StreamList) String() string { return proto.CompactTextString(m) } +func (*StreamList) ProtoMessage() {} +func (*StreamList) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{8} +} +func (m *StreamList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StreamList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StreamList.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StreamList) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamList.Merge(m, src) +} +func (m *StreamList) XXX_Size() int { + return m.Size() +} +func (m *StreamList) XXX_DiscardUnknown() { + xxx_messageInfo_StreamList.DiscardUnknown(m) +} + +var xxx_messageInfo_StreamList proto.InternalMessageInfo + +func (m *StreamList) GetStreamIds() [][]byte { + if m != nil { + return m.StreamIds + } + return nil +} + +func (m *StreamList) GetStreams() []*Stream { + if m != nil { + return m.Streams + } + return nil +} + +// Connection reports metrics and state of a libp2p connection. +type Connection struct { + // the id of this connection, not to be shown in user tooling, + // used for (cross)referencing connections (e.g. relay). + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // the peer id of the other party. + PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + // the status of this connection. + Status Status `protobuf:"varint,3,opt,name=status,proto3,enum=pb.Status" json:"status,omitempty"` + // a reference to the transport managing this connection. + TransportId []byte `protobuf:"bytes,4,opt,name=transport_id,json=transportId,proto3" json:"transport_id,omitempty"` + // the endpoints participating in this connection. + Endpoints *EndpointPair `protobuf:"bytes,5,opt,name=endpoints,proto3" json:"endpoints,omitempty"` + // the timeline of the connection, see Connection.Timeline. + Timeline *Connection_Timeline `protobuf:"bytes,6,opt,name=timeline,proto3" json:"timeline,omitempty"` + // our role in this connection. + Role Role `protobuf:"varint,7,opt,name=role,proto3,enum=pb.Role" json:"role,omitempty"` + // traffic statistics. + Traffic *Traffic `protobuf:"bytes,8,opt,name=traffic,proto3" json:"traffic,omitempty"` + // properties of this connection. + Attribs *Connection_Attributes `protobuf:"bytes,9,opt,name=attribs,proto3" json:"attribs,omitempty"` + // the instantaneous latency of this connection in nanoseconds. + LatencyNs uint64 `protobuf:"varint,10,opt,name=latency_ns,json=latencyNs,proto3" json:"latency_ns,omitempty"` + // streams within this connection. + Streams *StreamList `protobuf:"bytes,11,opt,name=streams,proto3" json:"streams,omitempty"` + // if this is a relayed connection, this points to the relaying connection. + // a default value here (empty bytes) indicates this is not a relayed connection. + // + // Types that are valid to be assigned to RelayedOver: + // *Connection_ConnId + // *Connection_Conn + RelayedOver isConnection_RelayedOver `protobuf_oneof:"relayed_over"` + // user provided tags. + UserProvidedTags []string `protobuf:"bytes,99,rep,name=user_provided_tags,json=userProvidedTags,proto3" json:"user_provided_tags,omitempty"` +} + +func (m *Connection) Reset() { *m = Connection{} } +func (m *Connection) String() string { return proto.CompactTextString(m) } +func (*Connection) ProtoMessage() {} +func (*Connection) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{9} +} +func (m *Connection) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Connection) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Connection.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Connection) XXX_Merge(src proto.Message) { + xxx_messageInfo_Connection.Merge(m, src) +} +func (m *Connection) XXX_Size() int { + return m.Size() +} +func (m *Connection) XXX_DiscardUnknown() { + xxx_messageInfo_Connection.DiscardUnknown(m) +} + +var xxx_messageInfo_Connection proto.InternalMessageInfo + +type isConnection_RelayedOver interface { + isConnection_RelayedOver() + MarshalTo([]byte) (int, error) + Size() int +} + +type Connection_ConnId struct { + ConnId []byte `protobuf:"bytes,16,opt,name=conn_id,json=connId,proto3,oneof" json:"conn_id,omitempty"` +} +type Connection_Conn struct { + Conn *Connection `protobuf:"bytes,17,opt,name=conn,proto3,oneof" json:"conn,omitempty"` +} + +func (*Connection_ConnId) isConnection_RelayedOver() {} +func (*Connection_Conn) isConnection_RelayedOver() {} + +func (m *Connection) GetRelayedOver() isConnection_RelayedOver { + if m != nil { + return m.RelayedOver + } + return nil +} + +func (m *Connection) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Connection) GetPeerId() string { + if m != nil { + return m.PeerId + } + return "" +} + +func (m *Connection) GetStatus() Status { + if m != nil { + return m.Status + } + return Status_ACTIVE +} + +func (m *Connection) GetTransportId() []byte { + if m != nil { + return m.TransportId + } + return nil +} + +func (m *Connection) GetEndpoints() *EndpointPair { + if m != nil { + return m.Endpoints + } + return nil +} + +func (m *Connection) GetTimeline() *Connection_Timeline { + if m != nil { + return m.Timeline + } + return nil +} + +func (m *Connection) GetRole() Role { + if m != nil { + return m.Role + } + return Role_INITIATOR +} + +func (m *Connection) GetTraffic() *Traffic { + if m != nil { + return m.Traffic + } + return nil +} + +func (m *Connection) GetAttribs() *Connection_Attributes { + if m != nil { + return m.Attribs + } + return nil +} + +func (m *Connection) GetLatencyNs() uint64 { + if m != nil { + return m.LatencyNs + } + return 0 +} + +func (m *Connection) GetStreams() *StreamList { + if m != nil { + return m.Streams + } + return nil +} + +func (m *Connection) GetConnId() []byte { + if x, ok := m.GetRelayedOver().(*Connection_ConnId); ok { + return x.ConnId + } + return nil +} + +func (m *Connection) GetConn() *Connection { + if x, ok := m.GetRelayedOver().(*Connection_Conn); ok { + return x.Conn + } + return nil +} + +func (m *Connection) GetUserProvidedTags() []string { + if m != nil { + return m.UserProvidedTags + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Connection) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Connection_ConnId)(nil), + (*Connection_Conn)(nil), + } +} + +// Timeline contains the timestamps (ms since epoch) of the well-known milestones of a connection. +type Connection_Timeline struct { + // the instant when a connection was opened on the wire. + OpenTs uint64 `protobuf:"varint,1,opt,name=open_ts,json=openTs,proto3" json:"open_ts,omitempty"` + // the instant when the upgrade process (handshake, security, multiplexing) finished. + UpgradedTs uint64 `protobuf:"varint,2,opt,name=upgraded_ts,json=upgradedTs,proto3" json:"upgraded_ts,omitempty"` + // the instant when this connection was terminated. + CloseTs uint64 `protobuf:"varint,3,opt,name=close_ts,json=closeTs,proto3" json:"close_ts,omitempty"` +} + +func (m *Connection_Timeline) Reset() { *m = Connection_Timeline{} } +func (m *Connection_Timeline) String() string { return proto.CompactTextString(m) } +func (*Connection_Timeline) ProtoMessage() {} +func (*Connection_Timeline) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{9, 0} +} +func (m *Connection_Timeline) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Connection_Timeline) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Connection_Timeline.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Connection_Timeline) XXX_Merge(src proto.Message) { + xxx_messageInfo_Connection_Timeline.Merge(m, src) +} +func (m *Connection_Timeline) XXX_Size() int { + return m.Size() +} +func (m *Connection_Timeline) XXX_DiscardUnknown() { + xxx_messageInfo_Connection_Timeline.DiscardUnknown(m) +} + +var xxx_messageInfo_Connection_Timeline proto.InternalMessageInfo + +func (m *Connection_Timeline) GetOpenTs() uint64 { + if m != nil { + return m.OpenTs + } + return 0 +} + +func (m *Connection_Timeline) GetUpgradedTs() uint64 { + if m != nil { + return m.UpgradedTs + } + return 0 +} + +func (m *Connection_Timeline) GetCloseTs() uint64 { + if m != nil { + return m.CloseTs + } + return 0 +} + +// Attributes encapsulates the attributes of this connection. +type Connection_Attributes struct { + // the multiplexer being used. + Multiplexer string `protobuf:"bytes,1,opt,name=multiplexer,proto3" json:"multiplexer,omitempty"` + // the encryption method being used. + Encryption string `protobuf:"bytes,2,opt,name=encryption,proto3" json:"encryption,omitempty"` +} + +func (m *Connection_Attributes) Reset() { *m = Connection_Attributes{} } +func (m *Connection_Attributes) String() string { return proto.CompactTextString(m) } +func (*Connection_Attributes) ProtoMessage() {} +func (*Connection_Attributes) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{9, 1} +} +func (m *Connection_Attributes) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Connection_Attributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Connection_Attributes.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Connection_Attributes) XXX_Merge(src proto.Message) { + xxx_messageInfo_Connection_Attributes.Merge(m, src) +} +func (m *Connection_Attributes) XXX_Size() int { + return m.Size() +} +func (m *Connection_Attributes) XXX_DiscardUnknown() { + xxx_messageInfo_Connection_Attributes.DiscardUnknown(m) +} + +var xxx_messageInfo_Connection_Attributes proto.InternalMessageInfo + +func (m *Connection_Attributes) GetMultiplexer() string { + if m != nil { + return m.Multiplexer + } + return "" +} + +func (m *Connection_Attributes) GetEncryption() string { + if m != nil { + return m.Encryption + } + return "" +} + +// Stream reports metrics and state of a libp2p stream. +type Stream struct { + // the id of this stream, not to be shown in user tooling, + // used for (cross)referencing streams. + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // the protocol pinned to this stream. + Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"` + // our role in this stream. + Role Role `protobuf:"varint,3,opt,name=role,proto3,enum=pb.Role" json:"role,omitempty"` + // traffic statistics. + Traffic *Traffic `protobuf:"bytes,4,opt,name=traffic,proto3" json:"traffic,omitempty"` + // the connection this stream is hosted under. + Conn *Stream_ConnectionRef `protobuf:"bytes,5,opt,name=conn,proto3" json:"conn,omitempty"` + // the timeline of the stream, see Stream.Timeline. + Timeline *Stream_Timeline `protobuf:"bytes,6,opt,name=timeline,proto3" json:"timeline,omitempty"` + // the status of this stream. + Status Status `protobuf:"varint,7,opt,name=status,proto3,enum=pb.Status" json:"status,omitempty"` + // the instantaneous latency of this stream in nanoseconds. + // TODO: this is hard to calculate. + LatencyNs uint64 `protobuf:"varint,16,opt,name=latency_ns,json=latencyNs,proto3" json:"latency_ns,omitempty"` + // user provided tags. + UserProvidedTags []string `protobuf:"bytes,99,rep,name=user_provided_tags,json=userProvidedTags,proto3" json:"user_provided_tags,omitempty"` +} + +func (m *Stream) Reset() { *m = Stream{} } +func (m *Stream) String() string { return proto.CompactTextString(m) } +func (*Stream) ProtoMessage() {} +func (*Stream) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{10} +} +func (m *Stream) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Stream) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Stream.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Stream) XXX_Merge(src proto.Message) { + xxx_messageInfo_Stream.Merge(m, src) +} +func (m *Stream) XXX_Size() int { + return m.Size() +} +func (m *Stream) XXX_DiscardUnknown() { + xxx_messageInfo_Stream.DiscardUnknown(m) +} + +var xxx_messageInfo_Stream proto.InternalMessageInfo + +func (m *Stream) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Stream) GetProtocol() string { + if m != nil { + return m.Protocol + } + return "" +} + +func (m *Stream) GetRole() Role { + if m != nil { + return m.Role + } + return Role_INITIATOR +} + +func (m *Stream) GetTraffic() *Traffic { + if m != nil { + return m.Traffic + } + return nil +} + +func (m *Stream) GetConn() *Stream_ConnectionRef { + if m != nil { + return m.Conn + } + return nil +} + +func (m *Stream) GetTimeline() *Stream_Timeline { + if m != nil { + return m.Timeline + } + return nil +} + +func (m *Stream) GetStatus() Status { + if m != nil { + return m.Status + } + return Status_ACTIVE +} + +func (m *Stream) GetLatencyNs() uint64 { + if m != nil { + return m.LatencyNs + } + return 0 +} + +func (m *Stream) GetUserProvidedTags() []string { + if m != nil { + return m.UserProvidedTags + } + return nil +} + +type Stream_ConnectionRef struct { + // Types that are valid to be assigned to Connection: + // *Stream_ConnectionRef_Conn + // *Stream_ConnectionRef_ConnId + Connection isStream_ConnectionRef_Connection `protobuf_oneof:"connection"` +} + +func (m *Stream_ConnectionRef) Reset() { *m = Stream_ConnectionRef{} } +func (m *Stream_ConnectionRef) String() string { return proto.CompactTextString(m) } +func (*Stream_ConnectionRef) ProtoMessage() {} +func (*Stream_ConnectionRef) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{10, 0} +} +func (m *Stream_ConnectionRef) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Stream_ConnectionRef) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Stream_ConnectionRef.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Stream_ConnectionRef) XXX_Merge(src proto.Message) { + xxx_messageInfo_Stream_ConnectionRef.Merge(m, src) +} +func (m *Stream_ConnectionRef) XXX_Size() int { + return m.Size() +} +func (m *Stream_ConnectionRef) XXX_DiscardUnknown() { + xxx_messageInfo_Stream_ConnectionRef.DiscardUnknown(m) +} + +var xxx_messageInfo_Stream_ConnectionRef proto.InternalMessageInfo + +type isStream_ConnectionRef_Connection interface { + isStream_ConnectionRef_Connection() + MarshalTo([]byte) (int, error) + Size() int +} + +type Stream_ConnectionRef_Conn struct { + Conn *Connection `protobuf:"bytes,1,opt,name=conn,proto3,oneof" json:"conn,omitempty"` +} +type Stream_ConnectionRef_ConnId struct { + ConnId []byte `protobuf:"bytes,2,opt,name=conn_id,json=connId,proto3,oneof" json:"conn_id,omitempty"` +} + +func (*Stream_ConnectionRef_Conn) isStream_ConnectionRef_Connection() {} +func (*Stream_ConnectionRef_ConnId) isStream_ConnectionRef_Connection() {} + +func (m *Stream_ConnectionRef) GetConnection() isStream_ConnectionRef_Connection { + if m != nil { + return m.Connection + } + return nil +} + +func (m *Stream_ConnectionRef) GetConn() *Connection { + if x, ok := m.GetConnection().(*Stream_ConnectionRef_Conn); ok { + return x.Conn + } + return nil +} + +func (m *Stream_ConnectionRef) GetConnId() []byte { + if x, ok := m.GetConnection().(*Stream_ConnectionRef_ConnId); ok { + return x.ConnId + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Stream_ConnectionRef) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Stream_ConnectionRef_Conn)(nil), + (*Stream_ConnectionRef_ConnId)(nil), + } +} + +// Timeline contains the timestamps (ms since epoch) of the well-known milestones of a stream. +type Stream_Timeline struct { + // the instant when the stream was opened. + OpenTs uint64 `protobuf:"varint,1,opt,name=open_ts,json=openTs,proto3" json:"open_ts,omitempty"` + // the instant when the stream was terminated. + CloseTs uint64 `protobuf:"varint,2,opt,name=close_ts,json=closeTs,proto3" json:"close_ts,omitempty"` +} + +func (m *Stream_Timeline) Reset() { *m = Stream_Timeline{} } +func (m *Stream_Timeline) String() string { return proto.CompactTextString(m) } +func (*Stream_Timeline) ProtoMessage() {} +func (*Stream_Timeline) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{10, 1} +} +func (m *Stream_Timeline) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Stream_Timeline) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Stream_Timeline.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Stream_Timeline) XXX_Merge(src proto.Message) { + xxx_messageInfo_Stream_Timeline.Merge(m, src) +} +func (m *Stream_Timeline) XXX_Size() int { + return m.Size() +} +func (m *Stream_Timeline) XXX_DiscardUnknown() { + xxx_messageInfo_Stream_Timeline.DiscardUnknown(m) +} + +var xxx_messageInfo_Stream_Timeline proto.InternalMessageInfo + +func (m *Stream_Timeline) GetOpenTs() uint64 { + if m != nil { + return m.OpenTs + } + return 0 +} + +func (m *Stream_Timeline) GetCloseTs() uint64 { + if m != nil { + return m.CloseTs + } + return 0 +} + +// DHT metrics and state. +type DHT struct { + // DHT protocol name + Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` + // protocol enabled. + Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"` + // timestamp (ms since epoch) of start up. + StartTs uint64 `protobuf:"varint,3,opt,name=start_ts,json=startTs,proto3" json:"start_ts,omitempty"` + // params of the dht. + Params *DHT_Params `protobuf:"bytes,4,opt,name=params,proto3" json:"params,omitempty"` + // existing, intantiated buckets and their contents + Buckets []*DHT_Bucket `protobuf:"bytes,5,rep,name=buckets,proto3" json:"buckets,omitempty"` + // counts inbound queries received from other peers + IncomingQueries *DHT_QueryGauge `protobuf:"bytes,6,opt,name=incoming_queries,json=incomingQueries,proto3" json:"incoming_queries,omitempty"` + // counts outbound queries dispatched by this peer + OutgoingQueries *DHT_QueryGauge `protobuf:"bytes,7,opt,name=outgoing_queries,json=outgoingQueries,proto3" json:"outgoing_queries,omitempty"` +} + +func (m *DHT) Reset() { *m = DHT{} } +func (m *DHT) String() string { return proto.CompactTextString(m) } +func (*DHT) ProtoMessage() {} +func (*DHT) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{11} +} +func (m *DHT) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DHT) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DHT.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DHT) XXX_Merge(src proto.Message) { + xxx_messageInfo_DHT.Merge(m, src) +} +func (m *DHT) XXX_Size() int { + return m.Size() +} +func (m *DHT) XXX_DiscardUnknown() { + xxx_messageInfo_DHT.DiscardUnknown(m) +} + +var xxx_messageInfo_DHT proto.InternalMessageInfo + +func (m *DHT) GetProtocol() string { + if m != nil { + return m.Protocol + } + return "" +} + +func (m *DHT) GetEnabled() bool { + if m != nil { + return m.Enabled + } + return false +} + +func (m *DHT) GetStartTs() uint64 { + if m != nil { + return m.StartTs + } + return 0 +} + +func (m *DHT) GetParams() *DHT_Params { + if m != nil { + return m.Params + } + return nil +} + +func (m *DHT) GetBuckets() []*DHT_Bucket { + if m != nil { + return m.Buckets + } + return nil +} + +func (m *DHT) GetIncomingQueries() *DHT_QueryGauge { + if m != nil { + return m.IncomingQueries + } + return nil +} + +func (m *DHT) GetOutgoingQueries() *DHT_QueryGauge { + if m != nil { + return m.OutgoingQueries + } + return nil +} + +type DHT_Params struct { + // routing table bucket size. + K uint64 `protobuf:"varint,1,opt,name=k,proto3" json:"k,omitempty"` + // concurrency of asynchronous requests. + Alpha uint64 `protobuf:"varint,2,opt,name=alpha,proto3" json:"alpha,omitempty"` + // number of disjoint paths to use. + DisjointPaths uint64 `protobuf:"varint,3,opt,name=disjoint_paths,json=disjointPaths,proto3" json:"disjoint_paths,omitempty"` + // number of peers closest to a target that must have responded + // in order for a given query path to complete + Beta uint64 `protobuf:"varint,4,opt,name=beta,proto3" json:"beta,omitempty"` +} + +func (m *DHT_Params) Reset() { *m = DHT_Params{} } +func (m *DHT_Params) String() string { return proto.CompactTextString(m) } +func (*DHT_Params) ProtoMessage() {} +func (*DHT_Params) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{11, 0} +} +func (m *DHT_Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DHT_Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DHT_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DHT_Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_DHT_Params.Merge(m, src) +} +func (m *DHT_Params) XXX_Size() int { + return m.Size() +} +func (m *DHT_Params) XXX_DiscardUnknown() { + xxx_messageInfo_DHT_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_DHT_Params proto.InternalMessageInfo + +func (m *DHT_Params) GetK() uint64 { + if m != nil { + return m.K + } + return 0 +} + +func (m *DHT_Params) GetAlpha() uint64 { + if m != nil { + return m.Alpha + } + return 0 +} + +func (m *DHT_Params) GetDisjointPaths() uint64 { + if m != nil { + return m.DisjointPaths + } + return 0 +} + +func (m *DHT_Params) GetBeta() uint64 { + if m != nil { + return m.Beta + } + return 0 +} + +// Peer in DHT +type DHT_PeerInDHT struct { + // the peer id of the host system + PeerId string `protobuf:"bytes,1,opt,name=peer_id,json=peerId,proto3" json:"peer_id,omitempty"` + // the peer's status when data snapshot is taken + Status DHT_PeerInDHT_Status `protobuf:"varint,2,opt,name=status,proto3,enum=pb.DHT_PeerInDHT_Status" json:"status,omitempty"` + // age in bucket (ms) + AgeInBucket uint32 `protobuf:"varint,3,opt,name=age_in_bucket,json=ageInBucket,proto3" json:"age_in_bucket,omitempty"` +} + +func (m *DHT_PeerInDHT) Reset() { *m = DHT_PeerInDHT{} } +func (m *DHT_PeerInDHT) String() string { return proto.CompactTextString(m) } +func (*DHT_PeerInDHT) ProtoMessage() {} +func (*DHT_PeerInDHT) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{11, 1} +} +func (m *DHT_PeerInDHT) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DHT_PeerInDHT) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DHT_PeerInDHT.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DHT_PeerInDHT) XXX_Merge(src proto.Message) { + xxx_messageInfo_DHT_PeerInDHT.Merge(m, src) +} +func (m *DHT_PeerInDHT) XXX_Size() int { + return m.Size() +} +func (m *DHT_PeerInDHT) XXX_DiscardUnknown() { + xxx_messageInfo_DHT_PeerInDHT.DiscardUnknown(m) +} + +var xxx_messageInfo_DHT_PeerInDHT proto.InternalMessageInfo + +func (m *DHT_PeerInDHT) GetPeerId() string { + if m != nil { + return m.PeerId + } + return "" +} + +func (m *DHT_PeerInDHT) GetStatus() DHT_PeerInDHT_Status { + if m != nil { + return m.Status + } + return DHT_PeerInDHT_ACTIVE +} + +func (m *DHT_PeerInDHT) GetAgeInBucket() uint32 { + if m != nil { + return m.AgeInBucket + } + return 0 +} + +// A "k-bucket" containing peers of a certain kadamelia distance +type DHT_Bucket struct { + // CPL (Common Prefix Length) is the length of the common prefix + // between the ids of every peer in this bucket and the DHT peer id + Cpl uint32 `protobuf:"varint,1,opt,name=cpl,proto3" json:"cpl,omitempty"` + // Peers associated with this bucket + Peers []*DHT_PeerInDHT `protobuf:"bytes,2,rep,name=peers,proto3" json:"peers,omitempty"` +} + +func (m *DHT_Bucket) Reset() { *m = DHT_Bucket{} } +func (m *DHT_Bucket) String() string { return proto.CompactTextString(m) } +func (*DHT_Bucket) ProtoMessage() {} +func (*DHT_Bucket) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{11, 2} +} +func (m *DHT_Bucket) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DHT_Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DHT_Bucket.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DHT_Bucket) XXX_Merge(src proto.Message) { + xxx_messageInfo_DHT_Bucket.Merge(m, src) +} +func (m *DHT_Bucket) XXX_Size() int { + return m.Size() +} +func (m *DHT_Bucket) XXX_DiscardUnknown() { + xxx_messageInfo_DHT_Bucket.DiscardUnknown(m) +} + +var xxx_messageInfo_DHT_Bucket proto.InternalMessageInfo + +func (m *DHT_Bucket) GetCpl() uint32 { + if m != nil { + return m.Cpl + } + return 0 +} + +func (m *DHT_Bucket) GetPeers() []*DHT_PeerInDHT { + if m != nil { + return m.Peers + } + return nil +} + +// Counters of query events, by status +type DHT_QueryGauge struct { + // Cumulative counter of queries with "SUCCESS" status + Success uint64 `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + // Cumulative counter of queries with "ERROR" status + Error uint64 `protobuf:"varint,2,opt,name=error,proto3" json:"error,omitempty"` + // Cumulative counter of queries with "TIMEOUT" status + Timeout uint64 `protobuf:"varint,3,opt,name=timeout,proto3" json:"timeout,omitempty"` +} + +func (m *DHT_QueryGauge) Reset() { *m = DHT_QueryGauge{} } +func (m *DHT_QueryGauge) String() string { return proto.CompactTextString(m) } +func (*DHT_QueryGauge) ProtoMessage() {} +func (*DHT_QueryGauge) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{11, 3} +} +func (m *DHT_QueryGauge) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DHT_QueryGauge) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DHT_QueryGauge.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DHT_QueryGauge) XXX_Merge(src proto.Message) { + xxx_messageInfo_DHT_QueryGauge.Merge(m, src) +} +func (m *DHT_QueryGauge) XXX_Size() int { + return m.Size() +} +func (m *DHT_QueryGauge) XXX_DiscardUnknown() { + xxx_messageInfo_DHT_QueryGauge.DiscardUnknown(m) +} + +var xxx_messageInfo_DHT_QueryGauge proto.InternalMessageInfo + +func (m *DHT_QueryGauge) GetSuccess() uint64 { + if m != nil { + return m.Success + } + return 0 +} + +func (m *DHT_QueryGauge) GetError() uint64 { + if m != nil { + return m.Error + } + return 0 +} + +func (m *DHT_QueryGauge) GetTimeout() uint64 { + if m != nil { + return m.Timeout + } + return 0 +} + +// Subsystems encapsulates all instrumented subsystems for a libp2p host. +type Subsystems struct { + // connections data, source agnostic but currently only supports the Swarm subsystem + Connections []*Connection `protobuf:"bytes,1,rep,name=connections,proto3" json:"connections,omitempty"` + // the DHT subsystem. + Dht *DHT `protobuf:"bytes,2,opt,name=dht,proto3" json:"dht,omitempty"` +} + +func (m *Subsystems) Reset() { *m = Subsystems{} } +func (m *Subsystems) String() string { return proto.CompactTextString(m) } +func (*Subsystems) ProtoMessage() {} +func (*Subsystems) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{12} +} +func (m *Subsystems) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Subsystems) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Subsystems.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Subsystems) XXX_Merge(src proto.Message) { + xxx_messageInfo_Subsystems.Merge(m, src) +} +func (m *Subsystems) XXX_Size() int { + return m.Size() +} +func (m *Subsystems) XXX_DiscardUnknown() { + xxx_messageInfo_Subsystems.DiscardUnknown(m) +} + +var xxx_messageInfo_Subsystems proto.InternalMessageInfo + +func (m *Subsystems) GetConnections() []*Connection { + if m != nil { + return m.Connections + } + return nil +} + +func (m *Subsystems) GetDht() *DHT { + if m != nil { + return m.Dht + } + return nil +} + +// Connections and streams output for a time interval is one of these. +type State struct { + // list of connections + Subsystems *Subsystems `protobuf:"bytes,1,opt,name=subsystems,proto3" json:"subsystems,omitempty"` + // overall traffic for this peer + Traffic *Traffic `protobuf:"bytes,2,opt,name=traffic,proto3" json:"traffic,omitempty"` + // moment this data snapshot and instantaneous values were taken + InstantTs uint64 `protobuf:"varint,3,opt,name=instant_ts,json=instantTs,proto3" json:"instant_ts,omitempty"` + // start of included data collection (cumulative values counted from here) + StartTs uint64 `protobuf:"varint,4,opt,name=start_ts,json=startTs,proto3" json:"start_ts,omitempty"` + // length of time up to instant_ts covered by this data snapshot + SnapshotDurationMs uint32 `protobuf:"varint,5,opt,name=snapshot_duration_ms,json=snapshotDurationMs,proto3" json:"snapshot_duration_ms,omitempty"` +} + +func (m *State) Reset() { *m = State{} } +func (m *State) String() string { return proto.CompactTextString(m) } +func (*State) ProtoMessage() {} +func (*State) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{13} +} +func (m *State) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *State) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_State.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *State) XXX_Merge(src proto.Message) { + xxx_messageInfo_State.Merge(m, src) +} +func (m *State) XXX_Size() int { + return m.Size() +} +func (m *State) XXX_DiscardUnknown() { + xxx_messageInfo_State.DiscardUnknown(m) +} + +var xxx_messageInfo_State proto.InternalMessageInfo + +func (m *State) GetSubsystems() *Subsystems { + if m != nil { + return m.Subsystems + } + return nil +} + +func (m *State) GetTraffic() *Traffic { + if m != nil { + return m.Traffic + } + return nil +} + +func (m *State) GetInstantTs() uint64 { + if m != nil { + return m.InstantTs + } + return 0 +} + +func (m *State) GetStartTs() uint64 { + if m != nil { + return m.StartTs + } + return 0 +} + +func (m *State) GetSnapshotDurationMs() uint32 { + if m != nil { + return m.SnapshotDurationMs + } + return 0 +} + +// Event +type Event struct { + // definition of event type, containing only `name` unless this is first encounter of novel event + Type *EventType `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // time this event occurred (ms since epoch) + Ts uint64 `protobuf:"varint,2,opt,name=ts,proto3" json:"ts,omitempty"` + // stringified json; top-level keys and value types match EventProperty definitions + Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{14} +} +func (m *Event) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Event.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Event) XXX_Merge(src proto.Message) { + xxx_messageInfo_Event.Merge(m, src) +} +func (m *Event) XXX_Size() int { + return m.Size() +} +func (m *Event) XXX_DiscardUnknown() { + xxx_messageInfo_Event.DiscardUnknown(m) +} + +var xxx_messageInfo_Event proto.InternalMessageInfo + +func (m *Event) GetType() *EventType { + if m != nil { + return m.Type + } + return nil +} + +func (m *Event) GetTs() uint64 { + if m != nil { + return m.Ts + } + return 0 +} + +func (m *Event) GetContent() string { + if m != nil { + return m.Content + } + return "" +} + +// ServerMessage wraps messages to be sent to clients to allow extension +// based on new types of data sources +type ServerMessage struct { + // Version of this protobuf. + Version *Version `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // The payload this message contains. + // + // Types that are valid to be assigned to Payload: + // *ServerMessage_State + // *ServerMessage_Runtime + // *ServerMessage_Event + // *ServerMessage_Response + // *ServerMessage_Notice + Payload isServerMessage_Payload `protobuf_oneof:"payload"` +} + +func (m *ServerMessage) Reset() { *m = ServerMessage{} } +func (m *ServerMessage) String() string { return proto.CompactTextString(m) } +func (*ServerMessage) ProtoMessage() {} +func (*ServerMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{15} +} +func (m *ServerMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServerMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ServerMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ServerMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerMessage.Merge(m, src) +} +func (m *ServerMessage) XXX_Size() int { + return m.Size() +} +func (m *ServerMessage) XXX_DiscardUnknown() { + xxx_messageInfo_ServerMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerMessage proto.InternalMessageInfo + +type isServerMessage_Payload interface { + isServerMessage_Payload() + MarshalTo([]byte) (int, error) + Size() int +} + +type ServerMessage_State struct { + State *State `protobuf:"bytes,2,opt,name=state,proto3,oneof" json:"state,omitempty"` +} +type ServerMessage_Runtime struct { + Runtime *Runtime `protobuf:"bytes,3,opt,name=runtime,proto3,oneof" json:"runtime,omitempty"` +} +type ServerMessage_Event struct { + Event *Event `protobuf:"bytes,4,opt,name=event,proto3,oneof" json:"event,omitempty"` +} +type ServerMessage_Response struct { + Response *CommandResponse `protobuf:"bytes,5,opt,name=response,proto3,oneof" json:"response,omitempty"` +} +type ServerMessage_Notice struct { + Notice *ServerNotice `protobuf:"bytes,6,opt,name=notice,proto3,oneof" json:"notice,omitempty"` +} + +func (*ServerMessage_State) isServerMessage_Payload() {} +func (*ServerMessage_Runtime) isServerMessage_Payload() {} +func (*ServerMessage_Event) isServerMessage_Payload() {} +func (*ServerMessage_Response) isServerMessage_Payload() {} +func (*ServerMessage_Notice) isServerMessage_Payload() {} + +func (m *ServerMessage) GetPayload() isServerMessage_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (m *ServerMessage) GetVersion() *Version { + if m != nil { + return m.Version + } + return nil +} + +func (m *ServerMessage) GetState() *State { + if x, ok := m.GetPayload().(*ServerMessage_State); ok { + return x.State + } + return nil +} + +func (m *ServerMessage) GetRuntime() *Runtime { + if x, ok := m.GetPayload().(*ServerMessage_Runtime); ok { + return x.Runtime + } + return nil +} + +func (m *ServerMessage) GetEvent() *Event { + if x, ok := m.GetPayload().(*ServerMessage_Event); ok { + return x.Event + } + return nil +} + +func (m *ServerMessage) GetResponse() *CommandResponse { + if x, ok := m.GetPayload().(*ServerMessage_Response); ok { + return x.Response + } + return nil +} + +func (m *ServerMessage) GetNotice() *ServerNotice { + if x, ok := m.GetPayload().(*ServerMessage_Notice); ok { + return x.Notice + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*ServerMessage) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*ServerMessage_State)(nil), + (*ServerMessage_Runtime)(nil), + (*ServerMessage_Event)(nil), + (*ServerMessage_Response)(nil), + (*ServerMessage_Notice)(nil), + } +} + +// Configuration encapsulates configuration fields for the protocol and commands. +type Configuration struct { + RetentionPeriodMs uint64 `protobuf:"varint,1,opt,name=retention_period_ms,json=retentionPeriodMs,proto3" json:"retention_period_ms,omitempty"` + StateSnapshotIntervalMs uint64 `protobuf:"varint,2,opt,name=state_snapshot_interval_ms,json=stateSnapshotIntervalMs,proto3" json:"state_snapshot_interval_ms,omitempty"` +} + +func (m *Configuration) Reset() { *m = Configuration{} } +func (m *Configuration) String() string { return proto.CompactTextString(m) } +func (*Configuration) ProtoMessage() {} +func (*Configuration) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{16} +} +func (m *Configuration) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Configuration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Configuration.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Configuration) XXX_Merge(src proto.Message) { + xxx_messageInfo_Configuration.Merge(m, src) +} +func (m *Configuration) XXX_Size() int { + return m.Size() +} +func (m *Configuration) XXX_DiscardUnknown() { + xxx_messageInfo_Configuration.DiscardUnknown(m) +} + +var xxx_messageInfo_Configuration proto.InternalMessageInfo + +func (m *Configuration) GetRetentionPeriodMs() uint64 { + if m != nil { + return m.RetentionPeriodMs + } + return 0 +} + +func (m *Configuration) GetStateSnapshotIntervalMs() uint64 { + if m != nil { + return m.StateSnapshotIntervalMs + } + return 0 +} + +// ClientCommand is a command sent from the client to the server. +type ClientCommand struct { + Version *Version `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Id uint64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + Command ClientCommand_Command `protobuf:"varint,3,opt,name=command,proto3,enum=pb.ClientCommand_Command" json:"command,omitempty"` + Source ClientCommand_Source `protobuf:"varint,4,opt,name=source,proto3,enum=pb.ClientCommand_Source" json:"source,omitempty"` + Config *Configuration `protobuf:"bytes,5,opt,name=config,proto3" json:"config,omitempty"` +} + +func (m *ClientCommand) Reset() { *m = ClientCommand{} } +func (m *ClientCommand) String() string { return proto.CompactTextString(m) } +func (*ClientCommand) ProtoMessage() {} +func (*ClientCommand) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{17} +} +func (m *ClientCommand) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClientCommand) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ClientCommand.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ClientCommand) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientCommand.Merge(m, src) +} +func (m *ClientCommand) XXX_Size() int { + return m.Size() +} +func (m *ClientCommand) XXX_DiscardUnknown() { + xxx_messageInfo_ClientCommand.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientCommand proto.InternalMessageInfo + +func (m *ClientCommand) GetVersion() *Version { + if m != nil { + return m.Version + } + return nil +} + +func (m *ClientCommand) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *ClientCommand) GetCommand() ClientCommand_Command { + if m != nil { + return m.Command + } + return ClientCommand_HELLO +} + +func (m *ClientCommand) GetSource() ClientCommand_Source { + if m != nil { + return m.Source + } + return ClientCommand_STATE +} + +func (m *ClientCommand) GetConfig() *Configuration { + if m != nil { + return m.Config + } + return nil +} + +// CommandResponse is a response to a command sent by the client. +type CommandResponse struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Result CommandResponse_Result `protobuf:"varint,2,opt,name=result,proto3,enum=pb.CommandResponse_Result" json:"result,omitempty"` + Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` + // effective_config is the effective configuration the server holds for + // this connection. It is returned in response to HELLO and UPDATE_CONFIG + // commands. + EffectiveConfig *Configuration `protobuf:"bytes,4,opt,name=effective_config,json=effectiveConfig,proto3" json:"effective_config,omitempty"` +} + +func (m *CommandResponse) Reset() { *m = CommandResponse{} } +func (m *CommandResponse) String() string { return proto.CompactTextString(m) } +func (*CommandResponse) ProtoMessage() {} +func (*CommandResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{18} +} +func (m *CommandResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CommandResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CommandResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CommandResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommandResponse.Merge(m, src) +} +func (m *CommandResponse) XXX_Size() int { + return m.Size() +} +func (m *CommandResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CommandResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CommandResponse proto.InternalMessageInfo + +func (m *CommandResponse) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *CommandResponse) GetResult() CommandResponse_Result { + if m != nil { + return m.Result + } + return CommandResponse_OK +} + +func (m *CommandResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func (m *CommandResponse) GetEffectiveConfig() *Configuration { + if m != nil { + return m.EffectiveConfig + } + return nil +} + +// ServerNotice represents a NOTICE sent from the server to the client. +type ServerNotice struct { + Kind ServerNotice_Kind `protobuf:"varint,1,opt,name=kind,proto3,enum=pb.ServerNotice_Kind" json:"kind,omitempty"` +} + +func (m *ServerNotice) Reset() { *m = ServerNotice{} } +func (m *ServerNotice) String() string { return proto.CompactTextString(m) } +func (*ServerNotice) ProtoMessage() {} +func (*ServerNotice) Descriptor() ([]byte, []int) { + return fileDescriptor_53a8bedf9a75e10a, []int{19} +} +func (m *ServerNotice) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServerNotice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ServerNotice.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ServerNotice) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerNotice.Merge(m, src) +} +func (m *ServerNotice) XXX_Size() int { + return m.Size() +} +func (m *ServerNotice) XXX_DiscardUnknown() { + xxx_messageInfo_ServerNotice.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerNotice proto.InternalMessageInfo + +func (m *ServerNotice) GetKind() ServerNotice_Kind { + if m != nil { + return m.Kind + } + return ServerNotice_DISCARDING_EVENTS +} + +func init() { + proto.RegisterEnum("pb.Status", Status_name, Status_value) + proto.RegisterEnum("pb.Role", Role_name, Role_value) + proto.RegisterEnum("pb.EventType_EventProperty_PropertyType", EventType_EventProperty_PropertyType_name, EventType_EventProperty_PropertyType_value) + proto.RegisterEnum("pb.DHT_PeerInDHT_Status", DHT_PeerInDHT_Status_name, DHT_PeerInDHT_Status_value) + proto.RegisterEnum("pb.ClientCommand_Source", ClientCommand_Source_name, ClientCommand_Source_value) + proto.RegisterEnum("pb.ClientCommand_Command", ClientCommand_Command_name, ClientCommand_Command_value) + proto.RegisterEnum("pb.CommandResponse_Result", CommandResponse_Result_name, CommandResponse_Result_value) + proto.RegisterEnum("pb.ServerNotice_Kind", ServerNotice_Kind_name, ServerNotice_Kind_value) + proto.RegisterType((*Version)(nil), "pb.Version") + proto.RegisterType((*ResultCounter)(nil), "pb.ResultCounter") + proto.RegisterType((*SlidingCounter)(nil), "pb.SlidingCounter") + proto.RegisterType((*DataGauge)(nil), "pb.DataGauge") + proto.RegisterType((*EventType)(nil), "pb.EventType") + proto.RegisterType((*EventType_EventProperty)(nil), "pb.EventType.EventProperty") + proto.RegisterType((*Runtime)(nil), "pb.Runtime") + proto.RegisterType((*EndpointPair)(nil), "pb.EndpointPair") + proto.RegisterType((*Traffic)(nil), "pb.Traffic") + proto.RegisterType((*StreamList)(nil), "pb.StreamList") + proto.RegisterType((*Connection)(nil), "pb.Connection") + proto.RegisterType((*Connection_Timeline)(nil), "pb.Connection.Timeline") + proto.RegisterType((*Connection_Attributes)(nil), "pb.Connection.Attributes") + proto.RegisterType((*Stream)(nil), "pb.Stream") + proto.RegisterType((*Stream_ConnectionRef)(nil), "pb.Stream.ConnectionRef") + proto.RegisterType((*Stream_Timeline)(nil), "pb.Stream.Timeline") + proto.RegisterType((*DHT)(nil), "pb.DHT") + proto.RegisterType((*DHT_Params)(nil), "pb.DHT.Params") + proto.RegisterType((*DHT_PeerInDHT)(nil), "pb.DHT.PeerInDHT") + proto.RegisterType((*DHT_Bucket)(nil), "pb.DHT.Bucket") + proto.RegisterType((*DHT_QueryGauge)(nil), "pb.DHT.QueryGauge") + proto.RegisterType((*Subsystems)(nil), "pb.Subsystems") + proto.RegisterType((*State)(nil), "pb.State") + proto.RegisterType((*Event)(nil), "pb.Event") + proto.RegisterType((*ServerMessage)(nil), "pb.ServerMessage") + proto.RegisterType((*Configuration)(nil), "pb.Configuration") + proto.RegisterType((*ClientCommand)(nil), "pb.ClientCommand") + proto.RegisterType((*CommandResponse)(nil), "pb.CommandResponse") + proto.RegisterType((*ServerNotice)(nil), "pb.ServerNotice") +} + +func init() { proto.RegisterFile("introspection.proto", fileDescriptor_53a8bedf9a75e10a) } + +var fileDescriptor_53a8bedf9a75e10a = []byte{ + // 2207 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0x5b, 0x6f, 0x1b, 0xc7, + 0x15, 0xe6, 0xfd, 0x72, 0x78, 0xf1, 0x6a, 0x9c, 0x20, 0xb4, 0x52, 0xab, 0xf6, 0xc6, 0x49, 0x14, + 0xc3, 0x50, 0x6d, 0x3a, 0x06, 0x02, 0x34, 0x0d, 0x20, 0x89, 0x5b, 0x8b, 0x8e, 0x44, 0xd1, 0x43, + 0xca, 0x68, 0xfb, 0xd0, 0xc5, 0x8a, 0x3b, 0x22, 0xb7, 0x22, 0x77, 0xb7, 0x33, 0x43, 0x25, 0x02, + 0xfa, 0xd0, 0x7f, 0xd0, 0xfe, 0x82, 0xfe, 0x86, 0x3e, 0xf7, 0xad, 0x40, 0x1f, 0x8a, 0x3e, 0xe5, + 0xb1, 0x68, 0x5f, 0x0a, 0xfb, 0x29, 0xff, 0xa2, 0x38, 0x33, 0xb3, 0x17, 0xc9, 0x97, 0xa6, 0x6f, + 0x7b, 0xce, 0xf7, 0x9d, 0xb3, 0xb3, 0xe7, 0x36, 0x87, 0x84, 0x9b, 0x41, 0x28, 0x79, 0x24, 0x62, + 0x36, 0x93, 0x41, 0x14, 0xee, 0xc4, 0x3c, 0x92, 0x11, 0x29, 0xc5, 0xa7, 0xf6, 0x47, 0x50, 0x7f, + 0xc1, 0xb8, 0x08, 0xa2, 0x90, 0xf4, 0xa0, 0x7e, 0xa1, 0x1f, 0x7b, 0xc5, 0x3b, 0xc5, 0xed, 0x0e, + 0x4d, 0x44, 0xfb, 0x29, 0x74, 0x28, 0x13, 0xeb, 0xa5, 0xdc, 0x8f, 0xd6, 0xa1, 0x64, 0x9c, 0xbc, + 0x07, 0x55, 0x19, 0x49, 0x6f, 0x69, 0x88, 0x5a, 0x20, 0x5d, 0x28, 0x45, 0xe7, 0xbd, 0x92, 0x52, + 0x95, 0xa2, 0x73, 0x62, 0x41, 0x99, 0x71, 0xde, 0x2b, 0x2b, 0x05, 0x3e, 0xda, 0x7f, 0x2a, 0x41, + 0x77, 0xb2, 0x0c, 0xfc, 0x20, 0x9c, 0x27, 0xae, 0x3e, 0x80, 0x7a, 0x74, 0xc1, 0xb8, 0xfb, 0x68, + 0x65, 0x9c, 0xd5, 0x50, 0x7c, 0xb4, 0x4a, 0x81, 0x27, 0x2b, 0xe3, 0x52, 0x01, 0x4f, 0x56, 0xe4, + 0x16, 0x34, 0xb4, 0xc5, 0x93, 0x95, 0xf1, 0xad, 0x88, 0x8f, 0x72, 0xd0, 0xe3, 0x87, 0xab, 0x5e, + 0x25, 0x83, 0x1e, 0x3f, 0xcc, 0x59, 0x2d, 0x78, 0xaf, 0x9a, 0xb3, 0x5a, 0xf0, 0x14, 0xea, 0x2f, + 0x78, 0xaf, 0x96, 0x41, 0xfd, 0x1c, 0xf4, 0xf9, 0x82, 0xf7, 0xea, 0x19, 0xf4, 0x79, 0x0e, 0xfa, + 0x62, 0xc1, 0x7b, 0x8d, 0x0c, 0xfa, 0x62, 0xc1, 0xc9, 0x87, 0xd0, 0xd4, 0xef, 0x42, 0x8f, 0x4d, + 0x85, 0x29, 0x2e, 0xca, 0x29, 0xd8, 0x47, 0x9f, 0x90, 0x81, 0x28, 0xdb, 0xa7, 0xd0, 0x1c, 0x78, + 0xd2, 0x7b, 0xea, 0xad, 0xe7, 0x0c, 0x99, 0xb3, 0xf5, 0xca, 0x3d, 0xbd, 0x94, 0x4c, 0xa8, 0xe0, + 0x54, 0x68, 0x63, 0xb6, 0x5e, 0xed, 0xa1, 0x4c, 0x7e, 0x0c, 0x2d, 0x04, 0x63, 0x6f, 0x76, 0xce, + 0xa4, 0x50, 0x21, 0xaa, 0x50, 0x98, 0xad, 0x57, 0x63, 0xad, 0xc1, 0xf8, 0x05, 0xa1, 0x90, 0xee, + 0xe9, 0x37, 0x2a, 0x4a, 0x15, 0x5a, 0x43, 0x71, 0xef, 0x1b, 0xfb, 0xaf, 0x25, 0x68, 0x3a, 0x17, + 0x2c, 0x94, 0xd3, 0xcb, 0x98, 0x11, 0x02, 0x95, 0xd0, 0x5b, 0x31, 0xe5, 0xbf, 0x49, 0xd5, 0x33, + 0xd9, 0x83, 0x6e, 0xcc, 0xa3, 0x98, 0x71, 0x79, 0xe9, 0xca, 0xcb, 0x98, 0xa1, 0xfb, 0xf2, 0x76, + 0xab, 0xff, 0xe1, 0x4e, 0x7c, 0xba, 0x93, 0x9a, 0xea, 0xa7, 0xb1, 0x21, 0xd2, 0x4e, 0x62, 0x82, + 0x98, 0xd8, 0xfc, 0x77, 0x11, 0x3a, 0x57, 0x08, 0x6f, 0x7c, 0xd3, 0x97, 0x50, 0xc1, 0x17, 0xa8, + 0xe3, 0x77, 0xfb, 0xdb, 0xef, 0xf0, 0xbf, 0x33, 0xce, 0xb9, 0xa7, 0xca, 0x8a, 0xdc, 0x85, 0xf6, + 0xc2, 0x13, 0xee, 0x6a, 0xbd, 0x94, 0x41, 0xbc, 0x64, 0xea, 0x3b, 0x1b, 0xb4, 0xb5, 0xf0, 0xc4, + 0x91, 0x51, 0xd9, 0x27, 0xd0, 0xce, 0x1b, 0x12, 0x80, 0xda, 0x64, 0x4a, 0x87, 0xa3, 0xa7, 0x56, + 0x01, 0x9f, 0x47, 0x27, 0x47, 0x7b, 0x0e, 0xb5, 0x8a, 0xa4, 0x01, 0x95, 0xe9, 0xf0, 0xc8, 0xb1, + 0x00, 0xb5, 0x63, 0xc7, 0xa1, 0xc3, 0x81, 0xd5, 0x22, 0x1d, 0x68, 0x1e, 0x9d, 0x1c, 0x4e, 0x87, + 0xbb, 0x83, 0x01, 0xb5, 0xda, 0x48, 0x7a, 0x36, 0x39, 0x1e, 0x59, 0xbf, 0xb2, 0xff, 0x5c, 0x84, + 0x3a, 0x5d, 0x87, 0x32, 0x58, 0x31, 0xf2, 0x09, 0x74, 0x83, 0x55, 0xbc, 0x64, 0x2b, 0x16, 0x4a, + 0x4f, 0x26, 0xed, 0xd3, 0xa4, 0xd7, 0xb4, 0xf9, 0xfe, 0x2a, 0x29, 0x42, 0x22, 0x92, 0x4d, 0x68, + 0xc4, 0x4b, 0x4f, 0x9e, 0x45, 0x5c, 0x57, 0x74, 0x93, 0xa6, 0x32, 0xa6, 0x31, 0x66, 0x8c, 0xbb, + 0x81, 0xaf, 0x2a, 0xba, 0x49, 0x6b, 0x28, 0x0e, 0x7d, 0xb2, 0x03, 0x2d, 0x86, 0x01, 0x32, 0x19, + 0xaa, 0xab, 0x0c, 0x75, 0xae, 0x44, 0x90, 0x02, 0x4b, 0x1e, 0x85, 0xfd, 0x0b, 0x68, 0x3b, 0xa1, + 0x1f, 0x47, 0x41, 0x28, 0xc7, 0x5e, 0xc0, 0xc9, 0x47, 0xd0, 0x11, 0x7c, 0xa6, 0x83, 0xe7, 0xf9, + 0x3e, 0x37, 0xa7, 0x6e, 0x0b, 0x3e, 0x3b, 0x4a, 0x74, 0x48, 0xf2, 0x85, 0xcc, 0x91, 0xf4, 0xc9, + 0xdb, 0xbe, 0x90, 0x29, 0xc9, 0x9e, 0x43, 0x7d, 0xca, 0xbd, 0xb3, 0xb3, 0x60, 0x46, 0x1e, 0x00, + 0x48, 0xfd, 0xe8, 0x06, 0x3a, 0x0e, 0xe6, 0x4c, 0x69, 0x55, 0xd3, 0xa6, 0x21, 0x0c, 0x43, 0xfc, + 0x84, 0x84, 0x1d, 0xad, 0xa5, 0xf2, 0xfd, 0x1a, 0x3d, 0xf1, 0x77, 0xbc, 0x96, 0xf6, 0x73, 0x80, + 0x89, 0xe4, 0xcc, 0x5b, 0x1d, 0x06, 0x42, 0x92, 0xdb, 0x00, 0x42, 0x49, 0x6e, 0xe0, 0x63, 0x7f, + 0x94, 0xb7, 0xdb, 0xb4, 0xa9, 0x35, 0x43, 0x5f, 0x90, 0x7b, 0x50, 0xd7, 0x42, 0x52, 0xbd, 0x80, + 0x8e, 0xb5, 0x3d, 0x4d, 0x20, 0xfb, 0x5f, 0x55, 0x80, 0xfd, 0x28, 0x0c, 0xf5, 0x60, 0xc4, 0x11, + 0x16, 0xf8, 0xea, 0xdc, 0x6d, 0x5a, 0x0a, 0xfc, 0x7c, 0xf4, 0x4b, 0x57, 0xa2, 0x6f, 0x43, 0x4d, + 0x48, 0x4f, 0xae, 0x85, 0x4a, 0x58, 0x37, 0x71, 0x8e, 0x1a, 0x6a, 0x10, 0x2c, 0x4f, 0xc9, 0xbd, + 0x50, 0xc4, 0x11, 0x97, 0x49, 0xfe, 0xda, 0xb4, 0x95, 0xea, 0x54, 0x12, 0x9b, 0xcc, 0x24, 0x45, + 0xa8, 0xb1, 0xd4, 0xea, 0x5b, 0x2a, 0x85, 0xb9, 0x4c, 0xd1, 0x8c, 0x42, 0x1e, 0x43, 0x03, 0x6b, + 0x6e, 0x19, 0x84, 0x4c, 0x8d, 0xaa, 0x56, 0xff, 0x03, 0xa4, 0x67, 0x5f, 0xb0, 0x33, 0x35, 0x30, + 0x4d, 0x89, 0xe4, 0x47, 0x50, 0xe1, 0xd1, 0x92, 0xa9, 0x01, 0xd6, 0xed, 0x37, 0xd0, 0x80, 0x46, + 0x4b, 0x46, 0x95, 0x96, 0x7c, 0x0c, 0x75, 0x13, 0x62, 0x35, 0xc6, 0x5a, 0xfd, 0x16, 0x12, 0x4c, + 0x42, 0x69, 0x82, 0x91, 0xc7, 0x50, 0xf7, 0xa4, 0xe4, 0xc1, 0xa9, 0x50, 0x13, 0xad, 0xd5, 0xbf, + 0x75, 0xed, 0xc5, 0xbb, 0x0a, 0x5d, 0x4b, 0x26, 0x68, 0xc2, 0xc4, 0x14, 0x2d, 0x3d, 0xc9, 0xc2, + 0xd9, 0xa5, 0x1b, 0x0a, 0x35, 0xec, 0x2a, 0xb4, 0x69, 0x34, 0x23, 0x41, 0xb6, 0xb3, 0x14, 0xb5, + 0x94, 0xcf, 0x6e, 0x96, 0x22, 0x4c, 0x71, 0x9a, 0x26, 0x72, 0x0b, 0xea, 0xb3, 0x28, 0x0c, 0x31, + 0x8a, 0x16, 0x46, 0xf1, 0xa0, 0x40, 0x6b, 0xa8, 0x18, 0xfa, 0xe4, 0x1e, 0x54, 0xf0, 0xa9, 0xb7, + 0x91, 0x79, 0xc8, 0x4e, 0x75, 0x50, 0xa0, 0x0a, 0x25, 0x0f, 0x80, 0xac, 0x05, 0xe3, 0x6e, 0xcc, + 0xa3, 0x8b, 0xc0, 0x67, 0xbe, 0x2b, 0xbd, 0xb9, 0xe8, 0xcd, 0xee, 0x94, 0xb7, 0x9b, 0xd4, 0x42, + 0x64, 0x6c, 0x80, 0xa9, 0x37, 0x17, 0x9b, 0x2e, 0x34, 0x92, 0x38, 0xaa, 0x7b, 0x28, 0x66, 0xa1, + 0x2b, 0x93, 0x19, 0x5c, 0x43, 0x71, 0xaa, 0x26, 0xf0, 0x3a, 0x9e, 0x73, 0x4f, 0x79, 0x4b, 0x27, + 0x70, 0xa2, 0x9a, 0xe2, 0xa1, 0x1b, 0xb3, 0x65, 0x24, 0x18, 0xa2, 0x7a, 0x04, 0xd7, 0x95, 0x3c, + 0x15, 0x9b, 0x23, 0x80, 0x2c, 0x5e, 0xe4, 0x0e, 0xb4, 0x92, 0x19, 0xf6, 0x2d, 0x4b, 0x1a, 0x31, + 0xaf, 0x22, 0x5b, 0x00, 0x2c, 0x9c, 0xf1, 0xcb, 0x58, 0x66, 0xe3, 0x23, 0xa7, 0xd9, 0xeb, 0x42, + 0x9b, 0xb3, 0xa5, 0x77, 0xc9, 0x7c, 0x17, 0xef, 0x92, 0x67, 0x95, 0x46, 0xdb, 0xb2, 0xec, 0xef, + 0xcb, 0x50, 0xd3, 0xd1, 0x7c, 0xad, 0xb0, 0x71, 0xe4, 0xe0, 0x12, 0x30, 0x8b, 0x96, 0xc6, 0x5d, + 0x2a, 0xa7, 0xf5, 0x52, 0xfe, 0x5f, 0xf5, 0x52, 0x79, 0x47, 0xbd, 0x3c, 0x30, 0x69, 0xd1, 0x45, + 0xdd, 0xcb, 0x12, 0x9b, 0xcb, 0x0e, 0x65, 0x67, 0x26, 0x3d, 0x3f, 0x79, 0xad, 0xae, 0x6f, 0xe6, + 0x2c, 0xde, 0x50, 0xd3, 0x59, 0xff, 0xd5, 0xdf, 0xda, 0x7f, 0x57, 0xab, 0xcf, 0xba, 0x5e, 0x7d, + 0xff, 0x5f, 0x49, 0xfc, 0x1a, 0x3a, 0x57, 0x0e, 0x9e, 0xd6, 0x5d, 0xf1, 0x9d, 0x75, 0x97, 0x2b, + 0xdc, 0xd2, 0xd5, 0xc2, 0xdd, 0x6b, 0x03, 0xcc, 0x52, 0x83, 0xcd, 0xaf, 0x7e, 0x48, 0xc9, 0xe5, + 0x2b, 0xaa, 0x74, 0xa5, 0xa2, 0xec, 0xef, 0xab, 0x50, 0x1e, 0x1c, 0x4c, 0xaf, 0x24, 0xb6, 0x78, + 0x2d, 0xb1, 0x3d, 0xa8, 0xb3, 0xd0, 0x3b, 0x5d, 0x32, 0x7d, 0x98, 0x06, 0x4d, 0x44, 0x74, 0x2c, + 0xa4, 0xc7, 0x65, 0xae, 0x54, 0x95, 0x3c, 0x15, 0xe4, 0x13, 0xa8, 0xc5, 0x1e, 0xc7, 0x1e, 0xad, + 0x64, 0x5f, 0x3a, 0x38, 0x98, 0xee, 0x8c, 0x95, 0x96, 0x1a, 0x14, 0x9b, 0xf9, 0x74, 0xad, 0x97, + 0x91, 0xaa, 0x9a, 0xb7, 0x29, 0x71, 0x4f, 0xa9, 0x69, 0x02, 0x93, 0x9f, 0x81, 0x15, 0x84, 0xb3, + 0x68, 0x15, 0x84, 0x73, 0xf7, 0xb7, 0x6b, 0xc6, 0x03, 0x26, 0x4c, 0xd2, 0x49, 0x62, 0xf2, 0x7c, + 0xcd, 0xf8, 0xa5, 0xbe, 0x00, 0x6e, 0x24, 0xdc, 0xe7, 0x9a, 0x8a, 0xe6, 0xd1, 0x5a, 0xce, 0xa3, + 0xbc, 0x79, 0xfd, 0xed, 0xe6, 0x09, 0xd7, 0x98, 0x6f, 0xce, 0xa1, 0xa6, 0x4f, 0x4e, 0xda, 0x50, + 0x3c, 0x37, 0x01, 0x2e, 0x9e, 0xe3, 0x4e, 0xeb, 0x2d, 0xe3, 0x85, 0x67, 0x02, 0xab, 0x05, 0xf2, + 0x31, 0x74, 0xfd, 0x40, 0xfc, 0x06, 0xa7, 0xaf, 0x1b, 0x7b, 0x72, 0x91, 0x84, 0xa7, 0x93, 0x68, + 0xc7, 0xa8, 0xc4, 0xdd, 0xe6, 0x94, 0x49, 0x4f, 0x85, 0xa8, 0x42, 0xd5, 0xf3, 0xe6, 0x5f, 0x8a, + 0xd0, 0x1c, 0xe3, 0x6d, 0x11, 0x62, 0x5e, 0x72, 0x37, 0x49, 0xf1, 0xca, 0x4d, 0xf2, 0x30, 0xad, + 0x64, 0xbd, 0x04, 0xf5, 0xd2, 0xf8, 0x26, 0xb6, 0xd7, 0xeb, 0xda, 0x86, 0x8e, 0x37, 0x67, 0x6e, + 0x10, 0xba, 0x3a, 0xa2, 0x66, 0x0b, 0x6e, 0x79, 0x73, 0x36, 0x0c, 0x75, 0xb0, 0xed, 0xaf, 0xb0, + 0xf3, 0x15, 0x1b, 0xa0, 0xb6, 0xbb, 0x3f, 0x1d, 0xbe, 0x70, 0xac, 0x02, 0x69, 0x41, 0xfd, 0x68, + 0x38, 0x99, 0xe0, 0xfa, 0x53, 0x24, 0x6d, 0x68, 0x50, 0xe7, 0x99, 0xb3, 0x3f, 0x75, 0x06, 0x56, + 0x09, 0x57, 0x9d, 0xfd, 0xdd, 0xd1, 0x60, 0x38, 0xd8, 0x9d, 0x3a, 0x56, 0x79, 0x73, 0x1f, 0x6a, + 0xda, 0x13, 0x6e, 0xf1, 0xb3, 0x38, 0xd9, 0xf4, 0xf1, 0x91, 0x7c, 0x0a, 0x55, 0x3c, 0x7b, 0x72, + 0xaf, 0x6e, 0xbc, 0x76, 0x60, 0xaa, 0xf1, 0xcd, 0x17, 0x00, 0x59, 0x26, 0xb0, 0xfa, 0xc4, 0x7a, + 0x36, 0x63, 0x22, 0xa9, 0xea, 0x44, 0xc4, 0xd0, 0x33, 0xce, 0x23, 0x9e, 0x84, 0x5e, 0x09, 0xc8, + 0xc7, 0x76, 0xc7, 0xcd, 0xc0, 0x94, 0xa4, 0x11, 0xed, 0x5f, 0x02, 0x4c, 0xd6, 0xa7, 0xe2, 0x52, + 0x48, 0xb6, 0x12, 0xe4, 0x21, 0xb4, 0xb2, 0x3e, 0xd2, 0x8b, 0xc0, 0x6b, 0xfd, 0x48, 0xf3, 0x14, + 0x72, 0x0b, 0xca, 0xfe, 0x22, 0xd9, 0x37, 0xea, 0xe6, 0xf8, 0x14, 0x75, 0xf6, 0x3f, 0x8a, 0x50, + 0xc5, 0xc0, 0x31, 0xb2, 0x03, 0x20, 0xd2, 0x97, 0xe4, 0xbb, 0x3c, 0x7b, 0x35, 0xcd, 0x31, 0xf2, + 0x73, 0xb1, 0xf4, 0x8e, 0xb9, 0x78, 0x1b, 0x00, 0xf7, 0x70, 0x2f, 0xcc, 0xf5, 0x5a, 0xd3, 0x68, + 0x74, 0x87, 0xa7, 0x8d, 0x58, 0xb9, 0xda, 0x88, 0x0f, 0xe1, 0x3d, 0x11, 0x7a, 0xb1, 0x58, 0x44, + 0xd2, 0xf5, 0xd7, 0x5c, 0x2d, 0x95, 0xee, 0x4a, 0x98, 0x5f, 0x33, 0x24, 0xc1, 0x06, 0x06, 0x3a, + 0x12, 0xf6, 0x14, 0xaa, 0x6a, 0x17, 0x24, 0x77, 0xcd, 0x9a, 0x9d, 0x5b, 0xc8, 0xb2, 0x25, 0x51, + 0xef, 0xd2, 0x5d, 0x28, 0xa5, 0x43, 0xa5, 0x24, 0x05, 0x46, 0x7f, 0x16, 0x85, 0x92, 0x85, 0xd2, + 0xac, 0xa4, 0x89, 0x68, 0xff, 0xa1, 0x04, 0x9d, 0x09, 0xe3, 0x17, 0x8c, 0x1f, 0x31, 0x21, 0xbc, + 0xb9, 0xba, 0x12, 0xf2, 0xbf, 0x1c, 0xcd, 0xa7, 0x9b, 0xdf, 0x95, 0xd9, 0x9a, 0x7b, 0x17, 0xaa, + 0x58, 0xc1, 0xcc, 0xc4, 0xa7, 0x99, 0x8c, 0x6c, 0x76, 0x50, 0xa0, 0x1a, 0x21, 0x9f, 0x42, 0x9d, + 0xeb, 0xb5, 0x5a, 0xbd, 0xd5, 0x78, 0x32, 0x9b, 0xf6, 0x41, 0x81, 0x26, 0x28, 0xfa, 0x52, 0xbb, + 0xad, 0x19, 0x4a, 0xcd, 0xf4, 0x93, 0xd0, 0x97, 0x42, 0xc8, 0x23, 0x68, 0x70, 0x26, 0xe2, 0x28, + 0x14, 0xcc, 0xdc, 0x42, 0x37, 0x75, 0x51, 0xac, 0x56, 0x5e, 0xe8, 0x53, 0x03, 0x1d, 0x14, 0x68, + 0x4a, 0x23, 0xf7, 0xa1, 0x16, 0x46, 0x32, 0x98, 0x25, 0x97, 0x90, 0xda, 0xc5, 0xf4, 0xb7, 0x8e, + 0x94, 0x1e, 0xc7, 0xb7, 0x66, 0xec, 0x35, 0xa1, 0x1e, 0x7b, 0x97, 0xcb, 0xc8, 0xf3, 0xed, 0xdf, + 0xa9, 0xbb, 0xe1, 0x2c, 0x98, 0x9b, 0xd0, 0x93, 0x1d, 0xb8, 0xc9, 0x19, 0x06, 0x0b, 0x53, 0x14, + 0x33, 0x1e, 0x44, 0xbe, 0xbb, 0x4a, 0xca, 0x7e, 0x23, 0x85, 0xc6, 0x0a, 0x39, 0x12, 0xe4, 0xa7, + 0xb0, 0xa9, 0xbe, 0xdf, 0x4d, 0x13, 0x1c, 0xe0, 0x8f, 0xe3, 0x0b, 0x6f, 0xe9, 0xae, 0x92, 0xa4, + 0x7c, 0xa0, 0x18, 0x13, 0x43, 0x18, 0x1a, 0xfc, 0x48, 0xd8, 0xbf, 0x2f, 0x43, 0x67, 0x7f, 0x19, + 0xb0, 0x50, 0x9a, 0x4f, 0xfb, 0xa1, 0xf9, 0xd0, 0x3b, 0x81, 0x49, 0x79, 0xe0, 0xe3, 0x8a, 0x37, + 0xd3, 0x1e, 0xcc, 0xd5, 0xaf, 0x57, 0xbc, 0xbc, 0xeb, 0x34, 0x7a, 0x09, 0x53, 0x8d, 0xaf, 0x68, + 0xcd, 0x67, 0x4c, 0x65, 0xc2, 0x8c, 0xaf, 0xab, 0x36, 0x13, 0x85, 0x53, 0xc3, 0x23, 0x9f, 0x01, + 0xde, 0x80, 0x67, 0xc1, 0xdc, 0x64, 0x65, 0xc3, 0xb4, 0x6a, 0x16, 0x3f, 0x6a, 0x08, 0xf6, 0x03, + 0xa8, 0x69, 0x63, 0xd2, 0x84, 0xea, 0x64, 0x8a, 0xa3, 0x49, 0x0d, 0x31, 0x7a, 0x32, 0x52, 0xbf, + 0xd6, 0x8a, 0x38, 0xdd, 0x9c, 0x17, 0xce, 0x68, 0x3a, 0xb1, 0x4a, 0xf6, 0xb7, 0x50, 0x4f, 0x22, + 0xd0, 0x84, 0xea, 0x81, 0x73, 0x78, 0x78, 0x6c, 0xe8, 0xce, 0xf3, 0x13, 0x67, 0x32, 0xb5, 0x8a, + 0xe4, 0x06, 0xb4, 0xc6, 0x27, 0x93, 0x03, 0xd7, 0x19, 0xed, 0xee, 0x1d, 0x3a, 0x56, 0x89, 0x58, + 0xd0, 0x56, 0x8a, 0xc1, 0x70, 0xa2, 0x34, 0x65, 0xd2, 0x05, 0x50, 0x9a, 0xf1, 0xee, 0xc9, 0xc4, + 0xb1, 0x2a, 0xa9, 0x09, 0x75, 0x26, 0x27, 0x47, 0x8e, 0x55, 0x25, 0x1b, 0xd0, 0x39, 0x19, 0xe3, + 0x98, 0x74, 0xf7, 0x8f, 0x47, 0x3f, 0x1f, 0x3e, 0xb5, 0xea, 0xf6, 0xdf, 0x8a, 0x70, 0xe3, 0x5a, + 0x5d, 0xe5, 0x36, 0x2e, 0x1d, 0xdd, 0x3e, 0xd4, 0xb8, 0xfa, 0x13, 0xc5, 0xcc, 0xf9, 0xcd, 0x37, + 0x14, 0xe3, 0x8e, 0xfe, 0x9b, 0x85, 0x1a, 0x66, 0x36, 0x18, 0x75, 0x0b, 0x9a, 0xc1, 0xf8, 0x25, + 0x58, 0xec, 0xec, 0x0c, 0x87, 0xd9, 0x05, 0x73, 0x4d, 0x28, 0x2b, 0x6f, 0x0b, 0xe5, 0x8d, 0x94, + 0xaa, 0xf5, 0xf6, 0x2d, 0xa8, 0xe9, 0xb7, 0x90, 0x1a, 0x94, 0x8e, 0xbf, 0xb6, 0x0a, 0xa4, 0x0e, + 0x65, 0x87, 0x52, 0xab, 0x88, 0x3f, 0x11, 0xf3, 0xc5, 0x4e, 0x3e, 0x83, 0xca, 0x79, 0x10, 0xea, + 0x8f, 0xe8, 0xf6, 0xdf, 0xbf, 0xde, 0x0c, 0x3b, 0x5f, 0x07, 0xa1, 0x4f, 0x15, 0xc5, 0xbe, 0x0d, + 0x15, 0x94, 0xc8, 0xfb, 0xb0, 0x31, 0x18, 0x4e, 0xf6, 0x77, 0xe9, 0x60, 0x38, 0x7a, 0xea, 0x9a, + 0xd4, 0x14, 0xee, 0x3b, 0x6f, 0xbc, 0x8e, 0x00, 0x6a, 0xfb, 0x87, 0xc7, 0x13, 0x67, 0x60, 0x15, + 0x31, 0x4d, 0xc7, 0x63, 0x67, 0x84, 0x57, 0x53, 0x09, 0x05, 0x04, 0x50, 0x28, 0x63, 0x2e, 0x1d, + 0x4a, 0x8f, 0xa9, 0x55, 0xb9, 0x7f, 0x0f, 0x2a, 0xb8, 0x89, 0xe2, 0x65, 0x35, 0x1c, 0x0d, 0xa7, + 0xc3, 0xdd, 0xe9, 0x31, 0xb5, 0x0a, 0x28, 0x52, 0x67, 0x32, 0x3e, 0x1e, 0x0d, 0xf0, 0xb7, 0xfc, + 0x5e, 0xef, 0xef, 0x2f, 0xb7, 0x8a, 0xdf, 0xbd, 0xdc, 0x2a, 0xfe, 0xe7, 0xe5, 0x56, 0xf1, 0x8f, + 0xaf, 0xb6, 0x0a, 0xdf, 0xbd, 0xda, 0x2a, 0xfc, 0xf3, 0xd5, 0x56, 0xe1, 0xb4, 0xa6, 0x56, 0xa1, + 0xc7, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x54, 0x4b, 0x9d, 0x7a, 0x0f, 0x13, 0x00, 0x00, +} + +func (m *Version) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Version) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Version) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Version != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Version)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ResultCounter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResultCounter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResultCounter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Err != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Err)) + i-- + dAtA[i] = 0x18 + } + if m.Ok != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Ok)) + i-- + dAtA[i] = 0x10 + } + if m.Total != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Total)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SlidingCounter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SlidingCounter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SlidingCounter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Over_24Hr != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_24Hr)) + i-- + dAtA[i] = 0x50 + } + if m.Over_12Hr != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_12Hr)) + i-- + dAtA[i] = 0x48 + } + if m.Over_8Hr != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_8Hr)) + i-- + dAtA[i] = 0x40 + } + if m.Over_4Hr != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_4Hr)) + i-- + dAtA[i] = 0x38 + } + if m.Over_2Hr != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_2Hr)) + i-- + dAtA[i] = 0x30 + } + if m.Over_1Hr != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_1Hr)) + i-- + dAtA[i] = 0x28 + } + if m.Over_30M != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_30M)) + i-- + dAtA[i] = 0x20 + } + if m.Over_15M != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_15M)) + i-- + dAtA[i] = 0x18 + } + if m.Over_5M != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_5M)) + i-- + dAtA[i] = 0x10 + } + if m.Over_1M != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Over_1M)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DataGauge) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DataGauge) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DataGauge) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.InstBw != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.InstBw)) + i-- + dAtA[i] = 0x18 + } + if m.CumPackets != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.CumPackets)) + i-- + dAtA[i] = 0x10 + } + if m.CumBytes != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.CumBytes)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EventType) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventType) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventType) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PropertyTypes) > 0 { + for iNdEx := len(m.PropertyTypes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PropertyTypes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventType_EventProperty) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EventType_EventProperty) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventType_EventProperty) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.HasMultiple { + i-- + if m.HasMultiple { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if m.Type != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Runtime) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Runtime) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Runtime) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.EventTypes) > 0 { + for iNdEx := len(m.EventTypes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.EventTypes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if len(m.PeerId) > 0 { + i -= len(m.PeerId) + copy(dAtA[i:], m.PeerId) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.PeerId))) + i-- + dAtA[i] = 0x22 + } + if len(m.Platform) > 0 { + i -= len(m.Platform) + copy(dAtA[i:], m.Platform) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Platform))) + i-- + dAtA[i] = 0x1a + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + } + if len(m.Implementation) > 0 { + i -= len(m.Implementation) + copy(dAtA[i:], m.Implementation) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Implementation))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EndpointPair) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EndpointPair) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EndpointPair) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DstMultiaddr) > 0 { + i -= len(m.DstMultiaddr) + copy(dAtA[i:], m.DstMultiaddr) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.DstMultiaddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.SrcMultiaddr) > 0 { + i -= len(m.SrcMultiaddr) + copy(dAtA[i:], m.SrcMultiaddr) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.SrcMultiaddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Traffic) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Traffic) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Traffic) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.TrafficOut != nil { + { + size, err := m.TrafficOut.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.TrafficIn != nil { + { + size, err := m.TrafficIn.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *StreamList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StreamList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StreamList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Streams) > 0 { + for iNdEx := len(m.Streams) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Streams[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.StreamIds) > 0 { + for iNdEx := len(m.StreamIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.StreamIds[iNdEx]) + copy(dAtA[i:], m.StreamIds[iNdEx]) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.StreamIds[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Connection) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Connection) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Connection) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.UserProvidedTags) > 0 { + for iNdEx := len(m.UserProvidedTags) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UserProvidedTags[iNdEx]) + copy(dAtA[i:], m.UserProvidedTags[iNdEx]) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.UserProvidedTags[iNdEx]))) + i-- + dAtA[i] = 0x6 + i-- + dAtA[i] = 0x9a + } + } + if m.RelayedOver != nil { + { + size := m.RelayedOver.Size() + i -= size + if _, err := m.RelayedOver.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.Streams != nil { + { + size, err := m.Streams.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + if m.LatencyNs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.LatencyNs)) + i-- + dAtA[i] = 0x50 + } + if m.Attribs != nil { + { + size, err := m.Attribs.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + if m.Traffic != nil { + { + size, err := m.Traffic.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + if m.Role != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Role)) + i-- + dAtA[i] = 0x38 + } + if m.Timeline != nil { + { + size, err := m.Timeline.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.Endpoints != nil { + { + size, err := m.Endpoints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.TransportId) > 0 { + i -= len(m.TransportId) + copy(dAtA[i:], m.TransportId) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.TransportId))) + i-- + dAtA[i] = 0x22 + } + if m.Status != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x18 + } + if len(m.PeerId) > 0 { + i -= len(m.PeerId) + copy(dAtA[i:], m.PeerId) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.PeerId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Connection_ConnId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Connection_ConnId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ConnId != nil { + i -= len(m.ConnId) + copy(dAtA[i:], m.ConnId) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.ConnId))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + return len(dAtA) - i, nil +} +func (m *Connection_Conn) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Connection_Conn) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Conn != nil { + { + size, err := m.Conn.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } + return len(dAtA) - i, nil +} +func (m *Connection_Timeline) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Connection_Timeline) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Connection_Timeline) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CloseTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.CloseTs)) + i-- + dAtA[i] = 0x18 + } + if m.UpgradedTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.UpgradedTs)) + i-- + dAtA[i] = 0x10 + } + if m.OpenTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.OpenTs)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Connection_Attributes) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Connection_Attributes) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Connection_Attributes) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Encryption) > 0 { + i -= len(m.Encryption) + copy(dAtA[i:], m.Encryption) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Encryption))) + i-- + dAtA[i] = 0x12 + } + if len(m.Multiplexer) > 0 { + i -= len(m.Multiplexer) + copy(dAtA[i:], m.Multiplexer) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Multiplexer))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Stream) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Stream) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Stream) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.UserProvidedTags) > 0 { + for iNdEx := len(m.UserProvidedTags) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UserProvidedTags[iNdEx]) + copy(dAtA[i:], m.UserProvidedTags[iNdEx]) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.UserProvidedTags[iNdEx]))) + i-- + dAtA[i] = 0x6 + i-- + dAtA[i] = 0x9a + } + } + if m.LatencyNs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.LatencyNs)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } + if m.Status != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x38 + } + if m.Timeline != nil { + { + size, err := m.Timeline.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.Conn != nil { + { + size, err := m.Conn.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.Traffic != nil { + { + size, err := m.Traffic.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Role != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Role)) + i-- + dAtA[i] = 0x18 + } + if len(m.Protocol) > 0 { + i -= len(m.Protocol) + copy(dAtA[i:], m.Protocol) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Protocol))) + i-- + dAtA[i] = 0x12 + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Stream_ConnectionRef) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Stream_ConnectionRef) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Stream_ConnectionRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Connection != nil { + { + size := m.Connection.Size() + i -= size + if _, err := m.Connection.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *Stream_ConnectionRef_Conn) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Stream_ConnectionRef_Conn) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Conn != nil { + { + size, err := m.Conn.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *Stream_ConnectionRef_ConnId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Stream_ConnectionRef_ConnId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ConnId != nil { + i -= len(m.ConnId) + copy(dAtA[i:], m.ConnId) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.ConnId))) + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *Stream_Timeline) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Stream_Timeline) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Stream_Timeline) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CloseTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.CloseTs)) + i-- + dAtA[i] = 0x10 + } + if m.OpenTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.OpenTs)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DHT) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DHT) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DHT) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.OutgoingQueries != nil { + { + size, err := m.OutgoingQueries.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + if m.IncomingQueries != nil { + { + size, err := m.IncomingQueries.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if len(m.Buckets) > 0 { + for iNdEx := len(m.Buckets) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Buckets[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if m.Params != nil { + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.StartTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.StartTs)) + i-- + dAtA[i] = 0x18 + } + if m.Enabled { + i-- + if m.Enabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.Protocol) > 0 { + i -= len(m.Protocol) + copy(dAtA[i:], m.Protocol) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Protocol))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DHT_Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DHT_Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DHT_Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Beta != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Beta)) + i-- + dAtA[i] = 0x20 + } + if m.DisjointPaths != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.DisjointPaths)) + i-- + dAtA[i] = 0x18 + } + if m.Alpha != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Alpha)) + i-- + dAtA[i] = 0x10 + } + if m.K != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.K)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DHT_PeerInDHT) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DHT_PeerInDHT) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DHT_PeerInDHT) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.AgeInBucket != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.AgeInBucket)) + i-- + dAtA[i] = 0x18 + } + if m.Status != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x10 + } + if len(m.PeerId) > 0 { + i -= len(m.PeerId) + copy(dAtA[i:], m.PeerId) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.PeerId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DHT_Bucket) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DHT_Bucket) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DHT_Bucket) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Peers) > 0 { + for iNdEx := len(m.Peers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Peers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Cpl != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Cpl)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DHT_QueryGauge) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DHT_QueryGauge) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DHT_QueryGauge) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timeout != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Timeout)) + i-- + dAtA[i] = 0x18 + } + if m.Error != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Error)) + i-- + dAtA[i] = 0x10 + } + if m.Success != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Success)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Subsystems) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Subsystems) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Subsystems) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Dht != nil { + { + size, err := m.Dht.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Connections) > 0 { + for iNdEx := len(m.Connections) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Connections[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *State) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *State) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SnapshotDurationMs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.SnapshotDurationMs)) + i-- + dAtA[i] = 0x28 + } + if m.StartTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.StartTs)) + i-- + dAtA[i] = 0x20 + } + if m.InstantTs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.InstantTs)) + i-- + dAtA[i] = 0x18 + } + if m.Traffic != nil { + { + size, err := m.Traffic.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Subsystems != nil { + { + size, err := m.Subsystems.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Event) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Event) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Event) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Content) > 0 { + i -= len(m.Content) + copy(dAtA[i:], m.Content) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Content))) + i-- + dAtA[i] = 0x1a + } + if m.Ts != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Ts)) + i-- + dAtA[i] = 0x10 + } + if m.Type != nil { + { + size, err := m.Type.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ServerMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ServerMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Payload != nil { + { + size := m.Payload.Size() + i -= size + if _, err := m.Payload.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.Version != nil { + { + size, err := m.Version.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ServerMessage_State) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerMessage_State) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.State != nil { + { + size, err := m.State.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *ServerMessage_Runtime) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerMessage_Runtime) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Runtime != nil { + { + size, err := m.Runtime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *ServerMessage_Event) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerMessage_Event) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Event != nil { + { + size, err := m.Event.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} +func (m *ServerMessage_Response) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerMessage_Response) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Response != nil { + { + size, err := m.Response.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + return len(dAtA) - i, nil +} +func (m *ServerMessage_Notice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerMessage_Notice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Notice != nil { + { + size, err := m.Notice.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + return len(dAtA) - i, nil +} +func (m *Configuration) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Configuration) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Configuration) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.StateSnapshotIntervalMs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.StateSnapshotIntervalMs)) + i-- + dAtA[i] = 0x10 + } + if m.RetentionPeriodMs != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.RetentionPeriodMs)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ClientCommand) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClientCommand) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClientCommand) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Config != nil { + { + size, err := m.Config.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.Source != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Source)) + i-- + dAtA[i] = 0x20 + } + if m.Command != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Command)) + i-- + dAtA[i] = 0x18 + } + if m.Id != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x10 + } + if m.Version != nil { + { + size, err := m.Version.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CommandResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CommandResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CommandResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.EffectiveConfig != nil { + { + size, err := m.EffectiveConfig.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintIntrospection(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintIntrospection(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x1a + } + if m.Result != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ServerNotice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ServerNotice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServerNotice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Kind != 0 { + i = encodeVarintIntrospection(dAtA, i, uint64(m.Kind)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintIntrospection(dAtA []byte, offset int, v uint64) int { + offset -= sovIntrospection(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Version) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Version != 0 { + n += 1 + sovIntrospection(uint64(m.Version)) + } + return n +} + +func (m *ResultCounter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Total != 0 { + n += 1 + sovIntrospection(uint64(m.Total)) + } + if m.Ok != 0 { + n += 1 + sovIntrospection(uint64(m.Ok)) + } + if m.Err != 0 { + n += 1 + sovIntrospection(uint64(m.Err)) + } + return n +} + +func (m *SlidingCounter) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Over_1M != 0 { + n += 1 + sovIntrospection(uint64(m.Over_1M)) + } + if m.Over_5M != 0 { + n += 1 + sovIntrospection(uint64(m.Over_5M)) + } + if m.Over_15M != 0 { + n += 1 + sovIntrospection(uint64(m.Over_15M)) + } + if m.Over_30M != 0 { + n += 1 + sovIntrospection(uint64(m.Over_30M)) + } + if m.Over_1Hr != 0 { + n += 1 + sovIntrospection(uint64(m.Over_1Hr)) + } + if m.Over_2Hr != 0 { + n += 1 + sovIntrospection(uint64(m.Over_2Hr)) + } + if m.Over_4Hr != 0 { + n += 1 + sovIntrospection(uint64(m.Over_4Hr)) + } + if m.Over_8Hr != 0 { + n += 1 + sovIntrospection(uint64(m.Over_8Hr)) + } + if m.Over_12Hr != 0 { + n += 1 + sovIntrospection(uint64(m.Over_12Hr)) + } + if m.Over_24Hr != 0 { + n += 1 + sovIntrospection(uint64(m.Over_24Hr)) + } + return n +} + +func (m *DataGauge) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CumBytes != 0 { + n += 1 + sovIntrospection(uint64(m.CumBytes)) + } + if m.CumPackets != 0 { + n += 1 + sovIntrospection(uint64(m.CumPackets)) + } + if m.InstBw != 0 { + n += 1 + sovIntrospection(uint64(m.InstBw)) + } + return n +} + +func (m *EventType) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if len(m.PropertyTypes) > 0 { + for _, e := range m.PropertyTypes { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *EventType_EventProperty) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Type != 0 { + n += 1 + sovIntrospection(uint64(m.Type)) + } + if m.HasMultiple { + n += 2 + } + return n +} + +func (m *Runtime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Implementation) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.Platform) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.PeerId) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if len(m.EventTypes) > 0 { + for _, e := range m.EventTypes { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *EndpointPair) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SrcMultiaddr) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.DstMultiaddr) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *Traffic) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TrafficIn != nil { + l = m.TrafficIn.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.TrafficOut != nil { + l = m.TrafficOut.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *StreamList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.StreamIds) > 0 { + for _, b := range m.StreamIds { + l = len(b) + n += 1 + l + sovIntrospection(uint64(l)) + } + } + if len(m.Streams) > 0 { + for _, e := range m.Streams { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *Connection) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.PeerId) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovIntrospection(uint64(m.Status)) + } + l = len(m.TransportId) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Endpoints != nil { + l = m.Endpoints.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Timeline != nil { + l = m.Timeline.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Role != 0 { + n += 1 + sovIntrospection(uint64(m.Role)) + } + if m.Traffic != nil { + l = m.Traffic.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Attribs != nil { + l = m.Attribs.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.LatencyNs != 0 { + n += 1 + sovIntrospection(uint64(m.LatencyNs)) + } + if m.Streams != nil { + l = m.Streams.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.RelayedOver != nil { + n += m.RelayedOver.Size() + } + if len(m.UserProvidedTags) > 0 { + for _, s := range m.UserProvidedTags { + l = len(s) + n += 2 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *Connection_ConnId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ConnId != nil { + l = len(m.ConnId) + n += 2 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *Connection_Conn) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Conn != nil { + l = m.Conn.Size() + n += 2 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *Connection_Timeline) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OpenTs != 0 { + n += 1 + sovIntrospection(uint64(m.OpenTs)) + } + if m.UpgradedTs != 0 { + n += 1 + sovIntrospection(uint64(m.UpgradedTs)) + } + if m.CloseTs != 0 { + n += 1 + sovIntrospection(uint64(m.CloseTs)) + } + return n +} + +func (m *Connection_Attributes) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Multiplexer) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.Encryption) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *Stream) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + l = len(m.Protocol) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Role != 0 { + n += 1 + sovIntrospection(uint64(m.Role)) + } + if m.Traffic != nil { + l = m.Traffic.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Conn != nil { + l = m.Conn.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Timeline != nil { + l = m.Timeline.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovIntrospection(uint64(m.Status)) + } + if m.LatencyNs != 0 { + n += 2 + sovIntrospection(uint64(m.LatencyNs)) + } + if len(m.UserProvidedTags) > 0 { + for _, s := range m.UserProvidedTags { + l = len(s) + n += 2 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *Stream_ConnectionRef) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Connection != nil { + n += m.Connection.Size() + } + return n +} + +func (m *Stream_ConnectionRef_Conn) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Conn != nil { + l = m.Conn.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *Stream_ConnectionRef_ConnId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ConnId != nil { + l = len(m.ConnId) + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *Stream_Timeline) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OpenTs != 0 { + n += 1 + sovIntrospection(uint64(m.OpenTs)) + } + if m.CloseTs != 0 { + n += 1 + sovIntrospection(uint64(m.CloseTs)) + } + return n +} + +func (m *DHT) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Protocol) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Enabled { + n += 2 + } + if m.StartTs != 0 { + n += 1 + sovIntrospection(uint64(m.StartTs)) + } + if m.Params != nil { + l = m.Params.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if len(m.Buckets) > 0 { + for _, e := range m.Buckets { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + if m.IncomingQueries != nil { + l = m.IncomingQueries.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.OutgoingQueries != nil { + l = m.OutgoingQueries.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *DHT_Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.K != 0 { + n += 1 + sovIntrospection(uint64(m.K)) + } + if m.Alpha != 0 { + n += 1 + sovIntrospection(uint64(m.Alpha)) + } + if m.DisjointPaths != 0 { + n += 1 + sovIntrospection(uint64(m.DisjointPaths)) + } + if m.Beta != 0 { + n += 1 + sovIntrospection(uint64(m.Beta)) + } + return n +} + +func (m *DHT_PeerInDHT) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PeerId) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovIntrospection(uint64(m.Status)) + } + if m.AgeInBucket != 0 { + n += 1 + sovIntrospection(uint64(m.AgeInBucket)) + } + return n +} + +func (m *DHT_Bucket) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Cpl != 0 { + n += 1 + sovIntrospection(uint64(m.Cpl)) + } + if len(m.Peers) > 0 { + for _, e := range m.Peers { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + return n +} + +func (m *DHT_QueryGauge) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Success != 0 { + n += 1 + sovIntrospection(uint64(m.Success)) + } + if m.Error != 0 { + n += 1 + sovIntrospection(uint64(m.Error)) + } + if m.Timeout != 0 { + n += 1 + sovIntrospection(uint64(m.Timeout)) + } + return n +} + +func (m *Subsystems) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Connections) > 0 { + for _, e := range m.Connections { + l = e.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + } + if m.Dht != nil { + l = m.Dht.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *State) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Subsystems != nil { + l = m.Subsystems.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Traffic != nil { + l = m.Traffic.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.InstantTs != 0 { + n += 1 + sovIntrospection(uint64(m.InstantTs)) + } + if m.StartTs != 0 { + n += 1 + sovIntrospection(uint64(m.StartTs)) + } + if m.SnapshotDurationMs != 0 { + n += 1 + sovIntrospection(uint64(m.SnapshotDurationMs)) + } + return n +} + +func (m *Event) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != nil { + l = m.Type.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Ts != 0 { + n += 1 + sovIntrospection(uint64(m.Ts)) + } + l = len(m.Content) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *ServerMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Version != nil { + l = m.Version.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Payload != nil { + n += m.Payload.Size() + } + return n +} + +func (m *ServerMessage_State) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.State != nil { + l = m.State.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *ServerMessage_Runtime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Runtime != nil { + l = m.Runtime.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *ServerMessage_Event) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Event != nil { + l = m.Event.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *ServerMessage_Response) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Response != nil { + l = m.Response.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *ServerMessage_Notice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Notice != nil { + l = m.Notice.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} +func (m *Configuration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.RetentionPeriodMs != 0 { + n += 1 + sovIntrospection(uint64(m.RetentionPeriodMs)) + } + if m.StateSnapshotIntervalMs != 0 { + n += 1 + sovIntrospection(uint64(m.StateSnapshotIntervalMs)) + } + return n +} + +func (m *ClientCommand) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Version != nil { + l = m.Version.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.Id != 0 { + n += 1 + sovIntrospection(uint64(m.Id)) + } + if m.Command != 0 { + n += 1 + sovIntrospection(uint64(m.Command)) + } + if m.Source != 0 { + n += 1 + sovIntrospection(uint64(m.Source)) + } + if m.Config != nil { + l = m.Config.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *CommandResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovIntrospection(uint64(m.Id)) + } + if m.Result != 0 { + n += 1 + sovIntrospection(uint64(m.Result)) + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovIntrospection(uint64(l)) + } + if m.EffectiveConfig != nil { + l = m.EffectiveConfig.Size() + n += 1 + l + sovIntrospection(uint64(l)) + } + return n +} + +func (m *ServerNotice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Kind != 0 { + n += 1 + sovIntrospection(uint64(m.Kind)) + } + return n +} + +func sovIntrospection(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozIntrospection(x uint64) (n int) { + return sovIntrospection(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Version) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Version: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Version: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + m.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Version |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ResultCounter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ResultCounter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResultCounter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) + } + m.Total = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Total |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ok", wireType) + } + m.Ok = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ok |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Err", wireType) + } + m.Err = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Err |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SlidingCounter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SlidingCounter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SlidingCounter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_1M", wireType) + } + m.Over_1M = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_1M |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_5M", wireType) + } + m.Over_5M = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_5M |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_15M", wireType) + } + m.Over_15M = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_15M |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_30M", wireType) + } + m.Over_30M = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_30M |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_1Hr", wireType) + } + m.Over_1Hr = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_1Hr |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_2Hr", wireType) + } + m.Over_2Hr = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_2Hr |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_4Hr", wireType) + } + m.Over_4Hr = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_4Hr |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_8Hr", wireType) + } + m.Over_8Hr = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_8Hr |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_12Hr", wireType) + } + m.Over_12Hr = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_12Hr |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Over_24Hr", wireType) + } + m.Over_24Hr = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Over_24Hr |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DataGauge) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DataGauge: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DataGauge: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CumBytes", wireType) + } + m.CumBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CumBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CumPackets", wireType) + } + m.CumPackets = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CumPackets |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InstBw", wireType) + } + m.InstBw = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InstBw |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventType) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventType: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventType: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PropertyTypes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PropertyTypes = append(m.PropertyTypes, &EventType_EventProperty{}) + if err := m.PropertyTypes[len(m.PropertyTypes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventType_EventProperty) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EventProperty: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventProperty: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= EventType_EventProperty_PropertyType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HasMultiple", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.HasMultiple = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Runtime) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Runtime: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Runtime: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Implementation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Implementation = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Platform", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Platform = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PeerId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PeerId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EventTypes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EventTypes = append(m.EventTypes, &EventType{}) + if err := m.EventTypes[len(m.EventTypes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EndpointPair) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EndpointPair: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EndpointPair: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SrcMultiaddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SrcMultiaddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DstMultiaddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DstMultiaddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Traffic) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Traffic: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Traffic: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrafficIn", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TrafficIn == nil { + m.TrafficIn = &DataGauge{} + } + if err := m.TrafficIn.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrafficOut", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TrafficOut == nil { + m.TrafficOut = &DataGauge{} + } + if err := m.TrafficOut.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StreamList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StreamList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StreamList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StreamIds", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StreamIds = append(m.StreamIds, make([]byte, postIndex-iNdEx)) + copy(m.StreamIds[len(m.StreamIds)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Streams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Streams = append(m.Streams, &Stream{}) + if err := m.Streams[len(m.Streams)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Connection) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Connection: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Connection: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PeerId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PeerId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= Status(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TransportId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TransportId = append(m.TransportId[:0], dAtA[iNdEx:postIndex]...) + if m.TransportId == nil { + m.TransportId = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Endpoints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Endpoints == nil { + m.Endpoints = &EndpointPair{} + } + if err := m.Endpoints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timeline", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Timeline == nil { + m.Timeline = &Connection_Timeline{} + } + if err := m.Timeline.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + m.Role = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Role |= Role(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Traffic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Traffic == nil { + m.Traffic = &Traffic{} + } + if err := m.Traffic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attribs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Attribs == nil { + m.Attribs = &Connection_Attributes{} + } + if err := m.Attribs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LatencyNs", wireType) + } + m.LatencyNs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LatencyNs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Streams", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Streams == nil { + m.Streams = &StreamList{} + } + if err := m.Streams.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.RelayedOver = &Connection_ConnId{v} + iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conn", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &Connection{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.RelayedOver = &Connection_Conn{v} + iNdEx = postIndex + case 99: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserProvidedTags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserProvidedTags = append(m.UserProvidedTags, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Connection_Timeline) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Timeline: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Timeline: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OpenTs", wireType) + } + m.OpenTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OpenTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradedTs", wireType) + } + m.UpgradedTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpgradedTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CloseTs", wireType) + } + m.CloseTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CloseTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Connection_Attributes) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Attributes: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Attributes: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Multiplexer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Multiplexer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Encryption", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Encryption = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Stream) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Stream: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Stream: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Protocol = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + m.Role = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Role |= Role(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Traffic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Traffic == nil { + m.Traffic = &Traffic{} + } + if err := m.Traffic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conn", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Conn == nil { + m.Conn = &Stream_ConnectionRef{} + } + if err := m.Conn.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timeline", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Timeline == nil { + m.Timeline = &Stream_Timeline{} + } + if err := m.Timeline.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= Status(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LatencyNs", wireType) + } + m.LatencyNs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LatencyNs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 99: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserProvidedTags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserProvidedTags = append(m.UserProvidedTags, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Stream_ConnectionRef) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConnectionRef: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConnectionRef: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conn", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &Connection{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Connection = &Stream_ConnectionRef_Conn{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.Connection = &Stream_ConnectionRef_ConnId{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Stream_Timeline) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Timeline: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Timeline: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OpenTs", wireType) + } + m.OpenTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OpenTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CloseTs", wireType) + } + m.CloseTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CloseTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DHT) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DHT: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DHT: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Protocol = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTs", wireType) + } + m.StartTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Params == nil { + m.Params = &DHT_Params{} + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Buckets", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Buckets = append(m.Buckets, &DHT_Bucket{}) + if err := m.Buckets[len(m.Buckets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IncomingQueries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.IncomingQueries == nil { + m.IncomingQueries = &DHT_QueryGauge{} + } + if err := m.IncomingQueries.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OutgoingQueries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OutgoingQueries == nil { + m.OutgoingQueries = &DHT_QueryGauge{} + } + if err := m.OutgoingQueries.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DHT_Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field K", wireType) + } + m.K = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.K |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Alpha", wireType) + } + m.Alpha = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Alpha |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DisjointPaths", wireType) + } + m.DisjointPaths = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DisjointPaths |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Beta", wireType) + } + m.Beta = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Beta |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DHT_PeerInDHT) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PeerInDHT: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PeerInDHT: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PeerId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PeerId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= DHT_PeerInDHT_Status(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AgeInBucket", wireType) + } + m.AgeInBucket = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AgeInBucket |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DHT_Bucket) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Bucket: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Bucket: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Cpl", wireType) + } + m.Cpl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Cpl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Peers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Peers = append(m.Peers, &DHT_PeerInDHT{}) + if err := m.Peers[len(m.Peers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DHT_QueryGauge) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryGauge: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGauge: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + m.Success = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Success |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + m.Error = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Error |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType) + } + m.Timeout = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timeout |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Subsystems) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Subsystems: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Subsystems: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Connections", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Connections = append(m.Connections, &Connection{}) + if err := m.Connections[len(m.Connections)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dht", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Dht == nil { + m.Dht = &DHT{} + } + if err := m.Dht.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *State) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: State: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: State: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subsystems", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subsystems == nil { + m.Subsystems = &Subsystems{} + } + if err := m.Subsystems.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Traffic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Traffic == nil { + m.Traffic = &Traffic{} + } + if err := m.Traffic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InstantTs", wireType) + } + m.InstantTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InstantTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTs", wireType) + } + m.StartTs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotDurationMs", wireType) + } + m.SnapshotDurationMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SnapshotDurationMs |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Event) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Event: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Type == nil { + m.Type = &EventType{} + } + if err := m.Type.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ts", wireType) + } + m.Ts = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ts |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Content", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Content = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ServerMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ServerMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ServerMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Version == nil { + m.Version = &Version{} + } + if err := m.Version.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &State{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Payload = &ServerMessage_State{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Runtime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &Runtime{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Payload = &ServerMessage_Runtime{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &Event{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Payload = &ServerMessage_Event{v} + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Response", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &CommandResponse{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Payload = &ServerMessage_Response{v} + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Notice", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &ServerNotice{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Payload = &ServerMessage_Notice{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Configuration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Configuration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Configuration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RetentionPeriodMs", wireType) + } + m.RetentionPeriodMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RetentionPeriodMs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StateSnapshotIntervalMs", wireType) + } + m.StateSnapshotIntervalMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StateSnapshotIntervalMs |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClientCommand) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClientCommand: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClientCommand: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Version == nil { + m.Version = &Version{} + } + if err := m.Version.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType) + } + m.Command = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Command |= ClientCommand_Command(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + m.Source = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Source |= ClientCommand_Source(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Config == nil { + m.Config = &Configuration{} + } + if err := m.Config.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CommandResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CommandResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CommandResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= CommandResponse_Result(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EffectiveConfig", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthIntrospection + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthIntrospection + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.EffectiveConfig == nil { + m.EffectiveConfig = &Configuration{} + } + if err := m.EffectiveConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ServerNotice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ServerNotice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ServerNotice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + m.Kind = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIntrospection + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Kind |= ServerNotice_Kind(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipIntrospection(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthIntrospection + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipIntrospection(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowIntrospection + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthIntrospection + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupIntrospection + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthIntrospection + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthIntrospection = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowIntrospection = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupIntrospection = fmt.Errorf("proto: unexpected end of group") +) diff --git a/core/introspection/pb/introspection.proto b/core/introspection/pb/introspection.proto new file mode 100644 index 0000000000..144e7b9954 --- /dev/null +++ b/core/introspection/pb/introspection.proto @@ -0,0 +1,421 @@ +syntax = "proto3"; + +package pb; + +// Version of schema +message Version { + uint32 version = 1; +} +// ResultCounter is a monotonically increasing counter that reports an ok/err breakdown of the total. +message ResultCounter { + uint32 total = 1; + uint32 ok = 2; + uint32 err = 3; +} + +// Moving totals over sliding time windows. Models sensible time windows, +// we don't have to populate them all at once. +// +// Graphical example: +// +// time past -> present an event 16 min ago +// ======================================================X================>> +// | | 1m +// | |---| 5m +// | |-------------| 15m +// |------------X---------------| 30m +// |------------------------------------------X---------------| 60m +message SlidingCounter { + uint32 over_1m = 1; + uint32 over_5m = 2; + uint32 over_15m = 3; + uint32 over_30m = 4; + uint32 over_1hr = 5; + uint32 over_2hr = 6; + uint32 over_4hr = 7; + uint32 over_8hr = 8; + uint32 over_12hr = 9; + uint32 over_24hr = 10; +} + +// DataGauge reports stats for data traffic in a given direction. +message DataGauge { + // Cumulative bytes. + uint64 cum_bytes = 1; + // Cumulative packets. + uint64 cum_packets = 2; + // Instantaneous bandwidth measurement (bytes/second). + uint64 inst_bw = 3; +} + +// describes a type of event +message EventType { + // metadata about content types in event's top-level content JSON + message EventProperty { + // tells client how to sort, filter or display known content properties + enum PropertyType { + // for properties to treat as a simple primitive + STRING = 0; // default + NUMBER = 1; + // for properties with special human-readable formatting + TIME = 10; + PEERID = 11; + MULTIADDR = 12; + // for complex structures like nested arrays, object trees etc + JSON = 90; + } + // property name of content e.g. openTs + string name = 1; + // type to interpret content value as + PropertyType type = 2; + // if true, expect an array of values of `type`; else, singular + bool has_multiple = 3; + } + + // name of event type, e.g. PeerConnecting + string name = 1; + // for runtime, send property_types for all events already seen in events list + // for events, only send property_types in the first event of a type not in runtime + repeated EventProperty property_types = 2; +} + +// Runtime encapsulates runtime info about a node. +message Runtime { + // e.g. go-libp2p, js-libp2p, rust-libp2p, etc. + string implementation = 1; + // e.g. 1.2.3. + string version = 2; + // e.g. Windows, Unix, macOS, Chrome, Mozilla, etc. + string platform = 3; + // our peer id - the peer id of the host system + string peer_id = 4; + // metadata describing configured event types + repeated EventType event_types = 7; +} + +// EndpointPair is a pair of multiaddrs. +message EndpointPair { + // the source multiaddr. + string src_multiaddr = 1; + // the destination multiaddr. + string dst_multiaddr = 2; +} + +// The status of a connection or stream. +enum Status { + ACTIVE = 0; + CLOSED = 1; + OPENING = 2; + CLOSING = 3; + ERROR = 4; +} + +// Our role in a connection or stream. +enum Role { + INITIATOR = 0; + RESPONDER = 1; +} + +// Traffic encloses data transfer statistics. +message Traffic { + // snapshot of the data in metrics. + DataGauge traffic_in = 1; + // snapshot of the data out metrics. + DataGauge traffic_out = 2; +} + +// a list of streams, by reference or inlined. +message StreamList { + // NOTE: only one of the next 2 fields can appear, but proto3 + // doesn't support combining oneof and repeated. + // + // streams within this connection by reference. + repeated bytes stream_ids = 1; + // streams within this connection by inlining. + repeated Stream streams = 2; +} + +// Connection reports metrics and state of a libp2p connection. +message Connection { + // Timeline contains the timestamps (ms since epoch) of the well-known milestones of a connection. + message Timeline { + // the instant when a connection was opened on the wire. + uint64 open_ts = 1; + // the instant when the upgrade process (handshake, security, multiplexing) finished. + uint64 upgraded_ts = 2; + // the instant when this connection was terminated. + uint64 close_ts = 3; + } + + // Attributes encapsulates the attributes of this connection. + message Attributes { + // the multiplexer being used. + string multiplexer = 1; + // the encryption method being used. + string encryption = 2; + } + + // the id of this connection, not to be shown in user tooling, + // used for (cross)referencing connections (e.g. relay). + bytes id = 1; + // the peer id of the other party. + string peer_id = 2; + // the status of this connection. + Status status = 3; + // a reference to the transport managing this connection. + bytes transport_id = 4; + // the endpoints participating in this connection. + EndpointPair endpoints = 5; + // the timeline of the connection, see Connection.Timeline. + Timeline timeline = 6; + // our role in this connection. + Role role = 7; + // traffic statistics. + Traffic traffic = 8; + // properties of this connection. + Attributes attribs = 9; + // the instantaneous latency of this connection in nanoseconds. + uint64 latency_ns = 10; + // streams within this connection. + StreamList streams = 11; + + reserved 12 to 15; + + // if this is a relayed connection, this points to the relaying connection. + // a default value here (empty bytes) indicates this is not a relayed connection. + oneof relayed_over { + bytes conn_id = 16; + Connection conn = 17; + } + // user provided tags. + repeated string user_provided_tags = 99; +} + +// Stream reports metrics and state of a libp2p stream. +message Stream { + message ConnectionRef { + oneof connection { + // the parent connection inlined. + Connection conn = 1; + // the parent connection by reference. + bytes conn_id = 2; + } + } + + // Timeline contains the timestamps (ms since epoch) of the well-known milestones of a stream. + message Timeline { + // the instant when the stream was opened. + uint64 open_ts = 1; + // the instant when the stream was terminated. + uint64 close_ts = 2; + } + + // the id of this stream, not to be shown in user tooling, + // used for (cross)referencing streams. + bytes id = 1; + // the protocol pinned to this stream. + string protocol = 2; + // our role in this stream. + Role role = 3; + // traffic statistics. + Traffic traffic = 4; + // the connection this stream is hosted under. + ConnectionRef conn = 5; + // the timeline of the stream, see Stream.Timeline. + Timeline timeline = 6; + // the status of this stream. + Status status = 7; + + // the instantaneous latency of this stream in nanoseconds. + // TODO: this is hard to calculate. + uint64 latency_ns = 16; + // user provided tags. + repeated string user_provided_tags = 99; +} + +// DHT metrics and state. +message DHT { + message Params { + // routing table bucket size. + uint64 k = 1; + // concurrency of asynchronous requests. + uint64 alpha = 2; + // number of disjoint paths to use. + uint64 disjoint_paths = 3; + // number of peers closest to a target that must have responded + // in order for a given query path to complete + uint64 beta = 4; + } + + // Peer in DHT + message PeerInDHT { + // The DHT's relationship with this peer + enum Status { + // Connected, in a bucket, ready to send/receive queries + ACTIVE = 0; + // Not currently connected, still "in" a bucket (e.g. temporarily disconnected) + MISSING = 1; + // Removed from a bucket or candidate list (e.g. connection lost or too slow) + REJECTED = 2; + // Was reachable when last checked, waiting to join a currently-full bucket + CANDIDATE = 3; + } + // the peer id of the host system + string peer_id = 1; + // the peer's status when data snapshot is taken + Status status = 2; + // age in bucket (ms) + uint32 age_in_bucket = 3; + } + + // A "k-bucket" containing peers of a certain kadamelia distance + message Bucket { + // CPL (Common Prefix Length) is the length of the common prefix + // between the ids of every peer in this bucket and the DHT peer id + uint32 cpl = 1; + // Peers associated with this bucket + repeated PeerInDHT peers = 2; + // Bucket may need more fields depending on WIP remodeling + } + + // Counters of query events, by status + message QueryGauge { + // Cumulative counter of queries with "SUCCESS" status + uint64 success = 1; + // Cumulative counter of queries with "ERROR" status + uint64 error = 2; + // Cumulative counter of queries with "TIMEOUT" status + uint64 timeout = 3; + } + + // DHT protocol name + string protocol = 1; + // protocol enabled. + bool enabled = 2; + // timestamp (ms since epoch) of start up. + uint64 start_ts = 3; + // params of the dht. + Params params = 4; + // existing, intantiated buckets and their contents + repeated Bucket buckets = 5; + // counts inbound queries received from other peers + QueryGauge incoming_queries = 6; + // counts outbound queries dispatched by this peer + QueryGauge outgoing_queries = 7; +} + +// Subsystems encapsulates all instrumented subsystems for a libp2p host. +message Subsystems { + // connections data, source agnostic but currently only supports the Swarm subsystem + repeated Connection connections = 1; + // the DHT subsystem. + DHT dht = 2; +} + +// Connections and streams output for a time interval is one of these. +message State { + // list of connections + Subsystems subsystems = 1; + // overall traffic for this peer + Traffic traffic = 2; + // moment this data snapshot and instantaneous values were taken + uint64 instant_ts = 3; + // start of included data collection (cumulative values counted from here) + uint64 start_ts = 4; + // length of time up to instant_ts covered by this data snapshot + uint32 snapshot_duration_ms = 5; +} + +// Event +message Event { + // definition of event type, containing only `name` unless this is first encounter of novel event + EventType type = 1; + // time this event occurred (ms since epoch) + uint64 ts = 2; + // stringified json; top-level keys and value types match EventProperty definitions + string content = 3; +} + +// ServerMessage wraps messages to be sent to clients to allow extension +// based on new types of data sources +message ServerMessage { + // Version of this protobuf. + Version version = 1; + // The payload this message contains. + oneof payload { + State state = 2; + Runtime runtime = 3; + Event event = 4; + + CommandResponse response = 5; + ServerNotice notice = 6; + } +} + +// Configuration encapsulates configuration fields for the protocol and commands. +message Configuration { + uint64 retention_period_ms = 1; + uint64 state_snapshot_interval_ms = 2; +} + +// ClientCommand is a command sent from the client to the server. +message ClientCommand { + enum Source { + STATE = 0; // full state snapshot. + RUNTIME = 1; // runtime data message. + EVENTS = 2; // eventbus events. + } + + enum Command { + // HELLO is the first command that a client must send to greet the server. + // Connections that do not respect this invariant will be terminated. + HELLO = 0; + + // REQUEST is applicable to STATE and RUNTIME sources. + REQUEST = 1; + + // PUSH streams can only be started for STATE and EVENTS sources. + PUSH_ENABLE = 2; // enables pushing for a given source. + PUSH_DISABLE = 3; // disables pushing for a given source. + PUSH_PAUSE = 4; // pauses pushing for all sources. + PUSH_RESUME = 5; // resumes pushing for all sources. + + // UPDATE_CONFIG requests a configuration update. The config field is + // compulsory. + // + // The server reserves the right to override the requested values, and + // will return the effective configuration in the response. + UPDATE_CONFIG = 7; + } + + Version version = 1; + uint64 id = 2; // a unique ID for this request. + Command command = 3; + Source source = 4; + Configuration config = 5; +} + +// CommandResponse is a response to a command sent by the client. +message CommandResponse { + enum Result { + OK = 0; + ERR = 1; + } + + uint64 id = 1; // for correlation with the request. + Result result = 2; + string error = 3; + + // effective_config is the effective configuration the server holds for + // this connection. It is returned in response to HELLO and UPDATE_CONFIG + // commands. + Configuration effective_config = 4; +} + +// ServerNotice represents a NOTICE sent from the server to the client. +message ServerNotice { + enum Kind { + DISCARDING_EVENTS = 0; + } + Kind kind = 1; +} \ No newline at end of file diff --git a/core/metrics/bandwidth.go b/core/metrics/bandwidth.go new file mode 100644 index 0000000000..3532bf5ee0 --- /dev/null +++ b/core/metrics/bandwidth.go @@ -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 bandwith 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 / recieved 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 / recieved 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) +} diff --git a/core/metrics/bandwidth_test.go b/core/metrics/bandwidth_test.go new file mode 100644 index 0000000000..84c507ecc5 --- /dev/null +++ b/core/metrics/bandwidth_test.go @@ -0,0 +1,170 @@ +package metrics + +import ( + "fmt" + "sync" + "testing" + "time" + + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + + "github.com/libp2p/go-flow-metrics" + + "github.com/benbjohnson/clock" + "github.com/stretchr/testify/require" +) + +var cl = clock.NewMock() + +func init() { + flow.SetClock(cl) +} + +func BenchmarkBandwidthCounter(b *testing.B) { + b.StopTimer() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + bwc := NewBandwidthCounter() + round(bwc, b) + } +} + +func round(bwc *BandwidthCounter, b *testing.B) { + start := make(chan struct{}) + var wg sync.WaitGroup + wg.Add(10000) + for i := 0; i < 1000; i++ { + p := peer.ID(fmt.Sprintf("peer-%d", i)) + for j := 0; j < 10; j++ { + proto := protocol.ID(fmt.Sprintf("bitswap-%d", j)) + go func() { + defer wg.Done() + <-start + + for i := 0; i < 1000; i++ { + bwc.LogSentMessage(100) + bwc.LogSentMessageStream(100, proto, p) + time.Sleep(1 * time.Millisecond) + } + }() + } + } + + b.StartTimer() + close(start) + wg.Wait() + b.StopTimer() +} + +func TestBandwidthCounter(t *testing.T) { + bwc := NewBandwidthCounter() + for i := 0; i < 40; i++ { + for i := 0; i < 100; i++ { + p := peer.ID(fmt.Sprintf("peer-%d", i)) + for j := 0; j < 2; j++ { + proto := protocol.ID(fmt.Sprintf("proto-%d", j)) + + // make sure the bandwidth counters are active + bwc.LogSentMessage(100) + bwc.LogRecvMessage(50) + bwc.LogSentMessageStream(100, proto, p) + bwc.LogRecvMessageStream(50, proto, p) + + // <-start + } + } + cl.Add(100 * time.Millisecond) + } + + assertProtocols := func(check func(Stats)) { + byProtocol := bwc.GetBandwidthByProtocol() + require.Len(t, byProtocol, 2, "expected 2 protocols") + for i := 0; i < 2; i++ { + p := protocol.ID(fmt.Sprintf("proto-%d", i)) + for _, stats := range [...]Stats{bwc.GetBandwidthForProtocol(p), byProtocol[p]} { + check(stats) + } + } + } + + assertPeers := func(check func(Stats)) { + byPeer := bwc.GetBandwidthByPeer() + require.Len(t, byPeer, 100, "expected 100 peers") + for i := 0; i < 100; i++ { + p := peer.ID(fmt.Sprintf("peer-%d", i)) + for _, stats := range [...]Stats{bwc.GetBandwidthForPeer(p), byPeer[p]} { + check(stats) + } + } + } + + assertPeers(func(stats Stats) { + require.Equal(t, int64(8000), stats.TotalOut) + require.Equal(t, int64(4000), stats.TotalIn) + }) + + assertProtocols(func(stats Stats) { + require.Equal(t, int64(400000), stats.TotalOut) + require.Equal(t, int64(200000), stats.TotalIn) + }) + + stats := bwc.GetBandwidthTotals() + require.Equal(t, int64(800000), stats.TotalOut) + require.Equal(t, int64(400000), stats.TotalIn) +} + +func TestResetBandwidthCounter(t *testing.T) { + bwc := NewBandwidthCounter() + + p := peer.ID("peer-0") + proto := protocol.ID("proto-0") + + // We don't calculate bandwidth till we've been active for a second. + bwc.LogSentMessage(42) + bwc.LogRecvMessage(24) + bwc.LogSentMessageStream(100, proto, p) + bwc.LogRecvMessageStream(50, proto, p) + + time.Sleep(200 * time.Millisecond) // make sure the meters are registered with the sweeper + cl.Add(time.Second) + + bwc.LogSentMessage(42) + bwc.LogRecvMessage(24) + bwc.LogSentMessageStream(100, proto, p) + bwc.LogRecvMessageStream(50, proto, p) + + cl.Add(time.Second) + + { + stats := bwc.GetBandwidthTotals() + require.Equal(t, int64(84), stats.TotalOut) + require.Equal(t, int64(48), stats.TotalIn) + } + + { + stats := bwc.GetBandwidthByProtocol() + require.Len(t, stats, 1) + stat := stats[proto] + require.Equal(t, float64(100), stat.RateOut) + require.Equal(t, float64(50), stat.RateIn) + } + + { + stats := bwc.GetBandwidthByPeer() + require.Len(t, stats, 1) + stat := stats[p] + require.Equal(t, float64(100), stat.RateOut) + require.Equal(t, float64(50), stat.RateIn) + } + + bwc.Reset() + { + stats := bwc.GetBandwidthTotals() + require.Zero(t, stats.TotalOut) + require.Zero(t, stats.TotalIn) + require.Empty(t, bwc.GetBandwidthByProtocol(), "expected 0 protocols") + require.Empty(t, bwc.GetBandwidthByPeer(), "expected 0 peers") + } +} diff --git a/core/metrics/reporter.go b/core/metrics/reporter.go new file mode 100644 index 0000000000..466dff9d16 --- /dev/null +++ b/core/metrics/reporter.go @@ -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 +} diff --git a/core/network/conn.go b/core/network/conn.go new file mode 100644 index 0000000000..8554493e25 --- /dev/null +++ b/core/network/conn.go @@ -0,0 +1,76 @@ +package network + +import ( + "context" + "io" + + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + + 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 +} + +// 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 + + // LocalPrivateKey returns our private key + LocalPrivateKey() ic.PrivKey + + // RemotePeer returns the peer ID of the remote peer. + RemotePeer() peer.ID + + // RemotePublicKey returns the public key of the remote peer. + RemotePublicKey() ic.PubKey +} + +// 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 +} diff --git a/core/network/context.go b/core/network/context.go new file mode 100644 index 0000000000..7fabfb53e0 --- /dev/null +++ b/core/network/context.go @@ -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, "" +} diff --git a/core/network/context_test.go b/core/network/context_test.go new file mode 100644 index 0000000000..b12def5ef6 --- /dev/null +++ b/core/network/context_test.go @@ -0,0 +1,59 @@ +package network + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestDefaultTimeout(t *testing.T) { + ctx := context.Background() + dur := GetDialPeerTimeout(ctx) + if dur != DialPeerTimeout { + t.Fatal("expected default peer timeout") + } +} + +func TestNonDefaultTimeout(t *testing.T) { + customTimeout := time.Duration(1) + ctx := context.WithValue( + context.Background(), + dialPeerTimeoutCtxKey{}, + customTimeout, + ) + dur := GetDialPeerTimeout(ctx) + if dur != customTimeout { + t.Fatal("peer timeout doesn't match set timeout") + } +} + +func TestSettingTimeout(t *testing.T) { + customTimeout := time.Duration(1) + ctx := WithDialPeerTimeout( + context.Background(), + customTimeout, + ) + dur := GetDialPeerTimeout(ctx) + if dur != customTimeout { + t.Fatal("peer timeout doesn't match set timeout") + } +} + +func TestSimultaneousConnect(t *testing.T) { + t.Run("for the server", func(t *testing.T) { + serverCtx := WithSimultaneousConnect(context.Background(), false, "foobar") + ok, isClient, reason := GetSimultaneousConnect(serverCtx) + require.True(t, ok) + require.False(t, isClient) + require.Equal(t, reason, "foobar") + }) + t.Run("for the client", func(t *testing.T) { + serverCtx := WithSimultaneousConnect(context.Background(), true, "foo") + ok, isClient, reason := GetSimultaneousConnect(serverCtx) + require.True(t, ok) + require.True(t, isClient) + require.Equal(t, reason, "foo") + }) +} diff --git a/core/network/errors.go b/core/network/errors.go new file mode 100644 index 0000000000..2209ee2332 --- /dev/null +++ b/core/network/errors.go @@ -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 attemptig to reserve resources in a closed resource +// scope. +var ErrResourceScopeClosed = errors.New("resource scope closed") diff --git a/core/network/mocks/mock_conn_management_scope.go b/core/network/mocks/mock_conn_management_scope.go new file mode 100644 index 0000000000..5d847f91ff --- /dev/null +++ b/core/network/mocks/mock_conn_management_scope.go @@ -0,0 +1,131 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ConnManagementScope) + +// Package mocknetwork is a generated GoMock package. +package mocknetwork + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + network "github.com/libp2p/go-libp2p/core/network" + peer "github.com/libp2p/go-libp2p/core/peer" +) + +// MockConnManagementScope is a mock of ConnManagementScope interface. +type MockConnManagementScope struct { + ctrl *gomock.Controller + recorder *MockConnManagementScopeMockRecorder +} + +// MockConnManagementScopeMockRecorder is the mock recorder for MockConnManagementScope. +type MockConnManagementScopeMockRecorder struct { + mock *MockConnManagementScope +} + +// NewMockConnManagementScope creates a new mock instance. +func NewMockConnManagementScope(ctrl *gomock.Controller) *MockConnManagementScope { + mock := &MockConnManagementScope{ctrl: ctrl} + mock.recorder = &MockConnManagementScopeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockConnManagementScope) EXPECT() *MockConnManagementScopeMockRecorder { + return m.recorder +} + +// BeginSpan mocks base method. +func (m *MockConnManagementScope) BeginSpan() (network.ResourceScopeSpan, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeginSpan") + ret0, _ := ret[0].(network.ResourceScopeSpan) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeginSpan indicates an expected call of BeginSpan. +func (mr *MockConnManagementScopeMockRecorder) BeginSpan() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginSpan", reflect.TypeOf((*MockConnManagementScope)(nil).BeginSpan)) +} + +// Done mocks base method. +func (m *MockConnManagementScope) Done() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Done") +} + +// Done indicates an expected call of Done. +func (mr *MockConnManagementScopeMockRecorder) Done() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Done", reflect.TypeOf((*MockConnManagementScope)(nil).Done)) +} + +// PeerScope mocks base method. +func (m *MockConnManagementScope) PeerScope() network.PeerScope { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PeerScope") + ret0, _ := ret[0].(network.PeerScope) + return ret0 +} + +// PeerScope indicates an expected call of PeerScope. +func (mr *MockConnManagementScopeMockRecorder) PeerScope() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerScope", reflect.TypeOf((*MockConnManagementScope)(nil).PeerScope)) +} + +// ReleaseMemory mocks base method. +func (m *MockConnManagementScope) ReleaseMemory(arg0 int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReleaseMemory", arg0) +} + +// ReleaseMemory indicates an expected call of ReleaseMemory. +func (mr *MockConnManagementScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockConnManagementScope)(nil).ReleaseMemory), arg0) +} + +// ReserveMemory mocks base method. +func (m *MockConnManagementScope) ReserveMemory(arg0 int, arg1 byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReserveMemory", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ReserveMemory indicates an expected call of ReserveMemory. +func (mr *MockConnManagementScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockConnManagementScope)(nil).ReserveMemory), arg0, arg1) +} + +// SetPeer mocks base method. +func (m *MockConnManagementScope) SetPeer(arg0 peer.ID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPeer", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetPeer indicates an expected call of SetPeer. +func (mr *MockConnManagementScopeMockRecorder) SetPeer(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPeer", reflect.TypeOf((*MockConnManagementScope)(nil).SetPeer), arg0) +} + +// Stat mocks base method. +func (m *MockConnManagementScope) Stat() network.ScopeStat { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stat") + ret0, _ := ret[0].(network.ScopeStat) + return ret0 +} + +// Stat indicates an expected call of Stat. +func (mr *MockConnManagementScopeMockRecorder) Stat() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockConnManagementScope)(nil).Stat)) +} diff --git a/core/network/mocks/mock_peer_scope.go b/core/network/mocks/mock_peer_scope.go new file mode 100644 index 0000000000..1633839993 --- /dev/null +++ b/core/network/mocks/mock_peer_scope.go @@ -0,0 +1,105 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/libp2p/go-libp2p/core/network (interfaces: PeerScope) + +// Package mocknetwork is a generated GoMock package. +package mocknetwork + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + network "github.com/libp2p/go-libp2p/core/network" + peer "github.com/libp2p/go-libp2p/core/peer" +) + +// MockPeerScope is a mock of PeerScope interface. +type MockPeerScope struct { + ctrl *gomock.Controller + recorder *MockPeerScopeMockRecorder +} + +// MockPeerScopeMockRecorder is the mock recorder for MockPeerScope. +type MockPeerScopeMockRecorder struct { + mock *MockPeerScope +} + +// NewMockPeerScope creates a new mock instance. +func NewMockPeerScope(ctrl *gomock.Controller) *MockPeerScope { + mock := &MockPeerScope{ctrl: ctrl} + mock.recorder = &MockPeerScopeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPeerScope) EXPECT() *MockPeerScopeMockRecorder { + return m.recorder +} + +// BeginSpan mocks base method. +func (m *MockPeerScope) BeginSpan() (network.ResourceScopeSpan, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeginSpan") + ret0, _ := ret[0].(network.ResourceScopeSpan) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeginSpan indicates an expected call of BeginSpan. +func (mr *MockPeerScopeMockRecorder) BeginSpan() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginSpan", reflect.TypeOf((*MockPeerScope)(nil).BeginSpan)) +} + +// Peer mocks base method. +func (m *MockPeerScope) Peer() peer.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Peer") + ret0, _ := ret[0].(peer.ID) + return ret0 +} + +// Peer indicates an expected call of Peer. +func (mr *MockPeerScopeMockRecorder) Peer() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peer", reflect.TypeOf((*MockPeerScope)(nil).Peer)) +} + +// ReleaseMemory mocks base method. +func (m *MockPeerScope) ReleaseMemory(arg0 int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReleaseMemory", arg0) +} + +// ReleaseMemory indicates an expected call of ReleaseMemory. +func (mr *MockPeerScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockPeerScope)(nil).ReleaseMemory), arg0) +} + +// ReserveMemory mocks base method. +func (m *MockPeerScope) ReserveMemory(arg0 int, arg1 byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReserveMemory", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ReserveMemory indicates an expected call of ReserveMemory. +func (mr *MockPeerScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockPeerScope)(nil).ReserveMemory), arg0, arg1) +} + +// Stat mocks base method. +func (m *MockPeerScope) Stat() network.ScopeStat { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stat") + ret0, _ := ret[0].(network.ScopeStat) + return ret0 +} + +// Stat indicates an expected call of Stat. +func (mr *MockPeerScopeMockRecorder) Stat() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockPeerScope)(nil).Stat)) +} diff --git a/core/network/mocks/mock_protocol_scope.go b/core/network/mocks/mock_protocol_scope.go new file mode 100644 index 0000000000..646eede623 --- /dev/null +++ b/core/network/mocks/mock_protocol_scope.go @@ -0,0 +1,105 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ProtocolScope) + +// Package mocknetwork is a generated GoMock package. +package mocknetwork + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + network "github.com/libp2p/go-libp2p/core/network" + protocol "github.com/libp2p/go-libp2p/core/protocol" +) + +// MockProtocolScope is a mock of ProtocolScope interface. +type MockProtocolScope struct { + ctrl *gomock.Controller + recorder *MockProtocolScopeMockRecorder +} + +// MockProtocolScopeMockRecorder is the mock recorder for MockProtocolScope. +type MockProtocolScopeMockRecorder struct { + mock *MockProtocolScope +} + +// NewMockProtocolScope creates a new mock instance. +func NewMockProtocolScope(ctrl *gomock.Controller) *MockProtocolScope { + mock := &MockProtocolScope{ctrl: ctrl} + mock.recorder = &MockProtocolScopeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockProtocolScope) EXPECT() *MockProtocolScopeMockRecorder { + return m.recorder +} + +// BeginSpan mocks base method. +func (m *MockProtocolScope) BeginSpan() (network.ResourceScopeSpan, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeginSpan") + ret0, _ := ret[0].(network.ResourceScopeSpan) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeginSpan indicates an expected call of BeginSpan. +func (mr *MockProtocolScopeMockRecorder) BeginSpan() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginSpan", reflect.TypeOf((*MockProtocolScope)(nil).BeginSpan)) +} + +// Protocol mocks base method. +func (m *MockProtocolScope) Protocol() protocol.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Protocol") + ret0, _ := ret[0].(protocol.ID) + return ret0 +} + +// Protocol indicates an expected call of Protocol. +func (mr *MockProtocolScopeMockRecorder) Protocol() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Protocol", reflect.TypeOf((*MockProtocolScope)(nil).Protocol)) +} + +// ReleaseMemory mocks base method. +func (m *MockProtocolScope) ReleaseMemory(arg0 int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReleaseMemory", arg0) +} + +// ReleaseMemory indicates an expected call of ReleaseMemory. +func (mr *MockProtocolScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockProtocolScope)(nil).ReleaseMemory), arg0) +} + +// ReserveMemory mocks base method. +func (m *MockProtocolScope) ReserveMemory(arg0 int, arg1 byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReserveMemory", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ReserveMemory indicates an expected call of ReserveMemory. +func (mr *MockProtocolScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockProtocolScope)(nil).ReserveMemory), arg0, arg1) +} + +// Stat mocks base method. +func (m *MockProtocolScope) Stat() network.ScopeStat { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stat") + ret0, _ := ret[0].(network.ScopeStat) + return ret0 +} + +// Stat indicates an expected call of Stat. +func (mr *MockProtocolScopeMockRecorder) Stat() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockProtocolScope)(nil).Stat)) +} diff --git a/core/network/mocks/mock_resource_manager.go b/core/network/mocks/mock_resource_manager.go new file mode 100644 index 0000000000..dbf6219c38 --- /dev/null +++ b/core/network/mocks/mock_resource_manager.go @@ -0,0 +1,152 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ResourceManager) + +// Package mocknetwork is a generated GoMock package. +package mocknetwork + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + network "github.com/libp2p/go-libp2p/core/network" + peer "github.com/libp2p/go-libp2p/core/peer" + protocol "github.com/libp2p/go-libp2p/core/protocol" + multiaddr "github.com/multiformats/go-multiaddr" +) + +// MockResourceManager is a mock of ResourceManager interface. +type MockResourceManager struct { + ctrl *gomock.Controller + recorder *MockResourceManagerMockRecorder +} + +// MockResourceManagerMockRecorder is the mock recorder for MockResourceManager. +type MockResourceManagerMockRecorder struct { + mock *MockResourceManager +} + +// NewMockResourceManager creates a new mock instance. +func NewMockResourceManager(ctrl *gomock.Controller) *MockResourceManager { + mock := &MockResourceManager{ctrl: ctrl} + mock.recorder = &MockResourceManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockResourceManager) EXPECT() *MockResourceManagerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockResourceManager) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockResourceManagerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockResourceManager)(nil).Close)) +} + +// OpenConnection mocks base method. +func (m *MockResourceManager) OpenConnection(arg0 network.Direction, arg1 bool, arg2 multiaddr.Multiaddr) (network.ConnManagementScope, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenConnection", arg0, arg1, arg2) + ret0, _ := ret[0].(network.ConnManagementScope) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenConnection indicates an expected call of OpenConnection. +func (mr *MockResourceManagerMockRecorder) OpenConnection(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenConnection", reflect.TypeOf((*MockResourceManager)(nil).OpenConnection), arg0, arg1, arg2) +} + +// OpenStream mocks base method. +func (m *MockResourceManager) OpenStream(arg0 peer.ID, arg1 network.Direction) (network.StreamManagementScope, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OpenStream", arg0, arg1) + ret0, _ := ret[0].(network.StreamManagementScope) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OpenStream indicates an expected call of OpenStream. +func (mr *MockResourceManagerMockRecorder) OpenStream(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockResourceManager)(nil).OpenStream), arg0, arg1) +} + +// ViewPeer mocks base method. +func (m *MockResourceManager) ViewPeer(arg0 peer.ID, arg1 func(network.PeerScope) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewPeer", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ViewPeer indicates an expected call of ViewPeer. +func (mr *MockResourceManagerMockRecorder) ViewPeer(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewPeer", reflect.TypeOf((*MockResourceManager)(nil).ViewPeer), arg0, arg1) +} + +// ViewProtocol mocks base method. +func (m *MockResourceManager) ViewProtocol(arg0 protocol.ID, arg1 func(network.ProtocolScope) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewProtocol", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ViewProtocol indicates an expected call of ViewProtocol. +func (mr *MockResourceManagerMockRecorder) ViewProtocol(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewProtocol", reflect.TypeOf((*MockResourceManager)(nil).ViewProtocol), arg0, arg1) +} + +// ViewService mocks base method. +func (m *MockResourceManager) ViewService(arg0 string, arg1 func(network.ServiceScope) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewService", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ViewService indicates an expected call of ViewService. +func (mr *MockResourceManagerMockRecorder) ViewService(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewService", reflect.TypeOf((*MockResourceManager)(nil).ViewService), arg0, arg1) +} + +// ViewSystem mocks base method. +func (m *MockResourceManager) ViewSystem(arg0 func(network.ResourceScope) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewSystem", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ViewSystem indicates an expected call of ViewSystem. +func (mr *MockResourceManagerMockRecorder) ViewSystem(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewSystem", reflect.TypeOf((*MockResourceManager)(nil).ViewSystem), arg0) +} + +// ViewTransient mocks base method. +func (m *MockResourceManager) ViewTransient(arg0 func(network.ResourceScope) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ViewTransient", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ViewTransient indicates an expected call of ViewTransient. +func (mr *MockResourceManagerMockRecorder) ViewTransient(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewTransient", reflect.TypeOf((*MockResourceManager)(nil).ViewTransient), arg0) +} diff --git a/core/network/mocks/mock_stream_management_scope.go b/core/network/mocks/mock_stream_management_scope.go new file mode 100644 index 0000000000..7dace90959 --- /dev/null +++ b/core/network/mocks/mock_stream_management_scope.go @@ -0,0 +1,173 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/libp2p/go-libp2p/core/network (interfaces: StreamManagementScope) + +// Package mocknetwork is a generated GoMock package. +package mocknetwork + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + network "github.com/libp2p/go-libp2p/core/network" + protocol "github.com/libp2p/go-libp2p/core/protocol" +) + +// MockStreamManagementScope is a mock of StreamManagementScope interface. +type MockStreamManagementScope struct { + ctrl *gomock.Controller + recorder *MockStreamManagementScopeMockRecorder +} + +// MockStreamManagementScopeMockRecorder is the mock recorder for MockStreamManagementScope. +type MockStreamManagementScopeMockRecorder struct { + mock *MockStreamManagementScope +} + +// NewMockStreamManagementScope creates a new mock instance. +func NewMockStreamManagementScope(ctrl *gomock.Controller) *MockStreamManagementScope { + mock := &MockStreamManagementScope{ctrl: ctrl} + mock.recorder = &MockStreamManagementScopeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStreamManagementScope) EXPECT() *MockStreamManagementScopeMockRecorder { + return m.recorder +} + +// BeginSpan mocks base method. +func (m *MockStreamManagementScope) BeginSpan() (network.ResourceScopeSpan, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeginSpan") + ret0, _ := ret[0].(network.ResourceScopeSpan) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BeginSpan indicates an expected call of BeginSpan. +func (mr *MockStreamManagementScopeMockRecorder) BeginSpan() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginSpan", reflect.TypeOf((*MockStreamManagementScope)(nil).BeginSpan)) +} + +// Done mocks base method. +func (m *MockStreamManagementScope) Done() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Done") +} + +// Done indicates an expected call of Done. +func (mr *MockStreamManagementScopeMockRecorder) Done() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Done", reflect.TypeOf((*MockStreamManagementScope)(nil).Done)) +} + +// PeerScope mocks base method. +func (m *MockStreamManagementScope) PeerScope() network.PeerScope { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PeerScope") + ret0, _ := ret[0].(network.PeerScope) + return ret0 +} + +// PeerScope indicates an expected call of PeerScope. +func (mr *MockStreamManagementScopeMockRecorder) PeerScope() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerScope", reflect.TypeOf((*MockStreamManagementScope)(nil).PeerScope)) +} + +// ProtocolScope mocks base method. +func (m *MockStreamManagementScope) ProtocolScope() network.ProtocolScope { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ProtocolScope") + ret0, _ := ret[0].(network.ProtocolScope) + return ret0 +} + +// ProtocolScope indicates an expected call of ProtocolScope. +func (mr *MockStreamManagementScopeMockRecorder) ProtocolScope() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProtocolScope", reflect.TypeOf((*MockStreamManagementScope)(nil).ProtocolScope)) +} + +// ReleaseMemory mocks base method. +func (m *MockStreamManagementScope) ReleaseMemory(arg0 int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReleaseMemory", arg0) +} + +// ReleaseMemory indicates an expected call of ReleaseMemory. +func (mr *MockStreamManagementScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockStreamManagementScope)(nil).ReleaseMemory), arg0) +} + +// ReserveMemory mocks base method. +func (m *MockStreamManagementScope) ReserveMemory(arg0 int, arg1 byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReserveMemory", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ReserveMemory indicates an expected call of ReserveMemory. +func (mr *MockStreamManagementScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockStreamManagementScope)(nil).ReserveMemory), arg0, arg1) +} + +// ServiceScope mocks base method. +func (m *MockStreamManagementScope) ServiceScope() network.ServiceScope { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceScope") + ret0, _ := ret[0].(network.ServiceScope) + return ret0 +} + +// ServiceScope indicates an expected call of ServiceScope. +func (mr *MockStreamManagementScopeMockRecorder) ServiceScope() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceScope", reflect.TypeOf((*MockStreamManagementScope)(nil).ServiceScope)) +} + +// SetProtocol mocks base method. +func (m *MockStreamManagementScope) SetProtocol(arg0 protocol.ID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetProtocol", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetProtocol indicates an expected call of SetProtocol. +func (mr *MockStreamManagementScopeMockRecorder) SetProtocol(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProtocol", reflect.TypeOf((*MockStreamManagementScope)(nil).SetProtocol), arg0) +} + +// SetService mocks base method. +func (m *MockStreamManagementScope) SetService(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetService", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetService indicates an expected call of SetService. +func (mr *MockStreamManagementScopeMockRecorder) SetService(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetService", reflect.TypeOf((*MockStreamManagementScope)(nil).SetService), arg0) +} + +// Stat mocks base method. +func (m *MockStreamManagementScope) Stat() network.ScopeStat { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stat") + ret0, _ := ret[0].(network.ScopeStat) + return ret0 +} + +// Stat indicates an expected call of Stat. +func (mr *MockStreamManagementScopeMockRecorder) Stat() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockStreamManagementScope)(nil).Stat)) +} diff --git a/core/network/mocks/network.go b/core/network/mocks/network.go new file mode 100644 index 0000000000..975ba4a1f8 --- /dev/null +++ b/core/network/mocks/network.go @@ -0,0 +1,7 @@ +package mocknetwork + +//go:generate sh -c "mockgen -package mocknetwork -destination mock_resource_manager.go github.com/libp2p/go-libp2p/core/network ResourceManager" +//go:generate sh -c "mockgen -package mocknetwork -destination mock_conn_management_scope.go github.com/libp2p/go-libp2p/core/network ConnManagementScope" +//go:generate sh -c "mockgen -package mocknetwork -destination mock_stream_management_scope.go github.com/libp2p/go-libp2p/core/network StreamManagementScope" +//go:generate sh -c "mockgen -package mocknetwork -destination mock_peer_scope.go github.com/libp2p/go-libp2p/core/network PeerScope" +//go:generate sh -c "mockgen -package mocknetwork -destination mock_protocol_scope.go github.com/libp2p/go-libp2p/core/network ProtocolScope" diff --git a/core/network/mux.go b/core/network/mux.go new file mode 100644 index 0000000000..d12e2ea34b --- /dev/null +++ b/core/network/mux.go @@ -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) +} diff --git a/core/network/nattype.go b/core/network/nattype.go new file mode 100644 index 0000000000..bc95d68703 --- /dev/null +++ b/core/network/nattype.go @@ -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" + } +} diff --git a/core/network/network.go b/core/network/network.go new file mode 100644 index 0000000000..bf96697d55 --- /dev/null +++ b/core/network/network.go @@ -0,0 +1,186 @@ +// 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 +) + +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 threadsafe. + 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 Netowrk + Conns() []Conn + + // ConnsToPeer returns the connections in this Netowrk for given peer. + ConnsToPeer(p peer.ID) []Conn + + // Notify/StopNotify register and unregister a notifiee for signals + Notify(Notifiee) + StopNotify(Notifiee) +} diff --git a/core/network/notifee.go b/core/network/notifee.go new file mode 100644 index 0000000000..bb2f383387 --- /dev/null +++ b/core/network/notifee.go @@ -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) {} diff --git a/core/network/notifee_test.go b/core/network/notifee_test.go new file mode 100644 index 0000000000..12090d1f19 --- /dev/null +++ b/core/network/notifee_test.go @@ -0,0 +1,87 @@ +package network + +import ( + "testing" + + ma "github.com/multiformats/go-multiaddr" +) + +func TestListen(T *testing.T) { + var notifee NotifyBundle + addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + if err != nil { + T.Fatal("unexpected multiaddr error") + } + notifee.Listen(nil, addr) + + called := false + notifee.ListenF = func(Network, ma.Multiaddr) { + called = true + } + if called { + T.Fatal("called should be false") + } + + notifee.Listen(nil, addr) + if !called { + T.Fatal("Listen should have been called") + } +} + +func TestListenClose(T *testing.T) { + var notifee NotifyBundle + addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + if err != nil { + T.Fatal("unexpected multiaddr error") + } + notifee.ListenClose(nil, addr) + + called := false + notifee.ListenCloseF = func(Network, ma.Multiaddr) { + called = true + } + if called { + T.Fatal("called should be false") + } + + notifee.ListenClose(nil, addr) + if !called { + T.Fatal("ListenClose should have been called") + } +} + +func TestConnected(T *testing.T) { + var notifee NotifyBundle + notifee.Connected(nil, nil) + + called := false + notifee.ConnectedF = func(Network, Conn) { + called = true + } + if called { + T.Fatal("called should be false") + } + + notifee.Connected(nil, nil) + if !called { + T.Fatal("Connected should have been called") + } +} + +func TestDisconnected(T *testing.T) { + var notifee NotifyBundle + notifee.Disconnected(nil, nil) + + called := false + notifee.DisconnectedF = func(Network, Conn) { + called = true + } + if called { + T.Fatal("called should be false") + } + + notifee.Disconnected(nil, nil) + if !called { + T.Fatal("Disconnected should have been called") + } +} diff --git a/core/network/rcmgr.go b/core/network/rcmgr.go new file mode 100644 index 0000000000..b609257566 --- /dev/null +++ b/core/network/rcmgr.go @@ -0,0 +1,330 @@ +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 steam 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 prioirity 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. + // + // The 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 asociated 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 +var NullResourceManager ResourceManager = &nullResourceManager{} + +type nullResourceManager struct{} +type nullScope 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 +var NullScope = &nullScope{} + +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 } diff --git a/core/network/stream.go b/core/network/stream.go new file mode 100644 index 0000000000..62e230034c --- /dev/null +++ b/core/network/stream.go @@ -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 +} diff --git a/core/peer/addrinfo.go b/core/peer/addrinfo.go new file mode 100644 index 0000000000..19b07a4b7f --- /dev/null +++ b/core/peer/addrinfo.go @@ -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 a 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) { + var addrs []ma.Multiaddr + p2ppart, err := ma.NewComponent("p2p", Encode(pi.ID)) + if err != nil { + return nil, err + } + if len(pi.Addrs) == 0 { + return []ma.Multiaddr{p2ppart}, nil + } + 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 +} diff --git a/core/peer/addrinfo_serde.go b/core/peer/addrinfo_serde.go new file mode 100644 index 0000000000..a848ea6c66 --- /dev/null +++ b/core/peer/addrinfo_serde.go @@ -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 +} diff --git a/core/peer/addrinfo_test.go b/core/peer/addrinfo_test.go new file mode 100644 index 0000000000..9f18a8b603 --- /dev/null +++ b/core/peer/addrinfo_test.go @@ -0,0 +1,152 @@ +package peer_test + +import ( + "testing" + + ma "github.com/multiformats/go-multiaddr" + + . "github.com/libp2p/go-libp2p/core/peer" +) + +var ( + testID ID + maddrFull, maddrTpt, maddrPeer ma.Multiaddr +) + +func init() { + var err error + testID, err = Decode("QmS3zcG7LhYZYSJMhyRZvTddvbNUqtt8BJpaSs6mi1K5Va") + if err != nil { + panic(err) + } + maddrPeer = ma.StringCast("/p2p/" + Encode(testID)) + maddrTpt = ma.StringCast("/ip4/127.0.0.1/tcp/1234") + maddrFull = maddrTpt.Encapsulate(maddrPeer) +} + +func TestSplitAddr(t *testing.T) { + tpt, id := SplitAddr(maddrFull) + if !tpt.Equal(maddrTpt) { + t.Fatal("expected transport") + } + if id != testID { + t.Fatalf("%s != %s", id, testID) + } + + tpt, id = SplitAddr(maddrPeer) + if tpt != nil { + t.Fatal("expected no transport") + } + if id != testID { + t.Fatalf("%s != %s", id, testID) + } + + tpt, id = SplitAddr(maddrTpt) + if !tpt.Equal(maddrTpt) { + t.Fatal("expected a transport") + } + if id != "" { + t.Fatal("expected no peer ID") + } +} + +func TestAddrInfoFromP2pAddr(t *testing.T) { + ai, err := AddrInfoFromP2pAddr(maddrFull) + if err != nil { + t.Fatal(err) + } + if len(ai.Addrs) != 1 || !ai.Addrs[0].Equal(maddrTpt) { + t.Fatal("expected transport") + } + if ai.ID != testID { + t.Fatalf("%s != %s", ai.ID, testID) + } + + ai, err = AddrInfoFromP2pAddr(maddrPeer) + if err != nil { + t.Fatal(err) + } + if len(ai.Addrs) != 0 { + t.Fatal("expected transport") + } + if ai.ID != testID { + t.Fatalf("%s != %s", ai.ID, testID) + } + + _, err = AddrInfoFromP2pAddr(maddrTpt) + if err != ErrInvalidAddr { + t.Fatalf("wrong error: %s", err) + } +} + +func TestAddrInfosFromP2pAddrs(t *testing.T) { + infos, err := AddrInfosFromP2pAddrs() + if err != nil { + t.Fatal(err) + } + if len(infos) != 0 { + t.Fatal("expected no addrs") + } + if _, err = AddrInfosFromP2pAddrs(nil); err == nil { + t.Fatal("expected nil multiaddr to fail") + } + + addrs := []ma.Multiaddr{ + ma.StringCast("/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64"), + ma.StringCast("/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64"), + + ma.StringCast("/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd"), + ma.StringCast("/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd"), + + ma.StringCast("/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM"), + } + expected := map[string][]ma.Multiaddr{ + "QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64": { + ma.StringCast("/ip4/128.199.219.111/tcp/4001"), + ma.StringCast("/ip4/104.236.76.40/tcp/4001"), + }, + "QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd": { + ma.StringCast("/ip4/178.62.158.247/tcp/4001"), + }, + "QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM": nil, + } + infos, err = AddrInfosFromP2pAddrs(addrs...) + if err != nil { + t.Fatal(err) + } + for _, info := range infos { + exaddrs, ok := expected[info.ID.Pretty()] + if !ok { + t.Fatalf("didn't expect peer %s", info.ID) + } + if len(info.Addrs) != len(exaddrs) { + t.Fatalf("got %d addrs, expected %d", len(info.Addrs), len(exaddrs)) + } + // AddrInfosFromP2pAddrs preserves order. I'd like to keep this + // guarantee for now. + for i, addr := range info.Addrs { + if !exaddrs[i].Equal(addr) { + t.Fatalf("expected %s, got %s", exaddrs[i], addr) + } + } + delete(expected, info.ID.Pretty()) + } +} + +func TestAddrInfoJSON(t *testing.T) { + ai := AddrInfo{ID: testID, Addrs: []ma.Multiaddr{maddrFull}} + out, err := ai.MarshalJSON() + if err != nil { + t.Fatal(err) + } + var addrInfo AddrInfo + if err := addrInfo.UnmarshalJSON(out); err != nil { + t.Fatal(err) + } + if addrInfo.ID != testID { + t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty()) + } + if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) { + t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs) + } +} diff --git a/core/peer/pb/Makefile b/core/peer/pb/Makefile new file mode 100644 index 0000000000..7cf8222f89 --- /dev/null +++ b/core/peer/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(PWD):$(PWD)/../.. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/core/peer/pb/peer_record.pb.go b/core/peer/pb/peer_record.pb.go new file mode 100644 index 0000000000..36040c3c2c --- /dev/null +++ b/core/peer/pb/peer_record.pb.go @@ -0,0 +1,607 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: peer_record.proto + +package peer_pb + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// 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 { + // 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 (m *PeerRecord) Reset() { *m = PeerRecord{} } +func (m *PeerRecord) String() string { return proto.CompactTextString(m) } +func (*PeerRecord) ProtoMessage() {} +func (*PeerRecord) Descriptor() ([]byte, []int) { + return fileDescriptor_dc0d8059ab0ad14d, []int{0} +} +func (m *PeerRecord) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PeerRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PeerRecord.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PeerRecord) XXX_Merge(src proto.Message) { + xxx_messageInfo_PeerRecord.Merge(m, src) +} +func (m *PeerRecord) XXX_Size() int { + return m.Size() +} +func (m *PeerRecord) XXX_DiscardUnknown() { + xxx_messageInfo_PeerRecord.DiscardUnknown(m) +} + +var xxx_messageInfo_PeerRecord proto.InternalMessageInfo + +func (m *PeerRecord) GetPeerId() []byte { + if m != nil { + return m.PeerId + } + return nil +} + +func (m *PeerRecord) GetSeq() uint64 { + if m != nil { + return m.Seq + } + return 0 +} + +func (m *PeerRecord) GetAddresses() []*PeerRecord_AddressInfo { + if m != nil { + return m.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 { + Multiaddr []byte `protobuf:"bytes,1,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"` +} + +func (m *PeerRecord_AddressInfo) Reset() { *m = PeerRecord_AddressInfo{} } +func (m *PeerRecord_AddressInfo) String() string { return proto.CompactTextString(m) } +func (*PeerRecord_AddressInfo) ProtoMessage() {} +func (*PeerRecord_AddressInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_dc0d8059ab0ad14d, []int{0, 0} +} +func (m *PeerRecord_AddressInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PeerRecord_AddressInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PeerRecord_AddressInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PeerRecord_AddressInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_PeerRecord_AddressInfo.Merge(m, src) +} +func (m *PeerRecord_AddressInfo) XXX_Size() int { + return m.Size() +} +func (m *PeerRecord_AddressInfo) XXX_DiscardUnknown() { + xxx_messageInfo_PeerRecord_AddressInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_PeerRecord_AddressInfo proto.InternalMessageInfo + +func (m *PeerRecord_AddressInfo) GetMultiaddr() []byte { + if m != nil { + return m.Multiaddr + } + return nil +} + +func init() { + proto.RegisterType((*PeerRecord)(nil), "peer.pb.PeerRecord") + proto.RegisterType((*PeerRecord_AddressInfo)(nil), "peer.pb.PeerRecord.AddressInfo") +} + +func init() { proto.RegisterFile("peer_record.proto", fileDescriptor_dc0d8059ab0ad14d) } + +var fileDescriptor_dc0d8059ab0ad14d = []byte{ + // 189 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x48, 0x4d, 0x2d, + 0x8a, 0x2f, 0x4a, 0x4d, 0xce, 0x2f, 0x4a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x07, + 0x09, 0xe9, 0x15, 0x24, 0x29, 0x2d, 0x66, 0xe4, 0xe2, 0x0a, 0x48, 0x4d, 0x2d, 0x0a, 0x02, 0xcb, + 0x0a, 0x89, 0x73, 0x81, 0x65, 0xe2, 0x33, 0x53, 0x24, 0x18, 0x15, 0x18, 0x35, 0x78, 0x82, 0xd8, + 0x40, 0x5c, 0xcf, 0x14, 0x21, 0x01, 0x2e, 0xe6, 0xe2, 0xd4, 0x42, 0x09, 0x26, 0x05, 0x46, 0x0d, + 0x96, 0x20, 0x10, 0x53, 0xc8, 0x96, 0x8b, 0x33, 0x31, 0x25, 0xa5, 0x28, 0xb5, 0xb8, 0x38, 0xb5, + 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x5e, 0x0f, 0x6a, 0xac, 0x1e, 0xc2, 0x48, 0x3d, + 0x47, 0x88, 0x22, 0xcf, 0xbc, 0xb4, 0xfc, 0x20, 0x84, 0x0e, 0x29, 0x6d, 0x2e, 0x6e, 0x24, 0x19, + 0x21, 0x19, 0x2e, 0xce, 0xdc, 0xd2, 0x9c, 0x92, 0x4c, 0x90, 0x02, 0xa8, 0xd5, 0x08, 0x01, 0x27, + 0x89, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, + 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xfb, 0xc7, 0x18, + 0x10, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x99, 0x56, 0x19, 0xe4, 0x00, 0x00, 0x00, +} + +func (m *PeerRecord) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PeerRecord) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PeerRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Addresses) > 0 { + for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Addresses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPeerRecord(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Seq != 0 { + i = encodeVarintPeerRecord(dAtA, i, uint64(m.Seq)) + i-- + dAtA[i] = 0x10 + } + if len(m.PeerId) > 0 { + i -= len(m.PeerId) + copy(dAtA[i:], m.PeerId) + i = encodeVarintPeerRecord(dAtA, i, uint64(len(m.PeerId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PeerRecord_AddressInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PeerRecord_AddressInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PeerRecord_AddressInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Multiaddr) > 0 { + i -= len(m.Multiaddr) + copy(dAtA[i:], m.Multiaddr) + i = encodeVarintPeerRecord(dAtA, i, uint64(len(m.Multiaddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintPeerRecord(dAtA []byte, offset int, v uint64) int { + offset -= sovPeerRecord(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PeerRecord) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PeerId) + if l > 0 { + n += 1 + l + sovPeerRecord(uint64(l)) + } + if m.Seq != 0 { + n += 1 + sovPeerRecord(uint64(m.Seq)) + } + if len(m.Addresses) > 0 { + for _, e := range m.Addresses { + l = e.Size() + n += 1 + l + sovPeerRecord(uint64(l)) + } + } + return n +} + +func (m *PeerRecord_AddressInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Multiaddr) + if l > 0 { + n += 1 + l + sovPeerRecord(uint64(l)) + } + return n +} + +func sovPeerRecord(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPeerRecord(x uint64) (n int) { + return sovPeerRecord(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PeerRecord) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PeerRecord: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PeerRecord: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PeerId", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPeerRecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPeerRecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PeerId = append(m.PeerId[:0], dAtA[iNdEx:postIndex]...) + if m.PeerId == nil { + m.PeerId = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType) + } + m.Seq = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Seq |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPeerRecord + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPeerRecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addresses = append(m.Addresses, &PeerRecord_AddressInfo{}) + if err := m.Addresses[len(m.Addresses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPeerRecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPeerRecord + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPeerRecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PeerRecord_AddressInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddressInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddressInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Multiaddr", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPeerRecord + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPeerRecord + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Multiaddr = append(m.Multiaddr[:0], dAtA[iNdEx:postIndex]...) + if m.Multiaddr == nil { + m.Multiaddr = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPeerRecord(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPeerRecord + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPeerRecord + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPeerRecord(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPeerRecord + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthPeerRecord + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPeerRecord + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPeerRecord + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPeerRecord = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPeerRecord = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPeerRecord = fmt.Errorf("proto: unexpected end of group") +) diff --git a/core/peer/pb/peer_record.proto b/core/peer/pb/peer_record.proto new file mode 100644 index 0000000000..55dd43a2b8 --- /dev/null +++ b/core/peer/pb/peer_record.proto @@ -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; +} diff --git a/core/peer/peer.go b/core/peer/peer.go new file mode 100644 index 0000000000..7bd4f8d245 --- /dev/null +++ b/core/peer/peer.go @@ -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("", pid) + } + return fmt.Sprintf("", 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, ", ") +} diff --git a/core/peer/peer_serde.go b/core/peer/peer_serde.go new file mode 100644 index 0000000000..e3ac3f2c98 --- /dev/null +++ b/core/peer/peer_serde.go @@ -0,0 +1,75 @@ +// 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) +} + +// Size implements Gogo's proto.Sizer, but we omit the compile-time assertion to avoid introducing a hard +// dependency on gogo. +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 +} diff --git a/core/peer/peer_serde_test.go b/core/peer/peer_serde_test.go new file mode 100644 index 0000000000..c503d66b9e --- /dev/null +++ b/core/peer/peer_serde_test.go @@ -0,0 +1,83 @@ +package peer_test + +import ( + "testing" + + "github.com/libp2p/go-libp2p/core/peer" + . "github.com/libp2p/go-libp2p/core/test" +) + +func TestPeerSerdePB(t *testing.T) { + id, err := RandPeerID() + if err != nil { + t.Fatal(err) + } + b, err := id.Marshal() + if err != nil { + t.Fatal(err) + } + + var id2 peer.ID + if err = id2.Unmarshal(b); err != nil { + t.Fatal(err) + } + if id != id2 { + t.Error("expected equal ids in circular serde test") + } +} + +func TestPeerSerdeJSON(t *testing.T) { + id, err := RandPeerID() + if err != nil { + t.Fatal(err) + } + b, err := id.MarshalJSON() + if err != nil { + t.Fatal(err) + } + var id2 peer.ID + if err = id2.UnmarshalJSON(b); err != nil { + t.Fatal(err) + } + if id != id2 { + t.Error("expected equal ids in circular serde test") + } +} + +func TestBinaryMarshaler(t *testing.T) { + id, err := RandPeerID() + if err != nil { + t.Fatal(err) + } + b, err := id.MarshalBinary() + if err != nil { + t.Fatal(err) + } + + var id2 peer.ID + if err = id2.UnmarshalBinary(b); err != nil { + t.Fatal(err) + } + if id != id2 { + t.Error("expected equal ids in circular serde test") + } +} + +func TestTextMarshaler(t *testing.T) { + id, err := RandPeerID() + if err != nil { + t.Fatal(err) + } + b, err := id.MarshalText() + if err != nil { + t.Fatal(err) + } + + var id2 peer.ID + if err = id2.UnmarshalText(b); err != nil { + t.Fatal(err) + } + if id != id2 { + t.Error("expected equal ids in circular serde test") + } +} diff --git a/core/peer/peer_test.go b/core/peer/peer_test.go new file mode 100644 index 0000000000..d7fa930bcb --- /dev/null +++ b/core/peer/peer_test.go @@ -0,0 +1,300 @@ +package peer_test + +import ( + "crypto/rand" + "encoding/base64" + "fmt" + "strings" + "testing" + + ic "github.com/libp2p/go-libp2p/core/crypto" + . "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/test" + + b58 "github.com/mr-tron/base58/base58" + mh "github.com/multiformats/go-multihash" +) + +var gen1 keyset // generated +var gen2 keyset // generated +var man keyset // manual + +func hash(b []byte) []byte { + h, _ := mh.Sum(b, mh.SHA2_256, -1) + return []byte(h) +} + +func init() { + if err := gen1.generate(); err != nil { + panic(err) + } + if err := gen2.generate(); err != nil { + panic(err) + } + + skManBytes = strings.Replace(skManBytes, "\n", "", -1) + if err := man.load(hpkpMan, skManBytes); err != nil { + panic(err) + } +} + +type keyset struct { + sk ic.PrivKey + pk ic.PubKey + hpk string + hpkp string +} + +func (ks *keyset) generate() error { + var err error + ks.sk, ks.pk, err = test.RandTestKeyPair(ic.RSA, 2048) + if err != nil { + return err + } + + bpk, err := ic.MarshalPublicKey(ks.pk) + if err != nil { + return err + } + + ks.hpk = string(hash(bpk)) + ks.hpkp = b58.Encode([]byte(ks.hpk)) + return nil +} + +func (ks *keyset) load(hpkp, skBytesStr string) error { + skBytes, err := base64.StdEncoding.DecodeString(skBytesStr) + if err != nil { + return err + } + + ks.sk, err = ic.UnmarshalPrivateKey(skBytes) + if err != nil { + return err + } + + ks.pk = ks.sk.GetPublic() + bpk, err := ic.MarshalPublicKey(ks.pk) + if err != nil { + return err + } + + ks.hpk = string(hash(bpk)) + ks.hpkp = b58.Encode([]byte(ks.hpk)) + if ks.hpkp != hpkp { + return fmt.Errorf("hpkp doesn't match key. %s", hpkp) + } + return nil +} + +func TestIDMatchesPublicKey(t *testing.T) { + test := func(ks keyset) { + p1, err := Decode(ks.hpkp) + if err != nil { + t.Fatal(err) + } + + if ks.hpk != string(p1) { + t.Error("p1 and hpk differ") + } + + if !p1.MatchesPublicKey(ks.pk) { + t.Fatal("p1 does not match pk") + } + + p2, err := IDFromPublicKey(ks.pk) + if err != nil { + t.Fatal(err) + } + + if p1 != p2 { + t.Error("p1 and p2 differ", p1.String(), p2.String()) + } + + if p2.String() != ks.hpkp { + t.Error("hpkp and p2.String differ", ks.hpkp, p2.String()) + } + } + + test(gen1) + test(gen2) + test(man) +} + +func TestIDMatchesPrivateKey(t *testing.T) { + + test := func(ks keyset) { + p1, err := Decode(ks.hpkp) + if err != nil { + t.Fatal(err) + } + + if ks.hpk != string(p1) { + t.Error("p1 and hpk differ") + } + + if !p1.MatchesPrivateKey(ks.sk) { + t.Fatal("p1 does not match sk") + } + + p2, err := IDFromPrivateKey(ks.sk) + if err != nil { + t.Fatal(err) + } + + if p1 != p2 { + t.Error("p1 and p2 differ", p1.String(), p2.String()) + } + } + + test(gen1) + test(gen2) + test(man) +} + +func TestIDEncoding(t *testing.T) { + test := func(ks keyset) { + p1, err := Decode(ks.hpkp) + if err != nil { + t.Fatal(err) + } + + if ks.hpk != string(p1) { + t.Error("p1 and hpk differ") + } + + c := ToCid(p1) + p2, err := FromCid(c) + if err != nil || p1 != p2 { + t.Fatal("failed to round-trip through CID:", err) + } + p3, err := Decode(c.String()) + if err != nil { + t.Fatal(err) + } + if p3 != p1 { + t.Fatal("failed to round trip through CID string") + } + + if ks.hpkp != p1.String() { + t.Fatal("should always encode peer IDs as base58 by default") + } + } + + test(gen1) + test(gen2) + test(man) + + exampleCid := "bafkreifoybygix7fh3r3g5rqle3wcnhqldgdg4shzf4k3ulyw3gn7mabt4" + _, err := Decode(exampleCid) + if err == nil { + t.Fatal("should refuse to decode a non-peer ID CID") + } + + c := ToCid("") + if c.Defined() { + t.Fatal("cid of empty peer ID should have been undefined") + } +} + +func TestPublicKeyExtraction(t *testing.T) { + t.Skip("disabled until libp2p/go-libp2p-crypto#51 is fixed") + // Happy path + _, originalPub, err := ic.GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + + id, err := IDFromPublicKey(originalPub) + if err != nil { + t.Fatal(err) + } + + extractedPub, err := id.ExtractPublicKey() + if err != nil { + t.Fatal(err) + } + if extractedPub == nil { + t.Fatal("failed to extract public key") + } + if !originalPub.Equals(extractedPub) { + t.Fatal("extracted public key doesn't match") + } + + // Test invalid multihash (invariant of the type of public key) + pk, err := ID("").ExtractPublicKey() + if err == nil { + t.Fatal("expected an error") + } + if pk != nil { + t.Fatal("expected a nil public key") + } + + // Shouldn't work for, e.g. RSA keys (too large) + + _, rsaPub, err := ic.GenerateKeyPair(ic.RSA, 2048) + if err != nil { + t.Fatal(err) + } + rsaId, err := IDFromPublicKey(rsaPub) + if err != nil { + t.Fatal(err) + } + extractedRsaPub, err := rsaId.ExtractPublicKey() + if err != ErrNoPublicKey { + t.Fatal(err) + } + if extractedRsaPub != nil { + t.Fatal("expected to fail to extract public key from rsa ID") + } +} + +func TestValidate(t *testing.T) { + // Empty peer ID invalidates + err := ID("").Validate() + if err == nil { + t.Error("expected error") + } else if err != ErrEmptyPeerID { + t.Error("expected error message: " + ErrEmptyPeerID.Error()) + } + + // Non-empty peer ID validates + p, err := test.RandPeerID() + if err != nil { + t.Fatal(err) + } + + err = p.Validate() + if err != nil { + t.Error("expected nil, but found " + err.Error()) + } +} + +var hpkpMan = `QmcJeseojbPW9hSejUM1sQ1a2QmbrryPK4Z8pWbRUPaYEn` +var skManBytes = ` +CAASqAkwggSkAgEAAoIBAQC3hjPtPli71gFNzGJ6rUhYdb65BDwW7IrniEaZKi6z +tW4Iz0MouEJY8GPG1iQfqZKp5w9H2ENh4I1bk2dsezrJ7Nneg4Eqd78CmeHTAgaP +3PKsxohdMo/TOFNxwl8SkEF8FyVbio2TCoijYNHUuprZuq7MPEAJYr3Z1eEkM/xR +pMp3YI9S2SYsZQxbmmQ0/GfHOEvYajdow1qttreVTQkvmCppKtNLEU5InpX/W5fe +aQCj0pd7l74daZgM2WWz3juEUCVG7tdRUPg7ix1TYosbN96CKC3q2MJxe/wJ9gR5 +Jvjnaaaoon+mci5vrKzxdKBDmZ/ZbLiHDfVljMkbdOQLAgMBAAECggEAEULaF3JJ +vkD+lmamzIsHxuosKhKv5CgTWHuEyFsjUVu7IbD8zBOoidzyRX1WoHO+i6Rj14oL +rGUGZpqSm61rdhqE01zjBS+GE6SNjN8f5uANIxr5MGrVBDTEBGsXrhNLVXSH2vhJ +II9ZEqTEl5GFhvz7+9Ge5EMZQCfRqSoKjVMdrs+Rueuusr9p0wNg9PH1myA+cXGt +iNZA17Rj2IiWVZLDgYNo4DVQUt4mFb+wTJW4NSspGKaFebpn0hf4z21laoGoJqTC +cNETJw+QwQ0uDaRoYotTLT2/55e8XBFTdcTg5cmbZoKgMyGqZEHfRyD9reVDAZlM +EZwKtrm41kz94QKBgQDmPp5zVtFXQNONmje1NE0IjCaUKcqURXk4ZiILztfT9XLC +OXAUCs3TCq21jirCkZZ6gLfo12Wx0xJYmsKlaUOGNTa8FI5Xa7OyheYKixUvV6FW +J95P/sNuWscTjh7oZHgZk/L3yKrNzNBz7awComwV6qciXW7EP1uACHf5fS/RdQKB +gQDMDa38W9OeegRDrhCeYGsniJK7btOCzhNooruQKPPXxk+O4dyJm7VBbC/3Ch55 +a83W66T4k0Q7ysLVRT5Vqd5z3AM0sEM3ZoxUKCinG3NwPxVeXcoLasyEiq1vOFK6 +GqZKCMThCj7ZpbkWy0DPJagnYfZGC62lammuj+XQx7mvfwKBgQCTKhka/bXmgD/3 +9UeAIcLPIM2TzDZ4mQNHIjjGtVnMV8kXDaFung06xEuNjSYVoPq+qEFkqTCN/axv +R9P76BFJ2f93LehhRizggacsvAM5dFhh+i+lj+AYTBuMiz2EKpt9NcyJxhAuZKgk +QRi9wlU1mPtlArVG6HwylLcil3qV9QKBgQDJHtaU/KEY+2TGnIMuxxP2lEsjyLla +nOlOYc8C6Qpma8UwrHelfj5p7Eteb6/Xt6Tbp8kjZGuFj3T3plcpMdPbWEgkn3Kw +4TeBH0/qXUkrolHagBDLrglEvjbxf48ydV/fasM6l9GYzhofWFhZk+EoaArHwWz2 +tGrTrmsynBjt2wKBgErdYe+zZ2Wo+wXQGAoZi4pfcwiw4a97Kdh0dx+WZz7acHms +h+V20VRmEHm5h8WnJ/Wv5uK94t6NY17wzjQ7y2BN5mY5cA2cZAcpeqtv/N06tH4S +cn1UEuRB8VpwkjaPUNZhqtYK40qff2OTdJy8taFtQiN7fz9euWTC78zjph2s +` diff --git a/core/peer/record.go b/core/peer/record.go new file mode 100644 index 0000000000..9f8861af86 --- /dev/null +++ b/core/peer/record.go @@ -0,0 +1,251 @@ +package peer + +import ( + "fmt" + "sync" + "time" + + "github.com/libp2p/go-libp2p/core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/peer/pb" + "github.com/libp2p/go-libp2p/core/record" + + ma "github.com/multiformats/go-multiaddr" + + "github.com/gogo/protobuf/proto" +) + +var _ record.Record = (*PeerRecord)(nil) + +func init() { + record.RegisterType(&PeerRecord{}) +} + +// PeerRecordEnvelopeDomain is the domain string used for peer records contained in a Envelope. +const PeerRecordEnvelopeDomain = "libp2p-peer-record" + +// PeerRecordEnvelopePayloadType is the type hint used to identify peer records in a 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 a 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 { + var out []ma.Multiaddr + 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 { + var out []*pb.PeerRecord_AddressInfo + for _, addr := range addrs { + out = append(out, &pb.PeerRecord_AddressInfo{Multiaddr: addr.Bytes()}) + } + return out +} diff --git a/core/peer/record_test.go b/core/peer/record_test.go new file mode 100644 index 0000000000..4ac8ffba24 --- /dev/null +++ b/core/peer/record_test.go @@ -0,0 +1,67 @@ +package peer_test + +import ( + "bytes" + "testing" + + "github.com/libp2p/go-libp2p/core/crypto" + . "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" + "github.com/libp2p/go-libp2p/core/test" +) + +func TestPeerRecordConstants(t *testing.T) { + msgf := "Changing the %s may cause peer records to be incompatible with older versions. " + + "If you've already thought that through, please update this test so that it passes with the new values." + rec := PeerRecord{} + if rec.Domain() != "libp2p-peer-record" { + t.Errorf(msgf, "signing domain") + } + if !bytes.Equal(rec.Codec(), []byte{0x03, 0x01}) { + t.Errorf(msgf, "codec value") + } +} + +func TestSignedPeerRecordFromEnvelope(t *testing.T) { + priv, _, err := test.RandTestKeyPair(crypto.Ed25519, 256) + test.AssertNilError(t, err) + + addrs := test.GenerateTestAddrs(10) + id, err := IDFromPrivateKey(priv) + test.AssertNilError(t, err) + + rec := &PeerRecord{PeerID: id, Addrs: addrs, Seq: TimestampSeq()} + envelope, err := record.Seal(rec, priv) + test.AssertNilError(t, err) + + t.Run("is unaltered after round-trip serde", func(t *testing.T) { + envBytes, err := envelope.Marshal() + test.AssertNilError(t, err) + + env2, untypedRecord, err := record.ConsumeEnvelope(envBytes, PeerRecordEnvelopeDomain) + test.AssertNilError(t, err) + rec2, ok := untypedRecord.(*PeerRecord) + if !ok { + t.Error("unmarshaled record is not a *PeerRecord") + } + if !rec.Equal(rec2) { + t.Error("expected peer record to be unaltered after round-trip serde") + } + if !envelope.Equal(env2) { + t.Error("expected signed envelope to be unchanged after round-trip serde") + } + }) +} + +// This is pretty much guaranteed to pass on Linux no matter how we implement it, but Windows has +// low clock precision. This makes sure we never get a duplicate. +func TestTimestampSeq(t *testing.T) { + var last uint64 + for i := 0; i < 1000; i++ { + next := TimestampSeq() + if next <= last { + t.Errorf("non-increasing timestamp found: %d <= %d", next, last) + } + last = next + } +} diff --git a/core/peerstore/helpers.go b/core/peerstore/helpers.go new file mode 100644 index 0000000000..92e522d580 --- /dev/null +++ b/core/peerstore/helpers.go @@ -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 +} diff --git a/core/peerstore/peerstore.go b/core/peerstore/peerstore.go new file mode 100644 index 0000000000..213513bcda --- /dev/null +++ b/core/peerstore/peerstore.go @@ -0,0 +1,254 @@ +// 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/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 + + // ProviderAddrTTL is the TTL of an address we've received from a provider. + // This is also a temporary address, but lasts longer. After this expires, + // the records we return will require an extra lookup. + ProviderAddrTTL = time.Minute * 30 + + // 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 threadsafe 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 of 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 of 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 a 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) ([]string, error) + AddProtocols(peer.ID, ...string) error + SetProtocols(peer.ID, ...string) error + RemoveProtocols(peer.ID, ...string) 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, ...string) ([]string, 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 string and a nil error. + // If the returned error is not nil, the result is indeterminate. + FirstSupportedProtocol(peer.ID, ...string) (string, error) + + // RemovePeer removes all protocols associated with a peer. + RemovePeer(peer.ID) +} diff --git a/core/pnet/codec.go b/core/pnet/codec.go new file mode 100644 index 0000000000..e741aba995 --- /dev/null +++ b/core/pnet/codec.go @@ -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", pathPSKv1, 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 +} diff --git a/core/pnet/codec_test.go b/core/pnet/codec_test.go new file mode 100644 index 0000000000..b4b9272d09 --- /dev/null +++ b/core/pnet/codec_test.go @@ -0,0 +1,122 @@ +package pnet + +import ( + "bytes" + "encoding/base64" + "testing" +) + +func bufWithBase(base string, windows bool) *bytes.Buffer { + b := &bytes.Buffer{} + b.Write(pathPSKv1) + if windows { + b.WriteString("\r") + } + b.WriteString("\n") + b.WriteString(base) + if windows { + b.WriteString("\r") + } + b.WriteString("\n") + return b +} + +func TestDecodeHex(t *testing.T) { + testDecodeHex(t, true) + testDecodeHex(t, false) +} + +func TestDecodeBad(t *testing.T) { + testDecodeBad(t, true) + testDecodeBad(t, false) +} + +func testDecodeBad(t *testing.T, windows bool) { + b := bufWithBase("/verybadbase/", windows) + b.WriteString("Have fun decoding that key") + + _, err := DecodeV1PSK(b) + if err == nil { + t.Fatal("expected 'unknown encoding' got nil") + } +} + +func testDecodeHex(t *testing.T, windows bool) { + b := bufWithBase("/base16/", windows) + for i := 0; i < 32; i++ { + b.WriteString("FF") + } + + psk, err := DecodeV1PSK(b) + if err != nil { + t.Fatal(err) + } + + for _, b := range psk { + if b != 255 { + t.Fatal("byte was wrong") + } + } +} + +func TestDecodeB64(t *testing.T) { + testDecodeB64(t, true) + testDecodeB64(t, false) +} + +func testDecodeB64(t *testing.T, windows bool) { + b := bufWithBase("/base64/", windows) + key := make([]byte, 32) + for i := 0; i < 32; i++ { + key[i] = byte(i) + } + + e := base64.NewEncoder(base64.StdEncoding, b) + _, err := e.Write(key) + if err != nil { + t.Fatal(err) + } + err = e.Close() + if err != nil { + t.Fatal(err) + } + + psk, err := DecodeV1PSK(b) + if err != nil { + t.Fatal(err) + } + + for i, b := range psk { + if b != psk[i] { + t.Fatal("byte was wrong") + } + } + +} + +func TestDecodeBin(t *testing.T) { + testDecodeBin(t, true) + testDecodeBin(t, false) +} + +func testDecodeBin(t *testing.T, windows bool) { + b := bufWithBase("/bin/", windows) + key := make([]byte, 32) + for i := 0; i < 32; i++ { + key[i] = byte(i) + } + + b.Write(key) + + psk, err := DecodeV1PSK(b) + if err != nil { + t.Fatal(err) + } + + for i, b := range psk { + if b != psk[i] { + t.Fatal("byte was wrong") + } + } + +} diff --git a/core/pnet/env.go b/core/pnet/env.go new file mode 100644 index 0000000000..c8db5e3cbd --- /dev/null +++ b/core/pnet/env.go @@ -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" +} diff --git a/core/pnet/error.go b/core/pnet/error.go new file mode 100644 index 0000000000..184b71d6ac --- /dev/null +++ b/core/pnet/error.go @@ -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 +} diff --git a/core/pnet/error_test.go b/core/pnet/error_test.go new file mode 100644 index 0000000000..e1fe462b2a --- /dev/null +++ b/core/pnet/error_test.go @@ -0,0 +1,20 @@ +package pnet + +import ( + "errors" + "testing" +) + +func TestIsPnetErr(t *testing.T) { + err := NewError("test") + + if err.Error() != "privnet: test" { + t.Fatalf("expected 'privnet: test' got '%s'", err.Error()) + } + if !IsPNetError(err) { + t.Fatal("expected the pnetErr to be detected by IsPnetError") + } + if IsPNetError(errors.New("not pnet error")) { + t.Fatal("expected generic error not to be pnetError") + } +} diff --git a/core/pnet/protector.go b/core/pnet/protector.go new file mode 100644 index 0000000000..9d9dce9265 --- /dev/null +++ b/core/pnet/protector.go @@ -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 diff --git a/core/protocol/id.go b/core/protocol/id.go new file mode 100644 index 0000000000..9df3b5bcf1 --- /dev/null +++ b/core/protocol/id.go @@ -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 +} diff --git a/core/protocol/switch.go b/core/protocol/switch.go new file mode 100644 index 0000000000..e00ba1ad1f --- /dev/null +++ b/core/protocol/switch.go @@ -0,0 +1,82 @@ +// Package protocol provides core interfaces for protocol routing and negotiation in libp2p. +package protocol + +import ( + "io" +) + +// 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 = func(protocol string, rwc io.ReadWriteCloser) error + +// 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 string, 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 string, match func(string) bool, handler HandlerFunc) + + // RemoveHandler removes the registered handler (if any) for the + // given protocol ID string. + RemoveHandler(protocol string) + + // 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() []string +} + +// Negotiator is a component capable of reaching agreement over what protocols +// to use for inbound streams of communication. +type Negotiator interface { + // NegotiateLazy will return the registered protocol handler to use + // for a given inbound stream, returning as soon as the protocol has been + // determined. Returns an error if negotiation fails. + // + // NegotiateLazy may return before all protocol negotiation responses have been + // written to the stream. This is in contrast to Negotiate, which will block until + // the Negotiator is finished with the stream. + // + // Deprecated: use Negotiate instead. + NegotiateLazy(rwc io.ReadWriteCloser) (io.ReadWriteCloser, string, HandlerFunc, error) + + // 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) (string, 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 +} diff --git a/core/record/envelope.go b/core/record/envelope.go new file mode 100644 index 0000000000..38811994be --- /dev/null +++ b/core/record/envelope.go @@ -0,0 +1,299 @@ +package record + +import ( + "bytes" + "errors" + "fmt" + "sync" + + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/record/pb" + + pool "github.com/libp2p/go-buffer-pool" + + "github.com/gogo/protobuf/proto" + "github.com/multiformats/go-varint" +) + +// 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) +// } +// +// 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. +// +// 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 e, nil, fmt.Errorf("failed to validate envelope: %w", err) + } + + rec, err = e.Record() + if err != nil { + return e, 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 a 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 +} diff --git a/core/record/envelope_test.go b/core/record/envelope_test.go new file mode 100644 index 0000000000..45ac0e6687 --- /dev/null +++ b/core/record/envelope_test.go @@ -0,0 +1,314 @@ +package record_test + +import ( + "bytes" + "errors" + "testing" + + crypto "github.com/libp2p/go-libp2p/core/crypto" + . "github.com/libp2p/go-libp2p/core/record" + pb "github.com/libp2p/go-libp2p/core/record/pb" + "github.com/libp2p/go-libp2p/core/test" + + "github.com/gogo/protobuf/proto" +) + +type simpleRecord struct { + testDomain *string + testCodec []byte + message string +} + +func (r *simpleRecord) Domain() string { + if r.testDomain != nil { + return *r.testDomain + } + return "libp2p-testing" +} + +func (r *simpleRecord) Codec() []byte { + if r.testCodec != nil { + return r.testCodec + } + return []byte("/libp2p/testdata") +} + +func (r *simpleRecord) MarshalRecord() ([]byte, error) { + return []byte(r.message), nil +} + +func (r *simpleRecord) UnmarshalRecord(buf []byte) error { + r.message = string(buf) + return nil +} + +// Make an envelope, verify & open it, marshal & unmarshal it +func TestEnvelopeHappyPath(t *testing.T) { + var ( + rec = &simpleRecord{message: "hello world!"} + priv, pub, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + test.AssertNilError(t, err) + + payload, err := rec.MarshalRecord() + test.AssertNilError(t, err) + + envelope, err := Seal(rec, priv) + test.AssertNilError(t, err) + + if !envelope.PublicKey.Equals(pub) { + t.Error("envelope has unexpected public key") + } + + if !bytes.Equal(rec.Codec(), envelope.PayloadType) { + t.Error("PayloadType does not match record Codec") + } + + serialized, err := envelope.Marshal() + test.AssertNilError(t, err) + + RegisterType(&simpleRecord{}) + deserialized, rec2, err := ConsumeEnvelope(serialized, rec.Domain()) + test.AssertNilError(t, err) + + if !bytes.Equal(deserialized.RawPayload, payload) { + t.Error("payload of envelope does not match input") + } + + if !envelope.Equal(deserialized) { + t.Error("round-trip serde results in unequal envelope structures") + } + + typedRec, ok := rec2.(*simpleRecord) + if !ok { + t.Error("expected ConsumeEnvelope to return record with type registered for payloadType") + } + if typedRec.message != "hello world!" { + t.Error("unexpected alteration of record") + } +} + +func TestConsumeTypedEnvelope(t *testing.T) { + var ( + rec = simpleRecord{message: "hello world!"} + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + envelope, err := Seal(&rec, priv) + test.AssertNilError(t, err) + + envelopeBytes, err := envelope.Marshal() + test.AssertNilError(t, err) + + rec2 := &simpleRecord{} + _, err = ConsumeTypedEnvelope(envelopeBytes, rec2) + test.AssertNilError(t, err) + + if rec2.message != "hello world!" { + t.Error("unexpected alteration of record") + } +} + +func TestMakeEnvelopeFailsWithEmptyDomain(t *testing.T) { + var ( + rec = simpleRecord{message: "hello world!"} + domain = "" + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + if err != nil { + t.Fatal(err) + } + + // override domain with empty string + rec.testDomain = &domain + + _, err = Seal(&rec, priv) + test.ExpectError(t, err, "making an envelope with an empty domain should fail") +} + +func TestMakeEnvelopeFailsWithEmptyPayloadType(t *testing.T) { + var ( + rec = simpleRecord{message: "hello world!"} + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + if err != nil { + t.Fatal(err) + } + + // override payload with empty slice + rec.testCodec = []byte{} + + _, err = Seal(&rec, priv) + test.ExpectError(t, err, "making an envelope with an empty payloadType should fail") +} + +type failingRecord struct { + allowMarshal bool + allowUnmarshal bool +} + +func (r failingRecord) Domain() string { + return "testing" +} + +func (r failingRecord) Codec() []byte { + return []byte("doesn't matter") +} + +func (r failingRecord) MarshalRecord() ([]byte, error) { + if r.allowMarshal { + return []byte{}, nil + } + return nil, errors.New("marshal failed") +} +func (r failingRecord) UnmarshalRecord(data []byte) error { + if r.allowUnmarshal { + return nil + } + return errors.New("unmarshal failed") +} + +func TestSealFailsIfRecordMarshalFails(t *testing.T) { + var ( + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + if err != nil { + t.Fatal(err) + } + rec := failingRecord{} + _, err = Seal(rec, priv) + test.ExpectError(t, err, "Seal should fail if Record fails to marshal") +} + +func TestConsumeEnvelopeFailsIfEnvelopeUnmarshalFails(t *testing.T) { + _, _, err := ConsumeEnvelope([]byte("not an Envelope protobuf"), "doesn't-matter") + test.ExpectError(t, err, "ConsumeEnvelope should fail if Envelope fails to unmarshal") +} + +func TestConsumeEnvelopeFailsIfRecordUnmarshalFails(t *testing.T) { + var ( + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + if err != nil { + t.Fatal(err) + } + + RegisterType(failingRecord{}) + rec := failingRecord{allowMarshal: true} + env, err := Seal(rec, priv) + test.AssertNilError(t, err) + envBytes, err := env.Marshal() + test.AssertNilError(t, err) + + _, _, err = ConsumeEnvelope(envBytes, rec.Domain()) + test.ExpectError(t, err, "ConsumeEnvelope should fail if Record fails to unmarshal") +} + +func TestConsumeTypedEnvelopeFailsIfRecordUnmarshalFails(t *testing.T) { + var ( + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + if err != nil { + t.Fatal(err) + } + + RegisterType(failingRecord{}) + rec := failingRecord{allowMarshal: true} + env, err := Seal(rec, priv) + test.AssertNilError(t, err) + envBytes, err := env.Marshal() + test.AssertNilError(t, err) + + rec2 := failingRecord{} + _, err = ConsumeTypedEnvelope(envBytes, rec2) + test.ExpectError(t, err, "ConsumeTypedEnvelope should fail if Record fails to unmarshal") +} + +func TestEnvelopeValidateFailsForDifferentDomain(t *testing.T) { + var ( + rec = &simpleRecord{message: "hello world"} + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + test.AssertNilError(t, err) + + envelope, err := Seal(rec, priv) + test.AssertNilError(t, err) + + serialized, err := envelope.Marshal() + test.AssertNilError(t, err) + + // try to open our modified envelope + _, _, err = ConsumeEnvelope(serialized, "wrong-domain") + test.ExpectError(t, err, "should not be able to open envelope with incorrect domain") +} + +func TestEnvelopeValidateFailsIfPayloadTypeIsAltered(t *testing.T) { + var ( + rec = &simpleRecord{message: "hello world!"} + domain = "libp2p-testing" + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + test.AssertNilError(t, err) + + envelope, err := Seal(rec, priv) + test.AssertNilError(t, err) + + serialized := alterMessageAndMarshal(t, envelope, func(msg *pb.Envelope) { + msg.PayloadType = []byte("foo") + }) + + // try to open our modified envelope + _, _, err = ConsumeEnvelope(serialized, domain) + test.ExpectError(t, err, "should not be able to open envelope with modified PayloadType") +} + +func TestEnvelopeValidateFailsIfContentsAreAltered(t *testing.T) { + var ( + rec = &simpleRecord{message: "hello world!"} + domain = "libp2p-testing" + priv, _, err = test.RandTestKeyPair(crypto.Ed25519, 256) + ) + + test.AssertNilError(t, err) + + envelope, err := Seal(rec, priv) + test.AssertNilError(t, err) + + serialized := alterMessageAndMarshal(t, envelope, func(msg *pb.Envelope) { + msg.Payload = []byte("totally legit, trust me") + }) + + // try to open our modified envelope + _, _, err = ConsumeEnvelope(serialized, domain) + test.ExpectError(t, err, "should not be able to open envelope with modified payload") +} + +// Since we're outside of the crypto package (to avoid import cycles with test package), +// we can't alter the fields in a Envelope directly. This helper marshals +// the envelope to a protobuf and calls the alterMsg function, which should +// alter the protobuf message. +// Returns the serialized altered protobuf message. +func alterMessageAndMarshal(t *testing.T, envelope *Envelope, alterMsg func(*pb.Envelope)) []byte { + t.Helper() + + serialized, err := envelope.Marshal() + test.AssertNilError(t, err) + + msg := pb.Envelope{} + err = proto.Unmarshal(serialized, &msg) + test.AssertNilError(t, err) + + alterMsg(&msg) + serialized, err = msg.Marshal() + test.AssertNilError(t, err) + + return serialized +} diff --git a/core/record/pb/Makefile b/core/record/pb/Makefile new file mode 100644 index 0000000000..7cf8222f89 --- /dev/null +++ b/core/record/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(PWD):$(PWD)/../.. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/core/record/pb/envelope.pb.go b/core/record/pb/envelope.pb.go new file mode 100644 index 0000000000..a999021753 --- /dev/null +++ b/core/record/pb/envelope.pb.go @@ -0,0 +1,505 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: envelope.proto + +package record_pb + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// 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 { + // 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 (m *Envelope) Reset() { *m = Envelope{} } +func (m *Envelope) String() string { return proto.CompactTextString(m) } +func (*Envelope) ProtoMessage() {} +func (*Envelope) Descriptor() ([]byte, []int) { + return fileDescriptor_ee266e8c558e9dc5, []int{0} +} +func (m *Envelope) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Envelope) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Envelope.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Envelope) XXX_Merge(src proto.Message) { + xxx_messageInfo_Envelope.Merge(m, src) +} +func (m *Envelope) XXX_Size() int { + return m.Size() +} +func (m *Envelope) XXX_DiscardUnknown() { + xxx_messageInfo_Envelope.DiscardUnknown(m) +} + +var xxx_messageInfo_Envelope proto.InternalMessageInfo + +func (m *Envelope) GetPublicKey() *pb.PublicKey { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *Envelope) GetPayloadType() []byte { + if m != nil { + return m.PayloadType + } + return nil +} + +func (m *Envelope) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *Envelope) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func init() { + proto.RegisterType((*Envelope)(nil), "record.pb.Envelope") +} + +func init() { proto.RegisterFile("envelope.proto", fileDescriptor_ee266e8c558e9dc5) } + +var fileDescriptor_ee266e8c558e9dc5 = []byte{ + // 205 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xcd, 0x2b, 0x4b, + 0xcd, 0xc9, 0x2f, 0x48, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x2c, 0x4a, 0x4d, 0xce, + 0x2f, 0x4a, 0xd1, 0x2b, 0x48, 0x92, 0x12, 0x4b, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0x2f, 0x48, + 0xd2, 0x87, 0xb0, 0x20, 0x4a, 0x94, 0x66, 0x31, 0x72, 0x71, 0xb8, 0x42, 0x75, 0x09, 0x19, 0x73, + 0x71, 0x15, 0x94, 0x26, 0xe5, 0x64, 0x26, 0xc7, 0x67, 0xa7, 0x56, 0x4a, 0x30, 0x2a, 0x30, 0x6a, + 0x70, 0x1b, 0x89, 0xe8, 0xc1, 0xd4, 0x27, 0xe9, 0x05, 0x80, 0x25, 0xbd, 0x53, 0x2b, 0x83, 0x38, + 0x0b, 0x60, 0x4c, 0x21, 0x45, 0x2e, 0x9e, 0x82, 0xc4, 0xca, 0x9c, 0xfc, 0xc4, 0x94, 0xf8, 0x92, + 0xca, 0x82, 0x54, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x6e, 0xa8, 0x58, 0x48, 0x65, 0x41, + 0xaa, 0x90, 0x04, 0x17, 0x3b, 0x94, 0x2b, 0xc1, 0x0c, 0x96, 0x85, 0x71, 0x85, 0x64, 0xb8, 0x38, + 0x8b, 0x33, 0xd3, 0xf3, 0x12, 0x4b, 0x4a, 0x8b, 0x52, 0x25, 0x58, 0xc1, 0x72, 0x08, 0x01, 0x27, + 0x89, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, + 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x48, 0x62, 0x03, 0xbb, 0xde, 0x18, + 0x10, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x0b, 0xd9, 0x6d, 0xf2, 0x00, 0x00, 0x00, +} + +func (m *Envelope) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Envelope) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Envelope) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintEnvelope(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x2a + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintEnvelope(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x1a + } + if len(m.PayloadType) > 0 { + i -= len(m.PayloadType) + copy(dAtA[i:], m.PayloadType) + i = encodeVarintEnvelope(dAtA, i, uint64(len(m.PayloadType))) + i-- + dAtA[i] = 0x12 + } + if m.PublicKey != nil { + { + size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEnvelope(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintEnvelope(dAtA []byte, offset int, v uint64) int { + offset -= sovEnvelope(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Envelope) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PublicKey != nil { + l = m.PublicKey.Size() + n += 1 + l + sovEnvelope(uint64(l)) + } + l = len(m.PayloadType) + if l > 0 { + n += 1 + l + sovEnvelope(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovEnvelope(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovEnvelope(uint64(l)) + } + return n +} + +func sovEnvelope(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozEnvelope(x uint64) (n int) { + return sovEnvelope(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Envelope) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEnvelope + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Envelope: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Envelope: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEnvelope + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEnvelope + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEnvelope + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PublicKey == nil { + m.PublicKey = &pb.PublicKey{} + } + if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PayloadType", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEnvelope + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEnvelope + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEnvelope + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PayloadType = append(m.PayloadType[:0], dAtA[iNdEx:postIndex]...) + if m.PayloadType == nil { + m.PayloadType = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEnvelope + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEnvelope + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEnvelope + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEnvelope + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEnvelope + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEnvelope + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEnvelope(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthEnvelope + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthEnvelope + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipEnvelope(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEnvelope + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEnvelope + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowEnvelope + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthEnvelope + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupEnvelope + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthEnvelope + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthEnvelope = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowEnvelope = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupEnvelope = fmt.Errorf("proto: unexpected end of group") +) diff --git a/core/record/pb/envelope.proto b/core/record/pb/envelope.proto new file mode 100644 index 0000000000..ca3555fbf7 --- /dev/null +++ b/core/record/pb/envelope.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package record.pb; + +import "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; +} diff --git a/core/record/record.go b/core/record/record.go new file mode 100644 index 0000000000..704227f2a9 --- /dev/null +++ b/core/record/record.go @@ -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 lookup 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 +} diff --git a/core/record/record_test.go b/core/record/record_test.go new file mode 100644 index 0000000000..637964020c --- /dev/null +++ b/core/record/record_test.go @@ -0,0 +1,51 @@ +package record + +import "testing" + +var testPayloadType = []byte("/libp2p/test/record/payload-type") + +type testPayload struct { + unmarshalPayloadCalled bool +} + +func (p *testPayload) Domain() string { + return "testing" +} + +func (p *testPayload) Codec() []byte { + return testPayloadType +} + +func (p *testPayload) MarshalRecord() ([]byte, error) { + return []byte("hello"), nil +} + +func (p *testPayload) UnmarshalRecord(bytes []byte) error { + p.unmarshalPayloadCalled = true + return nil +} + +func TestUnmarshalPayload(t *testing.T) { + t.Run("fails if payload type is unregistered", func(t *testing.T) { + _, err := unmarshalRecordPayload([]byte("unknown type"), []byte{}) + if err != ErrPayloadTypeNotRegistered { + t.Error("Expected error when unmarshalling payload with unregistered payload type") + } + }) + + t.Run("calls UnmarshalRecord on concrete Record type", func(t *testing.T) { + RegisterType(&testPayload{}) + + payload, err := unmarshalRecordPayload(testPayloadType, []byte{}) + if err != nil { + t.Errorf("unexpected error unmarshalling registered payload type: %v", err) + } + typedPayload, ok := payload.(*testPayload) + if !ok { + t.Error("expected unmarshalled payload to be of the correct type") + } + if !typedPayload.unmarshalPayloadCalled { + t.Error("expected UnmarshalRecord to be called on concrete Record instance") + } + }) +} diff --git a/core/routing/options.go b/core/routing/options.go new file mode 100644 index 0000000000..4b235cbfc0 --- /dev/null +++ b/core/routing/options.go @@ -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 +} diff --git a/core/routing/query.go b/core/routing/query.go new file mode 100644 index 0000000000..72791b5274 --- /dev/null +++ b/core/routing/query.go @@ -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 falls, calling `PublishQueryEvent` on the +// context will be a no-op. +func SubscribesToQueryEvents(ctx context.Context) bool { + return ctx.Value(routingQueryKey{}) != nil +} diff --git a/core/routing/query_serde.go b/core/routing/query_serde.go new file mode 100644 index 0000000000..6b566e0ca8 --- /dev/null +++ b/core/routing/query_serde.go @@ -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 +} diff --git a/core/routing/query_test.go b/core/routing/query_test.go new file mode 100644 index 0000000000..15b4846dbb --- /dev/null +++ b/core/routing/query_test.go @@ -0,0 +1,44 @@ +package routing + +import ( + "context" + "fmt" + "sync" + "testing" +) + +func TestEventsCancel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + ctx, events := RegisterForQueryEvents(ctx) + goch := make(chan struct{}) + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + PublishQueryEvent(ctx, &QueryEvent{Extra: fmt.Sprint(i)}) + } + close(goch) + for i := 100; i < 1000; i++ { + PublishQueryEvent(ctx, &QueryEvent{Extra: fmt.Sprint(i)}) + } + }() + go func() { + defer wg.Done() + i := 0 + for e := range events { + if i < 100 { + if e.Extra != fmt.Sprint(i) { + t.Errorf("expected %d, got %s", i, e.Extra) + } + } + i++ + } + if i < 100 { + t.Errorf("expected at least 100 events, got %d", i) + } + }() + <-goch + cancel() + wg.Wait() +} diff --git a/core/routing/routing.go b/core/routing/routing.go new file mode 100644 index 0000000000..07437b5dff --- /dev/null +++ b/core/routing/routing.go @@ -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) +} diff --git a/core/sec/insecure/insecure.go b/core/sec/insecure/insecure.go new file mode 100644 index 0000000000..12bd1842b4 --- /dev/null +++ b/core/sec/insecure/insecure.go @@ -0,0 +1,234 @@ +// Package insecure provides an insecure, unencrypted implementation of the 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/peer" + "github.com/libp2p/go-libp2p/core/sec" + pb "github.com/libp2p/go-libp2p/core/sec/insecure/pb" + + "github.com/libp2p/go-msgio" +) + +// 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 +} + +// NewWithIdentity constructs a new insecure transport. The provided private key +// is stored and returned from LocalPrivateKey to satisfy the +// SecureTransport interface, and the public key is sent to +// remote peers. No security is provided. +func NewWithIdentity(id peer.ID, key ci.PrivKey) *Transport { + return &Transport{ + id: id, + key: key, + } +} + +// LocalPeer returns the transport's local peer ID. +func (t *Transport) LocalPeer() peer.ID { + return t.id +} + +// LocalPrivateKey returns the local private key. +// This key is used only for identity generation and provides no security. +func (t *Transport) LocalPrivateKey() ci.PrivKey { + return t.key +} + +// 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(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + conn := &Conn{ + Conn: insecure, + local: t.id, + localPrivKey: t.key, + } + + err := conn.runHandshakeSync() + if err != nil { + return nil, err + } + + if t.key != nil && 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(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + conn := &Conn{ + Conn: insecure, + local: t.id, + localPrivKey: t.key, + } + + err := conn.runHandshakeSync() + if err != nil { + return nil, err + } + + if t.key != nil && p != conn.remote { + return nil, fmt.Errorf("remote peer sent unexpected peer ID. expected=%s received=%s", + p, conn.remote) + } + + return conn, nil +} + +// Conn is the connection type returned by the insecure transport. +type Conn struct { + net.Conn + + local peer.ID + remote peer.ID + + localPrivKey ci.PrivKey + 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.localPrivKey == nil { + return nil + } + + // Generate an Exchange message + msg, err := makeExchangeMessage(ic.localPrivKey.GetPublic()) + 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 := out.Marshal() + 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) + msg, err1 := r.ReadMsg() + + // Always wait for the read to finish. + err2 := <-wresult + + if err1 != nil { + return nil, err1 + } + if err2 != nil { + r.ReleaseMsg(msg) + return nil, err2 + } + inMsg := new(pb.Exchange) + err = inMsg.Unmarshal(msg) + 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 +} + +// LocalPrivateKey returns the private key for the local peer. +func (ic *Conn) LocalPrivateKey() ci.PrivKey { + return ic.localPrivKey +} + +var _ sec.SecureTransport = (*Transport)(nil) +var _ sec.SecureConn = (*Conn)(nil) diff --git a/core/sec/insecure/insecure_test.go b/core/sec/insecure/insecure_test.go new file mode 100644 index 0000000000..a3ce8314f4 --- /dev/null +++ b/core/sec/insecure/insecure_test.go @@ -0,0 +1,128 @@ +package insecure + +import ( + "context" + "io" + "net" + "testing" + + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + + "github.com/stretchr/testify/require" +) + +// Run a set of sessions through the session setup and verification. +func TestConnections(t *testing.T) { + clientTpt := newTestTransport(t, crypto.RSA, 2048) + serverTpt := newTestTransport(t, crypto.Ed25519, 1024) + + clientConn, serverConn, clientErr, serverErr := connect(t, clientTpt, serverTpt, serverTpt.LocalPeer(), "") + require.NoError(t, clientErr) + require.NoError(t, serverErr) + testIDs(t, clientTpt, serverTpt, clientConn, serverConn) + testKeys(t, clientTpt, serverTpt, clientConn, serverConn) + testReadWrite(t, clientConn, serverConn) +} + +func TestPeerIdMatchInbound(t *testing.T) { + clientTpt := newTestTransport(t, crypto.RSA, 2048) + serverTpt := newTestTransport(t, crypto.Ed25519, 1024) + + clientConn, serverConn, clientErr, serverErr := connect(t, clientTpt, serverTpt, serverTpt.LocalPeer(), clientTpt.LocalPeer()) + require.NoError(t, clientErr) + require.NoError(t, serverErr) + testIDs(t, clientTpt, serverTpt, clientConn, serverConn) + testKeys(t, clientTpt, serverTpt, clientConn, serverConn) + testReadWrite(t, clientConn, serverConn) +} + +func TestPeerIDMismatchInbound(t *testing.T) { + clientTpt := newTestTransport(t, crypto.RSA, 2048) + serverTpt := newTestTransport(t, crypto.Ed25519, 1024) + + _, _, _, serverErr := connect(t, clientTpt, serverTpt, serverTpt.LocalPeer(), "a-random-peer") + require.Error(t, serverErr) + require.Contains(t, serverErr.Error(), "remote peer sent unexpected peer ID") +} + +func TestPeerIDMismatchOutbound(t *testing.T) { + clientTpt := newTestTransport(t, crypto.RSA, 2048) + serverTpt := newTestTransport(t, crypto.Ed25519, 1024) + + _, _, clientErr, _ := connect(t, clientTpt, serverTpt, "a random peer", "") + require.Error(t, clientErr) + require.Contains(t, clientErr.Error(), "remote peer sent unexpected peer ID") +} + +func newTestTransport(t *testing.T, typ, bits int) *Transport { + priv, pub, err := crypto.GenerateKeyPair(typ, bits) + require.NoError(t, err) + id, err := peer.IDFromPublicKey(pub) + require.NoError(t, err) + return NewWithIdentity(id, priv) +} + +// Create a new pair of connected TCP sockets. +func newConnPair(t *testing.T) (net.Conn, net.Conn) { + lstnr, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err, "failed to listen") + + var clientErr error + var client net.Conn + done := make(chan struct{}) + + go func() { + defer close(done) + addr := lstnr.Addr() + client, clientErr = net.Dial(addr.Network(), addr.String()) + }() + + server, err := lstnr.Accept() + require.NoError(t, err, "failed to accept") + + <-done + lstnr.Close() + require.NoError(t, clientErr, "failed to connect") + return client, server +} + +func connect(t *testing.T, clientTpt, serverTpt *Transport, clientExpectsID, serverExpectsID peer.ID) (clientConn sec.SecureConn, serverConn sec.SecureConn, clientErr, serverErr error) { + client, server := newConnPair(t) + + done := make(chan struct{}) + go func() { + defer close(done) + clientConn, clientErr = clientTpt.SecureOutbound(context.TODO(), client, clientExpectsID) + }() + serverConn, serverErr = serverTpt.SecureInbound(context.TODO(), server, serverExpectsID) + <-done + return +} + +// Check the peer IDs +func testIDs(t *testing.T, clientTpt, serverTpt *Transport, clientConn, serverConn sec.SecureConn) { + require.Equal(t, clientConn.LocalPeer(), clientTpt.LocalPeer(), "Client Local Peer ID mismatch.") + require.Equal(t, clientConn.RemotePeer(), serverTpt.LocalPeer(), "Client Remote Peer ID mismatch.") + require.Equal(t, clientConn.LocalPeer(), serverConn.RemotePeer(), "Server Local Peer ID mismatch.") +} + +// Check the keys +func testKeys(t *testing.T, clientTpt, serverTpt *Transport, clientConn, serverConn sec.SecureConn) { + sk := serverConn.LocalPrivateKey() + require.True(t, sk.Equals(serverTpt.LocalPrivateKey()), "private key mismatch") + require.True(t, sk.GetPublic().Equals(clientConn.RemotePublicKey()), "public key mismatch") +} + +// Check sending and receiving messages +func testReadWrite(t *testing.T, clientConn, serverConn sec.SecureConn) { + before := []byte("hello world") + _, err := clientConn.Write(before) + require.NoError(t, err) + + after := make([]byte, len(before)) + _, err = io.ReadFull(serverConn, after) + require.NoError(t, err) + require.Equal(t, before, after, "message mismatch") +} diff --git a/core/sec/insecure/pb/Makefile b/core/sec/insecure/pb/Makefile new file mode 100644 index 0000000000..4fb825a4bb --- /dev/null +++ b/core/sec/insecure/pb/Makefile @@ -0,0 +1,11 @@ +PB = $(wildcard *.proto) +GO = $(PB:.proto=.pb.go) + +all: $(GO) + +%.pb.go: %.proto + protoc --proto_path=$(GOPATH)/src:../../../crypto/pb:. --gogofaster_out=. $< + +clean: + rm -f *.pb.go + rm -f *.go diff --git a/core/sec/insecure/pb/plaintext.pb.go b/core/sec/insecure/pb/plaintext.pb.go new file mode 100644 index 0000000000..cd8719d110 --- /dev/null +++ b/core/sec/insecure/pb/plaintext.pb.go @@ -0,0 +1,383 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: plaintext.proto + +package plaintext_pb + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Exchange struct { + Id []byte `protobuf:"bytes,1,opt,name=id" json:"id"` + Pubkey *pb.PublicKey `protobuf:"bytes,2,opt,name=pubkey" json:"pubkey,omitempty"` +} + +func (m *Exchange) Reset() { *m = Exchange{} } +func (m *Exchange) String() string { return proto.CompactTextString(m) } +func (*Exchange) ProtoMessage() {} +func (*Exchange) Descriptor() ([]byte, []int) { + return fileDescriptor_aba144f73931b711, []int{0} +} +func (m *Exchange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Exchange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Exchange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Exchange) XXX_Merge(src proto.Message) { + xxx_messageInfo_Exchange.Merge(m, src) +} +func (m *Exchange) XXX_Size() int { + return m.Size() +} +func (m *Exchange) XXX_DiscardUnknown() { + xxx_messageInfo_Exchange.DiscardUnknown(m) +} + +var xxx_messageInfo_Exchange proto.InternalMessageInfo + +func (m *Exchange) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *Exchange) GetPubkey() *pb.PublicKey { + if m != nil { + return m.Pubkey + } + return nil +} + +func init() { + proto.RegisterType((*Exchange)(nil), "plaintext.pb.Exchange") +} + +func init() { proto.RegisterFile("plaintext.proto", fileDescriptor_aba144f73931b711) } + +var fileDescriptor_aba144f73931b711 = []byte{ + // 187 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0xc8, 0x49, 0xcc, + 0xcc, 0x2b, 0x49, 0xad, 0x28, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x41, 0x12, 0x48, + 0x92, 0x32, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xc9, 0x4c, + 0x2a, 0x30, 0x2a, 0xd0, 0x4f, 0xcf, 0xd7, 0x85, 0xb0, 0x74, 0x93, 0xf3, 0x8b, 0x52, 0xf5, 0x93, + 0x8b, 0x2a, 0x0b, 0x4a, 0xf2, 0xf5, 0x0b, 0x92, 0xa0, 0x2c, 0x88, 0x31, 0x4a, 0x7e, 0x5c, 0x1c, + 0xae, 0x15, 0xc9, 0x19, 0x89, 0x79, 0xe9, 0xa9, 0x42, 0x22, 0x5c, 0x4c, 0x99, 0x29, 0x12, 0x8c, + 0x0a, 0x8c, 0x1a, 0x3c, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x31, 0x65, 0xa6, 0x08, 0xe9, + 0x70, 0xb1, 0x15, 0x94, 0x26, 0x65, 0xa7, 0x56, 0x4a, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x1b, 0x89, + 0xe8, 0xc1, 0x0c, 0x48, 0xd2, 0x0b, 0x28, 0x4d, 0xca, 0xc9, 0x4c, 0xf6, 0x4e, 0xad, 0x0c, 0x82, + 0xaa, 0x71, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, + 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x06, 0x40, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x40, 0xde, 0x90, 0x0b, 0xc2, 0x00, 0x00, 0x00, +} + +func (m *Exchange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Exchange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Exchange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pubkey != nil { + { + size, err := m.Pubkey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPlaintext(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Id != nil { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintPlaintext(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintPlaintext(dAtA []byte, offset int, v uint64) int { + offset -= sovPlaintext(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Exchange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != nil { + l = len(m.Id) + n += 1 + l + sovPlaintext(uint64(l)) + } + if m.Pubkey != nil { + l = m.Pubkey.Size() + n += 1 + l + sovPlaintext(uint64(l)) + } + return n +} + +func sovPlaintext(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPlaintext(x uint64) (n int) { + return sovPlaintext(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Exchange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlaintext + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Exchange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Exchange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlaintext + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPlaintext + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPlaintext + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = append(m.Id[:0], dAtA[iNdEx:postIndex]...) + if m.Id == nil { + m.Id = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pubkey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPlaintext + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPlaintext + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPlaintext + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pubkey == nil { + m.Pubkey = &pb.PublicKey{} + } + if err := m.Pubkey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPlaintext(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPlaintext + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPlaintext + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPlaintext(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPlaintext + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthPlaintext + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPlaintext + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPlaintext + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPlaintext = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPlaintext = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPlaintext = fmt.Errorf("proto: unexpected end of group") +) diff --git a/core/sec/insecure/pb/plaintext.proto b/core/sec/insecure/pb/plaintext.proto new file mode 100644 index 0000000000..0e792b3cf5 --- /dev/null +++ b/core/sec/insecure/pb/plaintext.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package plaintext.pb; + +import "github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto"; + +message Exchange { + optional bytes id = 1; + optional crypto.pb.PublicKey pubkey = 2; +} diff --git a/core/sec/security.go b/core/sec/security.go new file mode 100644 index 0000000000..c192a56a91 --- /dev/null +++ b/core/sec/security.go @@ -0,0 +1,42 @@ +// 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" +) + +// 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) +} + +// A SecureMuxer is a wrapper around SecureTransport which can select security protocols +// and open outbound connections with simultaneous open. +type SecureMuxer interface { + // SecureInbound secures an inbound connection. + // The returned boolean indicates whether the connection should be treated as a server + // connection; in the case of SecureInbound it should always be true. + // If p is empty, connections from any peer are accepted. + SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (SecureConn, bool, error) + + // SecureOutbound secures an outbound connection. + // The returned boolean indicates whether the connection should be treated as a server + // connection due to simultaneous open. + SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (SecureConn, bool, error) +} diff --git a/core/test/addrs.go b/core/test/addrs.go new file mode 100644 index 0000000000..e18849c487 --- /dev/null +++ b/core/test/addrs.go @@ -0,0 +1,42 @@ +package test + +import ( + "fmt" + "testing" + + ma "github.com/multiformats/go-multiaddr" +) + +func GenerateTestAddrs(n int) []ma.Multiaddr { + out := make([]ma.Multiaddr, n) + for i := 0; i < n; i++ { + a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/1.2.3.4/tcp/%d", i)) + if err != nil { + continue + } + out[i] = a + } + return out +} + +func AssertAddressesEqual(t *testing.T, exp, act []ma.Multiaddr) { + t.Helper() + if len(exp) != len(act) { + t.Fatalf("lengths not the same. expected %d, got %d\n", len(exp), len(act)) + } + + for _, a := range exp { + found := false + + for _, b := range act { + if a.Equal(b) { + found = true + break + } + } + + if !found { + t.Fatalf("expected address %s not found", a) + } + } +} diff --git a/core/test/crypto.go b/core/test/crypto.go new file mode 100644 index 0000000000..5032485b3e --- /dev/null +++ b/core/test/crypto.go @@ -0,0 +1,21 @@ +package test + +import ( + "math/rand" + "sync/atomic" + + ci "github.com/libp2p/go-libp2p/core/crypto" +) + +var globalSeed int64 + +func RandTestKeyPair(typ, bits int) (ci.PrivKey, ci.PubKey, error) { + // workaround for low time resolution + seed := atomic.AddInt64(&globalSeed, 1) + return SeededTestKeyPair(typ, bits, seed) +} + +func SeededTestKeyPair(typ, bits int, seed int64) (ci.PrivKey, ci.PubKey, error) { + r := rand.New(rand.NewSource(seed)) + return ci.GenerateKeyPairWithReader(typ, bits, r) +} diff --git a/core/test/errors.go b/core/test/errors.go new file mode 100644 index 0000000000..82a3e696f2 --- /dev/null +++ b/core/test/errors.go @@ -0,0 +1,19 @@ +package test + +import ( + "testing" +) + +func AssertNilError(t *testing.T, err error) { + t.Helper() + if err != nil { + t.Errorf("unexpected error: %v", err) + } +} + +func ExpectError(t *testing.T, err error, msg string) { + t.Helper() + if err == nil { + t.Error(msg) + } +} diff --git a/core/test/peer.go b/core/test/peer.go new file mode 100644 index 0000000000..11998ff8e7 --- /dev/null +++ b/core/test/peer.go @@ -0,0 +1,25 @@ +package test + +import ( + "math/rand" + "testing" + + "github.com/libp2p/go-libp2p/core/peer" + + mh "github.com/multiformats/go-multihash" +) + +func RandPeerID() (peer.ID, error) { + buf := make([]byte, 16) + rand.Read(buf) + h, _ := mh.Sum(buf, mh.SHA2_256, -1) + return peer.ID(h), nil +} + +func RandPeerIDFatal(t testing.TB) peer.ID { + p, err := RandPeerID() + if err != nil { + t.Fatal(err) + } + return p +} diff --git a/core/transport/transport.go b/core/transport/transport.go new file mode 100644 index 0000000000..379e9d6d4a --- /dev/null +++ b/core/transport/transport.go @@ -0,0 +1,116 @@ +// Package transport provides the Transport interface, which represents +// the devices and network protocols used to send and receive data. +package transport + +import ( + "context" + "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 +} + +// 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 +} + +// 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) +} diff --git a/defaults.go b/defaults.go index 50985f34bc..ca70644860 100644 --- a/defaults.go +++ b/defaults.go @@ -5,6 +5,7 @@ package libp2p import ( "crypto/rand" + "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" @@ -15,8 +16,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/transport/tcp" ws "github.com/libp2p/go-libp2p/p2p/transport/websocket" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/multiformats/go-multiaddr" ) diff --git a/go.mod b/go.mod index 3abfc0388b..0f7044162b 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.18 require ( github.com/benbjohnson/clock v1.3.0 + github.com/btcsuite/btcd/btcec/v2 v2.2.0 github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c github.com/flynn/noise v1.0.0 github.com/gogo/protobuf v1.3.2 @@ -19,13 +20,14 @@ require ( github.com/jbenet/go-temp-err-catcher v0.1.0 github.com/klauspost/compress v1.15.1 github.com/libp2p/go-buffer-pool v0.1.0 + github.com/libp2p/go-flow-metrics v0.1.0 github.com/libp2p/go-libp2p-asn-util v0.2.0 - github.com/libp2p/go-libp2p-core v0.19.1 github.com/libp2p/go-libp2p-testing v0.11.0 github.com/libp2p/go-mplex v0.7.0 github.com/libp2p/go-msgio v0.2.0 github.com/libp2p/go-nat v0.1.0 github.com/libp2p/go-netroute v0.2.0 + github.com/libp2p/go-openssl v0.0.7 github.com/libp2p/go-reuseport v0.2.0 github.com/libp2p/go-yamux/v3 v3.1.2 github.com/libp2p/zeroconf/v2 v2.1.1 @@ -33,10 +35,12 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b github.com/minio/sha256-simd v1.0.0 + github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-base32 v0.0.4 github.com/multiformats/go-multiaddr v0.6.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multiaddr-fmt v0.1.0 + github.com/multiformats/go-multicodec v0.5.0 github.com/multiformats/go-multihash v0.2.0 github.com/multiformats/go-multistream v0.3.3 github.com/multiformats/go-varint v0.0.6 @@ -54,7 +58,6 @@ require ( require ( github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cheekybits/genny v1.0.0 // indirect @@ -80,8 +83,6 @@ require ( github.com/klauspost/cpuid/v2 v2.0.14 // indirect github.com/koron/go-ssdp v0.0.3 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect - github.com/libp2p/go-flow-metrics v0.0.3 // indirect - github.com/libp2p/go-openssl v0.0.7 // indirect github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect @@ -90,10 +91,8 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect - github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-multibase v0.1.1 // indirect - github.com/multiformats/go-multicodec v0.5.0 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect diff --git a/go.sum b/go.sum index 996b23138a..f3c26dee08 100644 --- a/go.sum +++ b/go.sum @@ -299,12 +299,10 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= -github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= +github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-core v0.19.1 h1:zaZQQCeCrFMtxFa1wHy6AhsVynyNmZAvwgWqSSPT3WE= -github.com/libp2p/go-libp2p-core v0.19.1/go.mod h1:2uLhmmqDiFY+dw+70KkBLeKvvsJHGWUINRDdeV1ip7k= github.com/libp2p/go-libp2p-testing v0.11.0 h1:+R7FRl/U3Y00neyBSM2qgDzqz3HkWH24U9nMlascHL4= github.com/libp2p/go-libp2p-testing v0.11.0/go.mod h1:qG4sF27dfKFoK9KlVzK2y52LQKhp0VEmLjV5aDqr1Hg= github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= diff --git a/libp2p.go b/libp2p.go index 7fdd3b71fe..d77c3b9b2e 100644 --- a/libp2p.go +++ b/libp2p.go @@ -2,8 +2,7 @@ package libp2p import ( "github.com/libp2p/go-libp2p/config" - - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" ) // Config describes a set of settings for a libp2p node. diff --git a/libp2p_test.go b/libp2p_test.go index 92be78c122..992b0839c8 100644 --- a/libp2p_test.go +++ b/libp2p_test.go @@ -7,14 +7,13 @@ import ( "strings" "testing" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/transport/tcp" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - "github.com/stretchr/testify/require" ) diff --git a/limits.go b/limits.go index 94eea3b11f..cf81fa7629 100644 --- a/limits.go +++ b/limits.go @@ -1,8 +1,7 @@ package libp2p import ( - "github.com/libp2p/go-libp2p-core/protocol" - + "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-libp2p/p2p/host/autonat" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" diff --git a/options.go b/options.go index a10f3a6c03..6ed6a94d35 100644 --- a/options.go +++ b/options.go @@ -8,15 +8,14 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/metrics" - "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/pnet" - "github.com/libp2p/go-libp2p/config" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/metrics" + "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/pnet" "github.com/libp2p/go-libp2p/p2p/host/autorelay" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" @@ -330,7 +329,7 @@ func AutoNATServiceRateLimit(global, perPeer int, interval time.Duration) Option // to actively reject inbound/outbound connections based on the lifecycle stage // of the connection. // -// For more information, refer to go-libp2p-core.ConnectionGater. +// For more information, refer to go-libp2p/core.ConnectionGater. func ConnectionGater(cg connmgr.ConnectionGater) Option { return func(cfg *Config) error { if cfg.ConnectionGater != nil { diff --git a/options_filter.go b/options_filter.go index c6b8175d8e..1f94ac3f00 100644 --- a/options_filter.go +++ b/options_filter.go @@ -1,10 +1,10 @@ package libp2p import ( - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/control" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/discovery/backoff/backoffcache.go b/p2p/discovery/backoff/backoffcache.go index 9aacfdadc7..82c07241f6 100644 --- a/p2p/discovery/backoff/backoffcache.go +++ b/p2p/discovery/backoff/backoffcache.go @@ -6,8 +6,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/discovery/backoff/backoffcache_test.go b/p2p/discovery/backoff/backoffcache_test.go index 15b998af3f..fe528cca1a 100644 --- a/p2p/discovery/backoff/backoffcache_test.go +++ b/p2p/discovery/backoff/backoffcache_test.go @@ -10,8 +10,8 @@ import ( bhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/peer" mockClock "github.com/benbjohnson/clock" ) diff --git a/p2p/discovery/backoff/backoffconnector.go b/p2p/discovery/backoff/backoffconnector.go index 62ac49897b..8a355a2d96 100644 --- a/p2p/discovery/backoff/backoffconnector.go +++ b/p2p/discovery/backoff/backoffconnector.go @@ -5,10 +5,10 @@ import ( "sync" "time" - lru "github.com/hashicorp/golang-lru" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + lru "github.com/hashicorp/golang-lru" ) // BackoffConnector is a utility to connect to peers, but only if we have not recently tried connecting to them already diff --git a/p2p/discovery/backoff/backoffconnector_test.go b/p2p/discovery/backoff/backoffconnector_test.go index 6bf958f9c9..e95796c3b6 100644 --- a/p2p/discovery/backoff/backoffconnector_test.go +++ b/p2p/discovery/backoff/backoffconnector_test.go @@ -7,12 +7,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" bhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/require" ) diff --git a/p2p/discovery/mdns/mdns.go b/p2p/discovery/mdns/mdns.go index cbae29a252..637fcdcb08 100644 --- a/p2p/discovery/mdns/mdns.go +++ b/p2p/discovery/mdns/mdns.go @@ -8,11 +8,12 @@ import ( "strings" "sync" - logging "github.com/ipfs/go-log/v2" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/zeroconf/v2" + logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/discovery/mdns/mdns_test.go b/p2p/discovery/mdns/mdns_test.go index 60a49cae2c..a2462790d3 100644 --- a/p2p/discovery/mdns/mdns_test.go +++ b/p2p/discovery/mdns/mdns_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/p2p/discovery/mocks/mocks.go b/p2p/discovery/mocks/mocks.go index 8b31ead06e..be0c429da1 100644 --- a/p2p/discovery/mocks/mocks.go +++ b/p2p/discovery/mocks/mocks.go @@ -5,9 +5,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" ) type clock interface { diff --git a/p2p/discovery/routing/routing.go b/p2p/discovery/routing/routing.go index ed010617ce..c312c32bc7 100644 --- a/p2p/discovery/routing/routing.go +++ b/p2p/discovery/routing/routing.go @@ -4,9 +4,9 @@ import ( "context" "time" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/routing" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/routing" "github.com/ipfs/go-cid" mh "github.com/multiformats/go-multihash" diff --git a/p2p/discovery/routing/routing_test.go b/p2p/discovery/routing/routing_test.go index d24a5818e6..ed8ab25d1d 100644 --- a/p2p/discovery/routing/routing_test.go +++ b/p2p/discovery/routing/routing_test.go @@ -13,9 +13,9 @@ import ( swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" "github.com/ipfs/go-cid" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" ) type mockRoutingTable struct { diff --git a/p2p/discovery/util/util.go b/p2p/discovery/util/util.go index ad10d242f0..7417526158 100644 --- a/p2p/discovery/util/util.go +++ b/p2p/discovery/util/util.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/peer" logging "github.com/ipfs/go-log/v2" ) diff --git a/p2p/host/autonat/autonat.go b/p2p/host/autonat/autonat.go index 68b330a46b..0fd8b0ec49 100644 --- a/p2p/host/autonat/autonat.go +++ b/p2p/host/autonat/autonat.go @@ -7,13 +7,12 @@ import ( "sync/atomic" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/host/eventbus" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/p2p/host/autonat/autonat_test.go b/p2p/host/autonat/autonat_test.go index 693079a216..6c743650c8 100644 --- a/p2p/host/autonat/autonat_test.go +++ b/p2p/host/autonat/autonat_test.go @@ -5,15 +5,14 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" bhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-msgio/protoio" ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" diff --git a/p2p/host/autonat/client.go b/p2p/host/autonat/client.go index f4eb08ad39..3edbeb50e2 100644 --- a/p2p/host/autonat/client.go +++ b/p2p/host/autonat/client.go @@ -5,13 +5,12 @@ import ( "fmt" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-msgio/protoio" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/autonat/dialpolicy.go b/p2p/host/autonat/dialpolicy.go index 653882cbad..9615229559 100644 --- a/p2p/host/autonat/dialpolicy.go +++ b/p2p/host/autonat/dialpolicy.go @@ -3,7 +3,8 @@ package autonat import ( "net" - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/host/autonat/dialpolicy_test.go b/p2p/host/autonat/dialpolicy_test.go index afa047eb73..75731ae9cf 100644 --- a/p2p/host/autonat/dialpolicy_test.go +++ b/p2p/host/autonat/dialpolicy_test.go @@ -6,12 +6,11 @@ import ( "net" "testing" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" blankhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/autonat/interface.go b/p2p/host/autonat/interface.go index 2551f2c5a4..f4c89beab4 100644 --- a/p2p/host/autonat/interface.go +++ b/p2p/host/autonat/interface.go @@ -4,8 +4,8 @@ import ( "context" "io" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/autonat/notify.go b/p2p/host/autonat/notify.go index fb8e980afb..a57bf15652 100644 --- a/p2p/host/autonat/notify.go +++ b/p2p/host/autonat/notify.go @@ -1,7 +1,7 @@ package autonat import ( - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/p2p/host/autonat/options.go b/p2p/host/autonat/options.go index 390533137b..0935dc2337 100644 --- a/p2p/host/autonat/options.go +++ b/p2p/host/autonat/options.go @@ -4,8 +4,8 @@ import ( "errors" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" ) // config holds configurable options for the autonat subsystem. diff --git a/p2p/host/autonat/proto.go b/p2p/host/autonat/proto.go index 69ac587173..93f273cd6b 100644 --- a/p2p/host/autonat/proto.go +++ b/p2p/host/autonat/proto.go @@ -1,10 +1,9 @@ package autonat import ( + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/autonat/svc.go b/p2p/host/autonat/svc.go index fc1fc3a8a0..10136a7de3 100644 --- a/p2p/host/autonat/svc.go +++ b/p2p/host/autonat/svc.go @@ -7,12 +7,11 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" - "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-msgio/protoio" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/autonat/svc_test.go b/p2p/host/autonat/svc_test.go index d01230e329..e1d751f132 100644 --- a/p2p/host/autonat/svc_test.go +++ b/p2p/host/autonat/svc_test.go @@ -6,13 +6,12 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" bhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/host/autonat/test/autonat_test.go b/p2p/host/autonat/test/autonat_test.go index 46a592e732..5bc893930c 100644 --- a/p2p/host/autonat/test/autonat_test.go +++ b/p2p/host/autonat/test/autonat_test.go @@ -7,10 +7,9 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/p2p/host/autonat" "github.com/stretchr/testify/require" diff --git a/p2p/host/autorelay/autorelay.go b/p2p/host/autorelay/autorelay.go index cb06561d21..e4e3568eff 100644 --- a/p2p/host/autorelay/autorelay.go +++ b/p2p/host/autorelay/autorelay.go @@ -4,10 +4,9 @@ import ( "context" "sync" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" basic "github.com/libp2p/go-libp2p/p2p/host/basic" logging "github.com/ipfs/go-log/v2" diff --git a/p2p/host/autorelay/autorelay_test.go b/p2p/host/autorelay/autorelay_test.go index 3a5ed75eb1..cb4d7e8899 100644 --- a/p2p/host/autorelay/autorelay_test.go +++ b/p2p/host/autorelay/autorelay_test.go @@ -7,14 +7,13 @@ import ( "time" "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/host/autorelay" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" circuitv2_proto "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/benbjohnson/clock" ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" diff --git a/p2p/host/autorelay/host.go b/p2p/host/autorelay/host.go index 9a90c9e6ea..740ca23621 100644 --- a/p2p/host/autorelay/host.go +++ b/p2p/host/autorelay/host.go @@ -1,7 +1,7 @@ package autorelay import ( - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" ) type AutoRelayHost struct { diff --git a/p2p/host/autorelay/options.go b/p2p/host/autorelay/options.go index 69de152a97..e62f129de9 100644 --- a/p2p/host/autorelay/options.go +++ b/p2p/host/autorelay/options.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/benbjohnson/clock" ) diff --git a/p2p/host/autorelay/relay_finder.go b/p2p/host/autorelay/relay_finder.go index 2fa872d187..a62947d38f 100644 --- a/p2p/host/autorelay/relay_finder.go +++ b/p2p/host/autorelay/relay_finder.go @@ -10,15 +10,14 @@ import ( "golang.org/x/sync/errgroup" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" basic "github.com/libp2p/go-libp2p/p2p/host/basic" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" circuitv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client" circuitv2_proto "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" - "github.com/libp2p/go-libp2p-core/event" - "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" ) diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go index 423cbe87a8..d3642bd810 100644 --- a/p2p/host/basic/basic_host.go +++ b/p2p/host/basic/basic_host.go @@ -9,6 +9,15 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "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" + "github.com/libp2p/go-libp2p/core/record" "github.com/libp2p/go-libp2p/p2p/host/autonat" "github.com/libp2p/go-libp2p/p2p/host/eventbus" "github.com/libp2p/go-libp2p/p2p/host/pstoremanager" @@ -19,16 +28,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/protocol/identify" "github.com/libp2p/go-libp2p/p2p/protocol/ping" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "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" - "github.com/libp2p/go-libp2p-core/record" - "github.com/libp2p/go-netroute" logging "github.com/ipfs/go-log/v2" diff --git a/p2p/host/basic/basic_host_test.go b/p2p/host/basic/basic_host_test.go index 8bc83b6f9b..02243c23b4 100644 --- a/p2p/host/basic/basic_host_test.go +++ b/p2p/host/basic/basic_host_test.go @@ -10,20 +10,19 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "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" + "github.com/libp2p/go-libp2p/core/record" + "github.com/libp2p/go-libp2p/core/test" "github.com/libp2p/go-libp2p/p2p/host/autonat" "github.com/libp2p/go-libp2p/p2p/host/eventbus" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "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" - "github.com/libp2p/go-libp2p-core/record" - "github.com/libp2p/go-libp2p-core/test" - ma "github.com/multiformats/go-multiaddr" madns "github.com/multiformats/go-multiaddr-dns" diff --git a/p2p/host/basic/natmgr.go b/p2p/host/basic/natmgr.go index ab4cef6231..782c116d44 100644 --- a/p2p/host/basic/natmgr.go +++ b/p2p/host/basic/natmgr.go @@ -8,10 +8,9 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/network" inat "github.com/libp2p/go-libp2p/p2p/net/nat" - "github.com/libp2p/go-libp2p-core/network" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/basic/peer_connectedness.go b/p2p/host/basic/peer_connectedness.go index 5460498cc0..bfc46ed8f8 100644 --- a/p2p/host/basic/peer_connectedness.go +++ b/p2p/host/basic/peer_connectedness.go @@ -3,9 +3,9 @@ package basichost import ( "sync" - "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/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/basic/peer_connectedness_test.go b/p2p/host/basic/peer_connectedness_test.go index fc8ecb60a8..f124b10926 100644 --- a/p2p/host/basic/peer_connectedness_test.go +++ b/p2p/host/basic/peer_connectedness_test.go @@ -5,12 +5,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/require" ) diff --git a/p2p/host/blank/blank.go b/p2p/host/blank/blank.go index 08f1f2fa48..16753eb0d5 100644 --- a/p2p/host/blank/blank.go +++ b/p2p/host/blank/blank.go @@ -6,17 +6,16 @@ import ( "fmt" "io" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "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" + "github.com/libp2p/go-libp2p/core/record" "github.com/libp2p/go-libp2p/p2p/host/eventbus" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "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" - "github.com/libp2p/go-libp2p-core/record" - logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/host/blank/peer_connectedness.go b/p2p/host/blank/peer_connectedness.go index 670edc545f..4f70540fca 100644 --- a/p2p/host/blank/peer_connectedness.go +++ b/p2p/host/blank/peer_connectedness.go @@ -3,9 +3,9 @@ package blankhost import ( "sync" - "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/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/blank/peer_connectedness_test.go b/p2p/host/blank/peer_connectedness_test.go index cabf3fe14a..260daa1e7d 100644 --- a/p2p/host/blank/peer_connectedness_test.go +++ b/p2p/host/blank/peer_connectedness_test.go @@ -5,12 +5,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/require" ) diff --git a/p2p/host/eventbus/basic.go b/p2p/host/eventbus/basic.go index 94685d56fc..6ab6c410ae 100644 --- a/p2p/host/eventbus/basic.go +++ b/p2p/host/eventbus/basic.go @@ -7,10 +7,10 @@ import ( "sync" "sync/atomic" - "github.com/libp2p/go-libp2p-core/event" + "github.com/libp2p/go-libp2p/core/event" ) -/////////////////////// +// ///////////////////// // BUS // basicBus is a type-based event delivery system @@ -273,7 +273,7 @@ func (b *basicBus) GetAllEventTypes() []reflect.Type { return types } -/////////////////////// +// ///////////////////// // NODE type wildcardNode struct { diff --git a/p2p/host/eventbus/basic_test.go b/p2p/host/eventbus/basic_test.go index 95faebe325..d2ede36a6e 100644 --- a/p2p/host/eventbus/basic_test.go +++ b/p2p/host/eventbus/basic_test.go @@ -9,7 +9,8 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/event" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p-testing/race" "github.com/stretchr/testify/require" diff --git a/p2p/host/peerstore/metrics.go b/p2p/host/peerstore/metrics.go index 87a9410471..e05fda7d8e 100644 --- a/p2p/host/peerstore/metrics.go +++ b/p2p/host/peerstore/metrics.go @@ -4,7 +4,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // LatencyEWMASmoothing governs the decay of the EWMA (the speed diff --git a/p2p/host/peerstore/metrics_test.go b/p2p/host/peerstore/metrics_test.go index 723baad275..d92a482b51 100644 --- a/p2p/host/peerstore/metrics_test.go +++ b/p2p/host/peerstore/metrics_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/test" + "github.com/libp2p/go-libp2p/core/test" ) func TestLatencyEWMAFun(t *testing.T) { diff --git a/p2p/host/peerstore/pb/custom.go b/p2p/host/peerstore/pb/custom.go index 41784a4f6d..6f22f92a22 100644 --- a/p2p/host/peerstore/pb/custom.go +++ b/p2p/host/peerstore/pb/custom.go @@ -3,9 +3,10 @@ package pstore_pb import ( "encoding/json" - proto "github.com/gogo/protobuf/proto" - peer "github.com/libp2p/go-libp2p-core/peer" - pt "github.com/libp2p/go-libp2p-core/test" + "github.com/libp2p/go-libp2p/core/peer" + pt "github.com/libp2p/go-libp2p/core/test" + + "github.com/gogo/protobuf/proto" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/peerstore/peerstore.go b/p2p/host/peerstore/peerstore.go index 9f5eda8f49..45c22c3620 100644 --- a/p2p/host/peerstore/peerstore.go +++ b/p2p/host/peerstore/peerstore.go @@ -1,8 +1,8 @@ package peerstore import ( - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) func PeerInfos(ps pstore.Peerstore, peers peer.IDSlice) []peer.AddrInfo { diff --git a/p2p/host/peerstore/pstoreds/addr_book.go b/p2p/host/peerstore/pstoreds/addr_book.go index ac540154cc..b3c5b32375 100644 --- a/p2p/host/peerstore/pstoreds/addr_book.go +++ b/p2p/host/peerstore/pstoreds/addr_book.go @@ -7,13 +7,12 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" pb "github.com/libp2p/go-libp2p/p2p/host/peerstore/pb" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" - lru "github.com/hashicorp/golang-lru" ds "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" @@ -282,7 +281,7 @@ func (ab *dsAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duratio // ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in // a record.Envelope), which will expire after the given TTL. -// See https://godoc.org/github.com/libp2p/go-libp2p-core/peerstore#CertifiedAddrBook for more details. +// See https://godoc.org/github.com/libp2p/go-libp2p/core/peerstore#CertifiedAddrBook for more details. func (ab *dsAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, ttl time.Duration) (bool, error) { r, err := recordEnvelope.Record() if err != nil { diff --git a/p2p/host/peerstore/pstoreds/addr_book_gc.go b/p2p/host/peerstore/pstoreds/addr_book_gc.go index 06df64899f..1cca7ad61d 100644 --- a/p2p/host/peerstore/pstoreds/addr_book_gc.go +++ b/p2p/host/peerstore/pstoreds/addr_book_gc.go @@ -6,10 +6,9 @@ import ( "strconv" "time" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/host/peerstore/pb" - "github.com/libp2p/go-libp2p-core/peer" - ds "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" b32 "github.com/multiformats/go-base32" diff --git a/p2p/host/peerstore/pstoreds/addr_book_gc_test.go b/p2p/host/peerstore/pstoreds/addr_book_gc_test.go index 3a2cab0b4b..68446edc42 100644 --- a/p2p/host/peerstore/pstoreds/addr_book_gc_test.go +++ b/p2p/host/peerstore/pstoreds/addr_book_gc_test.go @@ -5,10 +5,9 @@ import ( "testing" "time" + pstore "github.com/libp2p/go-libp2p/core/peerstore" "github.com/libp2p/go-libp2p/p2p/host/peerstore/test" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - mockClock "github.com/benbjohnson/clock" "github.com/ipfs/go-datastore/query" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/host/peerstore/pstoreds/ds_test.go b/p2p/host/peerstore/pstoreds/ds_test.go index ce3be5ab50..60a4ba1726 100644 --- a/p2p/host/peerstore/pstoreds/ds_test.go +++ b/p2p/host/peerstore/pstoreds/ds_test.go @@ -6,10 +6,9 @@ import ( "testing" "time" + pstore "github.com/libp2p/go-libp2p/core/peerstore" pt "github.com/libp2p/go-libp2p/p2p/host/peerstore/test" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - mockClock "github.com/benbjohnson/clock" ds "github.com/ipfs/go-datastore" badger "github.com/ipfs/go-ds-badger" diff --git a/p2p/host/peerstore/pstoreds/keybook.go b/p2p/host/peerstore/pstoreds/keybook.go index 7ee06c81f3..9db799b172 100644 --- a/p2p/host/peerstore/pstoreds/keybook.go +++ b/p2p/host/peerstore/pstoreds/keybook.go @@ -4,14 +4,13 @@ import ( "context" "errors" - "github.com/multiformats/go-base32" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ds "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" - - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/multiformats/go-base32" ) // Public and private keys are stored under the following db key pattern: diff --git a/p2p/host/peerstore/pstoreds/metadata.go b/p2p/host/peerstore/pstoreds/metadata.go index 1420173570..64c24fd782 100644 --- a/p2p/host/peerstore/pstoreds/metadata.go +++ b/p2p/host/peerstore/pstoreds/metadata.go @@ -6,8 +6,8 @@ import ( "encoding/gob" pool "github.com/libp2p/go-buffer-pool" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ds "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" diff --git a/p2p/host/peerstore/pstoreds/peerstore.go b/p2p/host/peerstore/pstoreds/peerstore.go index df6069b7fb..bd54768129 100644 --- a/p2p/host/peerstore/pstoreds/peerstore.go +++ b/p2p/host/peerstore/pstoreds/peerstore.go @@ -6,9 +6,8 @@ import ( "io" "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" pstore "github.com/libp2p/go-libp2p/p2p/host/peerstore" ds "github.com/ipfs/go-datastore" diff --git a/p2p/host/peerstore/pstoreds/protobook.go b/p2p/host/peerstore/pstoreds/protobook.go index af44722c28..cfc6ef7dd0 100644 --- a/p2p/host/peerstore/pstoreds/protobook.go +++ b/p2p/host/peerstore/pstoreds/protobook.go @@ -5,9 +5,8 @@ import ( "fmt" "sync" - "github.com/libp2p/go-libp2p-core/peer" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type protoSegment struct { diff --git a/p2p/host/peerstore/pstoremem/addr_book.go b/p2p/host/peerstore/pstoremem/addr_book.go index 7e6a67fa07..28aa6d4d3c 100644 --- a/p2p/host/peerstore/pstoremem/addr_book.go +++ b/p2p/host/peerstore/pstoremem/addr_book.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" @@ -183,7 +183,7 @@ func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du // ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in // a record.Envelope), which will expire after the given TTL. -// See https://godoc.org/github.com/libp2p/go-libp2p-core/peerstore#CertifiedAddrBook for more details. +// See https://godoc.org/github.com/libp2p/go-libp2p/core/peerstore#CertifiedAddrBook for more details. func (mab *memoryAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, ttl time.Duration) (bool, error) { r, err := recordEnvelope.Record() if err != nil { diff --git a/p2p/host/peerstore/pstoremem/inmem_test.go b/p2p/host/peerstore/pstoremem/inmem_test.go index b025cd460d..097a1fd25e 100644 --- a/p2p/host/peerstore/pstoremem/inmem_test.go +++ b/p2p/host/peerstore/pstoremem/inmem_test.go @@ -3,10 +3,9 @@ package pstoremem import ( "testing" + pstore "github.com/libp2p/go-libp2p/core/peerstore" pt "github.com/libp2p/go-libp2p/p2p/host/peerstore/test" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - mockClock "github.com/benbjohnson/clock" "github.com/stretchr/testify/require" "go.uber.org/goleak" diff --git a/p2p/host/peerstore/pstoremem/keybook.go b/p2p/host/peerstore/pstoremem/keybook.go index 387a573617..f995a08797 100644 --- a/p2p/host/peerstore/pstoremem/keybook.go +++ b/p2p/host/peerstore/pstoremem/keybook.go @@ -4,10 +4,9 @@ import ( "errors" "sync" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type memoryKeyBook struct { diff --git a/p2p/host/peerstore/pstoremem/metadata.go b/p2p/host/peerstore/pstoremem/metadata.go index 0fd41c07dd..305c741719 100644 --- a/p2p/host/peerstore/pstoremem/metadata.go +++ b/p2p/host/peerstore/pstoremem/metadata.go @@ -3,8 +3,8 @@ package pstoremem import ( "sync" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type memoryPeerMetadata struct { diff --git a/p2p/host/peerstore/pstoremem/peerstore.go b/p2p/host/peerstore/pstoremem/peerstore.go index 7c0d18b9d4..ec403f84c0 100644 --- a/p2p/host/peerstore/pstoremem/peerstore.go +++ b/p2p/host/peerstore/pstoremem/peerstore.go @@ -4,10 +4,9 @@ import ( "fmt" "io" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" pstore "github.com/libp2p/go-libp2p/p2p/host/peerstore" - - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" ) type pstoremem struct { diff --git a/p2p/host/peerstore/pstoremem/protobook.go b/p2p/host/peerstore/pstoremem/protobook.go index b2cf73e1c7..7a955c0769 100644 --- a/p2p/host/peerstore/pstoremem/protobook.go +++ b/p2p/host/peerstore/pstoremem/protobook.go @@ -4,9 +4,8 @@ import ( "errors" "sync" - "github.com/libp2p/go-libp2p-core/peer" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type protoSegment struct { diff --git a/p2p/host/peerstore/test/addr_book_suite.go b/p2p/host/peerstore/test/addr_book_suite.go index 5bcf8820ab..dba2b3cd84 100644 --- a/p2p/host/peerstore/test/addr_book_suite.go +++ b/p2p/host/peerstore/test/addr_book_suite.go @@ -4,14 +4,14 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" + "github.com/libp2p/go-libp2p/core/test" + mockClock "github.com/benbjohnson/clock" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" - "github.com/libp2p/go-libp2p-core/test" "github.com/multiformats/go-multiaddr" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" ) var addressBookSuite = map[string]func(book pstore.AddrBook, clk *mockClock.Mock) func(*testing.T){ diff --git a/p2p/host/peerstore/test/benchmarks_suite.go b/p2p/host/peerstore/test/benchmarks_suite.go index c67303b108..d45cac897e 100644 --- a/p2p/host/peerstore/test/benchmarks_suite.go +++ b/p2p/host/peerstore/test/benchmarks_suite.go @@ -6,7 +6,7 @@ import ( "sort" "testing" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) var peerstoreBenchmarks = map[string]func(pstore.Peerstore, chan *peerpair) func(*testing.B){ diff --git a/p2p/host/peerstore/test/keybook_suite.go b/p2p/host/peerstore/test/keybook_suite.go index 2774b3df37..3e559753bc 100644 --- a/p2p/host/peerstore/test/keybook_suite.go +++ b/p2p/host/peerstore/test/keybook_suite.go @@ -4,13 +4,12 @@ import ( "sort" "testing" - "github.com/stretchr/testify/require" - - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - pt "github.com/libp2p/go-libp2p-core/test" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" + pt "github.com/libp2p/go-libp2p/core/test" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/stretchr/testify/require" ) var keyBookSuite = map[string]func(kb pstore.KeyBook) func(*testing.T){ diff --git a/p2p/host/peerstore/test/peerstore_suite.go b/p2p/host/peerstore/test/peerstore_suite.go index 38f9a49564..325399dec3 100644 --- a/p2p/host/peerstore/test/peerstore_suite.go +++ b/p2p/host/peerstore/test/peerstore_suite.go @@ -9,11 +9,11 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/host/peerstore/test/utils.go b/p2p/host/peerstore/test/utils.go index c169894b21..8d327f4525 100644 --- a/p2p/host/peerstore/test/utils.go +++ b/p2p/host/peerstore/test/utils.go @@ -5,8 +5,9 @@ import ( "fmt" "testing" - peer "github.com/libp2p/go-libp2p-core/peer" - pt "github.com/libp2p/go-libp2p-core/test" + "github.com/libp2p/go-libp2p/core/peer" + pt "github.com/libp2p/go-libp2p/core/test" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/pstoremanager/mock_peerstore_test.go b/p2p/host/pstoremanager/mock_peerstore_test.go index c1414cce52..a15476486c 100644 --- a/p2p/host/pstoremanager/mock_peerstore_test.go +++ b/p2p/host/pstoremanager/mock_peerstore_test.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/libp2p/go-libp2p-core/peerstore (interfaces: Peerstore) +// Source: github.com/libp2p/go-libp2p/core/peerstore (interfaces: Peerstore) // Package pstoremanager_test is a generated GoMock package. package pstoremanager_test @@ -10,8 +10,8 @@ import ( time "time" gomock "github.com/golang/mock/gomock" - crypto "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" + crypto "github.com/libp2p/go-libp2p/core/crypto" + peer "github.com/libp2p/go-libp2p/core/peer" multiaddr "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/pstoremanager/pstoremanager.go b/p2p/host/pstoremanager/pstoremanager.go index 311ca0c98b..f8382c709d 100644 --- a/p2p/host/pstoremanager/pstoremanager.go +++ b/p2p/host/pstoremanager/pstoremanager.go @@ -5,10 +5,10 @@ import ( "sync" "time" - "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/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" logging "github.com/ipfs/go-log/v2" ) diff --git a/p2p/host/pstoremanager/pstoremanager_test.go b/p2p/host/pstoremanager/pstoremanager_test.go index dec09cdf76..064e625907 100644 --- a/p2p/host/pstoremanager/pstoremanager_test.go +++ b/p2p/host/pstoremanager/pstoremanager_test.go @@ -4,18 +4,17 @@ import ( "testing" "time" + "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/p2p/host/eventbus" "github.com/libp2p/go-libp2p/p2p/host/pstoremanager" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) -//go:generate sh -c "mockgen -package pstoremanager_test -destination mock_peerstore_test.go github.com/libp2p/go-libp2p-core/peerstore Peerstore" +//go:generate sh -c "mockgen -package pstoremanager_test -destination mock_peerstore_test.go github.com/libp2p/go-libp2p/core/peerstore Peerstore" func TestGracePeriod(t *testing.T) { t.Parallel() diff --git a/p2p/host/relaysvc/relay.go b/p2p/host/relaysvc/relay.go index d1928b3343..a36e20e002 100644 --- a/p2p/host/relaysvc/relay.go +++ b/p2p/host/relaysvc/relay.go @@ -6,9 +6,9 @@ import ( relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" ) type RelayManager struct { diff --git a/p2p/host/resource-manager/allowlist.go b/p2p/host/resource-manager/allowlist.go index fd72af07c8..d2bdb86935 100644 --- a/p2p/host/resource-manager/allowlist.go +++ b/p2p/host/resource-manager/allowlist.go @@ -7,7 +7,8 @@ import ( "net" "sync" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/host/resource-manager/allowlist_test.go b/p2p/host/resource-manager/allowlist_test.go index 2e8ce3f7ba..d665b63ff8 100644 --- a/p2p/host/resource-manager/allowlist_test.go +++ b/p2p/host/resource-manager/allowlist_test.go @@ -6,8 +6,9 @@ import ( "net" "testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/test" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/test" + "github.com/multiformats/go-multiaddr" ) @@ -22,7 +23,7 @@ func ExampleWithAllowlistedMultiaddrs() { // Any peer connecting from this IP address multiaddr.StringCast("/ip4/1.2.3.4"), // Only the specified peer from this address - multiaddr.StringCast("/ip4/2.2.3.4/p2p/" + peer.Encode(somePeer)), + multiaddr.StringCast("/ip4/2.2.3.4/p2p/" + somePeer.String()), // Only peers from this 1.2.3.0/24 IP address range multiaddr.StringCast("/ip4/1.2.3.0/ipcidr/24"), })) @@ -77,7 +78,7 @@ func TestAllowedWithPeer(t *testing.T) { name: "Blocked wrong peer", isConnAllowed: true, isAllowedWithPeer: false, - allowlist: []string{"/ip4/1.2.3.4" + "/p2p/" + peer.Encode(peerB)}, + allowlist: []string{"/ip4/1.2.3.4" + "/p2p/" + peerB.String()}, endpoint: multiaddrA, peer: peerA, }, @@ -100,7 +101,7 @@ func TestAllowedWithPeer(t *testing.T) { name: "allowed. right network, right peer", isConnAllowed: true, isAllowedWithPeer: true, - allowlist: []string{"/ip4/1.2.3.0/ipcidr/24" + "/p2p/" + peer.Encode(peerA)}, + allowlist: []string{"/ip4/1.2.3.0/ipcidr/24" + "/p2p/" + peerA.String()}, endpoint: multiaddrA, peer: peerA, }, { @@ -115,7 +116,7 @@ func TestAllowedWithPeer(t *testing.T) { name: "Blocked. right network, wrong peer", isConnAllowed: true, isAllowedWithPeer: false, - allowlist: []string{"/ip4/1.2.3.0/ipcidr/24" + "/p2p/" + peer.Encode(peerB)}, + allowlist: []string{"/ip4/1.2.3.0/ipcidr/24" + "/p2p/" + peerB.String()}, endpoint: multiaddrA, peer: peerA, }, @@ -131,7 +132,7 @@ func TestAllowedWithPeer(t *testing.T) { name: "allowed peer multiple ips in allowlist", isConnAllowed: true, isAllowedWithPeer: true, - allowlist: []string{"/ip4/1.2.3.4/p2p/" + peer.Encode(peerA), "/ip4/2.2.3.4/p2p/" + peer.Encode(peerA)}, + allowlist: []string{"/ip4/1.2.3.4/p2p/" + peerA.String(), "/ip4/2.2.3.4/p2p/" + peerA.String()}, endpoint: multiaddrA, peer: peerA, }, @@ -139,7 +140,7 @@ func TestAllowedWithPeer(t *testing.T) { name: "allowed peer multiple ips in allowlist", isConnAllowed: true, isAllowedWithPeer: true, - allowlist: []string{"/ip4/1.2.3.4/p2p/" + peer.Encode(peerA), "/ip4/1.2.3.4/p2p/" + peer.Encode(peerA)}, + allowlist: []string{"/ip4/1.2.3.4/p2p/" + peerA.String(), "/ip4/1.2.3.4/p2p/" + peerA.String()}, endpoint: multiaddrA, peer: peerA, }, @@ -147,7 +148,7 @@ func TestAllowedWithPeer(t *testing.T) { name: "allowed peer multiple ips in allowlist", isConnAllowed: true, isAllowedWithPeer: true, - allowlist: []string{"/ip4/1.2.3.4/p2p/" + peer.Encode(peerA), "/ip4/2.2.3.4/p2p/" + peer.Encode(peerA)}, + allowlist: []string{"/ip4/1.2.3.4/p2p/" + peerA.String(), "/ip4/2.2.3.4/p2p/" + peerA.String()}, endpoint: multiaddrB, peer: peerA, }, @@ -186,9 +187,9 @@ func TestRemoved(t *testing.T) { testCases := []testCase{ {name: "ip4", allowedMA: "/ip4/1.2.3.4"}, - {name: "ip4 with peer", allowedMA: "/ip4/1.2.3.4/p2p/" + peer.Encode(peerA)}, + {name: "ip4 with peer", allowedMA: "/ip4/1.2.3.4/p2p/" + peerA.String()}, {name: "ip4 network", allowedMA: "/ip4/0.0.0.0/ipcidr/0"}, - {name: "ip4 network with peer", allowedMA: "/ip4/0.0.0.0/ipcidr/0/p2p/" + peer.Encode(peerA)}, + {name: "ip4 network with peer", allowedMA: "/ip4/0.0.0.0/ipcidr/0/p2p/" + peerA.String()}, } for _, tc := range testCases { @@ -255,7 +256,7 @@ func BenchmarkAllowlistCheck(b *testing.B) { var ma multiaddr.Multiaddr if i%ratioOfSpecifiedPeers == 0 { - ma = multiaddr.StringCast(ipString + "/p2p/" + peer.Encode(test.RandPeerIDFatal(b))) + ma = multiaddr.StringCast(ipString + "/p2p/" + test.RandPeerIDFatal(b).String()) } else { ma = multiaddr.StringCast(ipString) } diff --git a/p2p/host/resource-manager/error.go b/p2p/host/resource-manager/error.go index 1ccc86f994..4b02672b89 100644 --- a/p2p/host/resource-manager/error.go +++ b/p2p/host/resource-manager/error.go @@ -3,7 +3,7 @@ package rcmgr import ( "errors" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) type errStreamOrConnLimitExceeded struct { diff --git a/p2p/host/resource-manager/extapi.go b/p2p/host/resource-manager/extapi.go index 92605c82b3..302678e198 100644 --- a/p2p/host/resource-manager/extapi.go +++ b/p2p/host/resource-manager/extapi.go @@ -5,9 +5,9 @@ import ( "sort" "strings" - "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/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // ResourceScopeLimiter is a trait interface that allows you to access scope limits. diff --git a/p2p/host/resource-manager/limit.go b/p2p/host/resource-manager/limit.go index 21dffb7df9..3fd57ff5d1 100644 --- a/p2p/host/resource-manager/limit.go +++ b/p2p/host/resource-manager/limit.go @@ -13,9 +13,9 @@ import ( "encoding/json" "io" - "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/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // Limit is an object that specifies basic resource limits. diff --git a/p2p/host/resource-manager/limit_config_test.go b/p2p/host/resource-manager/limit_config_test.go index 1330d4bf6d..21dede5641 100644 --- a/p2p/host/resource-manager/limit_config_test.go +++ b/p2p/host/resource-manager/limit_config_test.go @@ -6,7 +6,7 @@ import ( "os" "testing" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) diff --git a/p2p/host/resource-manager/limit_defaults.go b/p2p/host/resource-manager/limit_defaults.go index 39980ed82f..e037ca6afb 100644 --- a/p2p/host/resource-manager/limit_defaults.go +++ b/p2p/host/resource-manager/limit_defaults.go @@ -4,8 +4,8 @@ import ( "encoding/json" "math" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/pbnjay/memory" ) @@ -141,7 +141,7 @@ func (cfg *LimitConfig) MarshalJSON() ([]byte, error) { // we want to marshal the encoded peer id encodedPeerMap := make(map[string]BaseLimit, len(cfg.Peer)) for p, v := range cfg.Peer { - encodedPeerMap[peer.Encode(p)] = v + encodedPeerMap[p.String()] = v } type Alias LimitConfig diff --git a/p2p/host/resource-manager/metrics.go b/p2p/host/resource-manager/metrics.go index a875415a21..2f9e6b31b7 100644 --- a/p2p/host/resource-manager/metrics.go +++ b/p2p/host/resource-manager/metrics.go @@ -1,9 +1,9 @@ package rcmgr import ( - "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/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // MetricsReporter is an interface for collecting metrics from resource manager actions diff --git a/p2p/host/resource-manager/rcmgr.go b/p2p/host/resource-manager/rcmgr.go index b2cd18cc7a..03d100a634 100644 --- a/p2p/host/resource-manager/rcmgr.go +++ b/p2p/host/resource-manager/rcmgr.go @@ -7,12 +7,12 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" logging "github.com/ipfs/go-log/v2" + "github.com/multiformats/go-multiaddr" ) var log = logging.Logger("rcmgr") diff --git a/p2p/host/resource-manager/rcmgr_test.go b/p2p/host/resource-manager/rcmgr_test.go index de41cf6bcb..12420ac712 100644 --- a/p2p/host/resource-manager/rcmgr_test.go +++ b/p2p/host/resource-manager/rcmgr_test.go @@ -3,10 +3,11 @@ package rcmgr import ( "testing" - "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/test" + "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/test" + "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/host/resource-manager/scope.go b/p2p/host/resource-manager/scope.go index 2190527248..872f0eb686 100644 --- a/p2p/host/resource-manager/scope.go +++ b/p2p/host/resource-manager/scope.go @@ -5,7 +5,7 @@ import ( "strings" "sync" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) // resources tracks the current state of resource consumption diff --git a/p2p/host/resource-manager/scope_test.go b/p2p/host/resource-manager/scope_test.go index 3743068a30..af192a7bdc 100644 --- a/p2p/host/resource-manager/scope_test.go +++ b/p2p/host/resource-manager/scope_test.go @@ -3,7 +3,7 @@ package rcmgr import ( "testing" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) func checkResources(t *testing.T, rc *resources, st network.ScopeStat) { diff --git a/p2p/host/resource-manager/trace.go b/p2p/host/resource-manager/trace.go index ae871a0a3f..1af71edd7c 100644 --- a/p2p/host/resource-manager/trace.go +++ b/p2p/host/resource-manager/trace.go @@ -11,7 +11,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) type trace struct { diff --git a/p2p/host/routed/routed.go b/p2p/host/routed/routed.go index e783ebeca5..55c8d3474e 100644 --- a/p2p/host/routed/routed.go +++ b/p2p/host/routed/routed.go @@ -5,13 +5,13 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "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" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "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" logging "github.com/ipfs/go-log/v2" diff --git a/p2p/muxer/mplex/conn.go b/p2p/muxer/mplex/conn.go index 1abef546f5..ed4e847e5d 100644 --- a/p2p/muxer/mplex/conn.go +++ b/p2p/muxer/mplex/conn.go @@ -3,7 +3,7 @@ package mplex import ( "context" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mp "github.com/libp2p/go-mplex" ) diff --git a/p2p/muxer/mplex/stream.go b/p2p/muxer/mplex/stream.go index 64b70fbde9..53e9e6daf9 100644 --- a/p2p/muxer/mplex/stream.go +++ b/p2p/muxer/mplex/stream.go @@ -3,7 +3,7 @@ package mplex import ( "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mp "github.com/libp2p/go-mplex" ) diff --git a/p2p/muxer/mplex/transport.go b/p2p/muxer/mplex/transport.go index f24c1cc7ca..b7fbe84c7f 100644 --- a/p2p/muxer/mplex/transport.go +++ b/p2p/muxer/mplex/transport.go @@ -3,7 +3,7 @@ package mplex import ( "net" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mp "github.com/libp2p/go-mplex" ) diff --git a/p2p/muxer/mplex/transport_test.go b/p2p/muxer/mplex/transport_test.go index 1226b5d760..3a7d00faeb 100644 --- a/p2p/muxer/mplex/transport_test.go +++ b/p2p/muxer/mplex/transport_test.go @@ -5,7 +5,7 @@ import ( "net" "testing" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" test "github.com/libp2p/go-libp2p/p2p/muxer/testsuite" ) diff --git a/p2p/muxer/muxer-multistream/multistream.go b/p2p/muxer/muxer-multistream/multistream.go index 1668c0b90b..bf9d41630c 100644 --- a/p2p/muxer/muxer-multistream/multistream.go +++ b/p2p/muxer/muxer-multistream/multistream.go @@ -7,7 +7,7 @@ import ( "net" "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mss "github.com/multiformats/go-multistream" ) diff --git a/p2p/muxer/testsuite/mux.go b/p2p/muxer/testsuite/mux.go index fbfea2c0a1..d77d4073e0 100644 --- a/p2p/muxer/testsuite/mux.go +++ b/p2p/muxer/testsuite/mux.go @@ -16,9 +16,9 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-testing/ci" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) diff --git a/p2p/muxer/yamux/conn.go b/p2p/muxer/yamux/conn.go index 4feff1dea6..30f9f351bb 100644 --- a/p2p/muxer/yamux/conn.go +++ b/p2p/muxer/yamux/conn.go @@ -3,7 +3,7 @@ package yamux import ( "context" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-yamux/v3" ) diff --git a/p2p/muxer/yamux/stream.go b/p2p/muxer/yamux/stream.go index f75e77d659..e6a3a04bcd 100644 --- a/p2p/muxer/yamux/stream.go +++ b/p2p/muxer/yamux/stream.go @@ -3,7 +3,7 @@ package yamux import ( "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-yamux/v3" ) diff --git a/p2p/muxer/yamux/transport.go b/p2p/muxer/yamux/transport.go index 148fb5e992..bba53d7acb 100644 --- a/p2p/muxer/yamux/transport.go +++ b/p2p/muxer/yamux/transport.go @@ -5,7 +5,7 @@ import ( "math" "net" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-yamux/v3" ) diff --git a/p2p/net/conn-security-multistream/ssms.go b/p2p/net/conn-security-multistream/ssms.go index 46bb334a88..595d8dfde6 100644 --- a/p2p/net/conn-security-multistream/ssms.go +++ b/p2p/net/conn-security-multistream/ssms.go @@ -6,8 +6,9 @@ import ( "log" "net" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + mss "github.com/multiformats/go-multistream" ) diff --git a/p2p/net/conn-security-multistream/ssms_test.go b/p2p/net/conn-security-multistream/ssms_test.go index f027d729e1..5aa5db352d 100644 --- a/p2p/net/conn-security-multistream/ssms_test.go +++ b/p2p/net/conn-security-multistream/ssms_test.go @@ -2,19 +2,28 @@ package csms import ( "context" + "crypto/rand" "io" "net" "sync" "testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/sec/insecure" - tnet "github.com/libp2p/go-libp2p-testing/net" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/sec/insecure" "github.com/stretchr/testify/require" ) +func newPeer(t *testing.T) (crypto.PrivKey, peer.ID) { + priv, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + id, err := peer.IDFromPrivateKey(priv) + require.NoError(t, err) + return priv, id +} + type TransportAdapter struct { mux *SSMuxer } @@ -30,13 +39,13 @@ func (sm *TransportAdapter) SecureOutbound(ctx context.Context, insecure net.Con } func TestCommonProto(t *testing.T) { - idA := tnet.RandIdentityOrFatal(t) - idB := tnet.RandIdentityOrFatal(t) + privA, idA := newPeer(t) + privB, idB := newPeer(t) var at, bt SSMuxer - atInsecure := insecure.NewWithIdentity(idA.ID(), idA.PrivateKey()) - btInsecure := insecure.NewWithIdentity(idB.ID(), idB.PrivateKey()) + atInsecure := insecure.NewWithIdentity(idA, privA) + btInsecure := insecure.NewWithIdentity(idB, privB) at.AddTransport("/plaintext/1.0.0", atInsecure) bt.AddTransport("/plaintext/1.1.0", btInsecure) bt.AddTransport("/plaintext/1.0.0", btInsecure) @@ -48,7 +57,7 @@ func TestCommonProto(t *testing.T) { go func() { conn, err := ln.Accept() require.NoError(t, err) - c, err := muxB.SecureInbound(context.Background(), conn, idA.ID()) + c, err := muxB.SecureInbound(context.Background(), conn, idA) require.NoError(t, err) connChan <- c }() @@ -58,29 +67,29 @@ func TestCommonProto(t *testing.T) { cconn, err := net.Dial("tcp", ln.Addr().String()) require.NoError(t, err) - cc, err := muxA.SecureOutbound(context.Background(), cconn, idB.ID()) + cc, err := muxA.SecureOutbound(context.Background(), cconn, idB) require.NoError(t, err) - require.Equal(t, cc.LocalPeer(), idA.ID()) - require.Equal(t, cc.RemotePeer(), idB.ID()) + require.Equal(t, cc.LocalPeer(), idA) + require.Equal(t, cc.RemotePeer(), idB) _, err = cc.Write([]byte("foobar")) require.NoError(t, err) require.NoError(t, cc.Close()) sc := <-connChan - require.Equal(t, sc.LocalPeer(), idB.ID()) - require.Equal(t, sc.RemotePeer(), idA.ID()) + require.Equal(t, sc.LocalPeer(), idB) + require.Equal(t, sc.RemotePeer(), idA) b, err := io.ReadAll(sc) require.NoError(t, err) require.Equal(t, "foobar", string(b)) } func TestNoCommonProto(t *testing.T) { - idA := tnet.RandIdentityOrFatal(t) - idB := tnet.RandIdentityOrFatal(t) + privA, idA := newPeer(t) + privB, idB := newPeer(t) var at, bt SSMuxer - atInsecure := insecure.NewWithIdentity(idA.ID(), idA.PrivateKey()) - btInsecure := insecure.NewWithIdentity(idB.ID(), idB.PrivateKey()) + atInsecure := insecure.NewWithIdentity(idA, privA) + btInsecure := insecure.NewWithIdentity(idB, privB) at.AddTransport("/plaintext/1.0.0", atInsecure) bt.AddTransport("/plaintext/1.1.0", btInsecure) diff --git a/p2p/net/conngater/conngater.go b/p2p/net/conngater/conngater.go index fdfd7aeaa7..bcc927f184 100644 --- a/p2p/net/conngater/conngater.go +++ b/p2p/net/conngater/conngater.go @@ -5,10 +5,10 @@ import ( "net" "sync" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/control" + "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" diff --git a/p2p/net/conngater/conngater_test.go b/p2p/net/conngater/conngater_test.go index 7765e824b6..d60b5e4515 100644 --- a/p2p/net/conngater/conngater_test.go +++ b/p2p/net/conngater/conngater_test.go @@ -5,8 +5,9 @@ import ( "testing" "github.com/ipfs/go-datastore" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/connmgr/bench_test.go b/p2p/net/connmgr/bench_test.go index 73e25e97c5..83442f9162 100644 --- a/p2p/net/connmgr/bench_test.go +++ b/p2p/net/connmgr/bench_test.go @@ -5,7 +5,7 @@ import ( "sync" "testing" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/connmgr/connmgr.go b/p2p/net/connmgr/connmgr.go index b73e3a71d5..22b83c44eb 100644 --- a/p2p/net/connmgr/connmgr.go +++ b/p2p/net/connmgr/connmgr.go @@ -7,9 +7,9 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/net/connmgr/connmgr_test.go b/p2p/net/connmgr/connmgr_test.go index d70ec363e1..c2db206cb4 100644 --- a/p2p/net/connmgr/connmgr_test.go +++ b/p2p/net/connmgr/connmgr_test.go @@ -7,14 +7,12 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + tu "github.com/libp2p/go-libp2p/core/test" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - - tu "github.com/libp2p/go-libp2p-core/test" ma "github.com/multiformats/go-multiaddr" - "github.com/stretchr/testify/require" ) diff --git a/p2p/net/connmgr/decay.go b/p2p/net/connmgr/decay.go index 58e34a083d..9841c2f1fa 100644 --- a/p2p/net/connmgr/decay.go +++ b/p2p/net/connmgr/decay.go @@ -6,8 +6,8 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/peer" "github.com/benbjohnson/clock" ) diff --git a/p2p/net/connmgr/decay_test.go b/p2p/net/connmgr/decay_test.go index c271a1da56..bd28b32690 100644 --- a/p2p/net/connmgr/decay_test.go +++ b/p2p/net/connmgr/decay_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/peer" - tu "github.com/libp2p/go-libp2p-core/test" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/peer" + tu "github.com/libp2p/go-libp2p/core/test" "github.com/benbjohnson/clock" "github.com/stretchr/testify/require" diff --git a/p2p/net/mock/complement.go b/p2p/net/mock/complement.go index 4a8b251da0..d0162ca420 100644 --- a/p2p/net/mock/complement.go +++ b/p2p/net/mock/complement.go @@ -1,7 +1,7 @@ package mocknet import ( - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) // StreamComplement returns the other end of the given stream. This function diff --git a/p2p/net/mock/interface.go b/p2p/net/mock/interface.go index 68dee445e4..d89342b009 100644 --- a/p2p/net/mock/interface.go +++ b/p2p/net/mock/interface.go @@ -10,11 +10,11 @@ import ( "io" "time" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/mock/mock_conn.go b/p2p/net/mock/mock_conn.go index dae0867d57..5664fabb61 100644 --- a/p2p/net/mock/mock_conn.go +++ b/p2p/net/mock/mock_conn.go @@ -7,9 +7,9 @@ import ( "sync" "sync/atomic" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + ic "github.com/libp2p/go-libp2p/core/crypto" + "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" ) diff --git a/p2p/net/mock/mock_link.go b/p2p/net/mock/mock_link.go index fe65398e1c..47bf9a3f13 100644 --- a/p2p/net/mock/mock_link.go +++ b/p2p/net/mock/mock_link.go @@ -4,8 +4,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // link implements mocknet.Link diff --git a/p2p/net/mock/mock_net.go b/p2p/net/mock/mock_net.go index 9ec54d5436..21d214eccb 100644 --- a/p2p/net/mock/mock_net.go +++ b/p2p/net/mock/mock_net.go @@ -8,12 +8,11 @@ import ( "sort" "sync" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" diff --git a/p2p/net/mock/mock_notif_test.go b/p2p/net/mock/mock_notif_test.go index 7b038f534f..600e0af275 100644 --- a/p2p/net/mock/mock_notif_test.go +++ b/p2p/net/mock/mock_notif_test.go @@ -6,10 +6,10 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/mock/mock_peernet.go b/p2p/net/mock/mock_peernet.go index d633c741f3..2e931a660d 100644 --- a/p2p/net/mock/mock_peernet.go +++ b/p2p/net/mock/mock_peernet.go @@ -7,9 +7,9 @@ import ( "math/rand" "sync" - "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/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/mock/mock_printer.go b/p2p/net/mock/mock_printer.go index 344560e06b..33e1b965ff 100644 --- a/p2p/net/mock/mock_printer.go +++ b/p2p/net/mock/mock_printer.go @@ -4,8 +4,8 @@ import ( "fmt" "io" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // separate object so our interfaces are separate :) diff --git a/p2p/net/mock/mock_stream.go b/p2p/net/mock/mock_stream.go index 0d386b498c..61303daba5 100644 --- a/p2p/net/mock/mock_stream.go +++ b/p2p/net/mock/mock_stream.go @@ -9,8 +9,8 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" ) var streamCounter int64 diff --git a/p2p/net/mock/mock_test.go b/p2p/net/mock/mock_test.go index f99d82c9db..2acee646eb 100644 --- a/p2p/net/mock/mock_test.go +++ b/p2p/net/mock/mock_test.go @@ -3,48 +3,85 @@ package mocknet import ( "bytes" "context" + "crypto/rand" + "fmt" "io" "math" "sync" "testing" "time" - "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/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-testing/ci" - tnet "github.com/libp2p/go-libp2p-testing/net" + tetc "github.com/libp2p/go-libp2p-testing/etc" "github.com/libp2p/go-libp2p-testing/race" + ma "github.com/multiformats/go-multiaddr" + "github.com/stretchr/testify/require" ) +var lastPort = struct { + port int + sync.Mutex +}{} + +// randLocalTCPAddress returns a random multiaddr. it suppresses errors +// for nice composability-- do check the address isn't nil. +// +// NOTE: for real network tests, use a :0 address, so the kernel +// assigns an unused TCP port. otherwise you may get clashes. +func randLocalTCPAddress() ma.Multiaddr { + // chances are it will work out, but it **might** fail if the port is in use + // most ports above 10000 aren't in use by long running processes, so yay. + // (maybe there should be a range of "loopback" ports that are guaranteed + // to be open for the process, but naturally can only talk to self.) + + lastPort.Lock() + if lastPort.port == 0 { + lastPort.port = 10000 + tetc.SeededRand.Intn(50000) + } + port := lastPort.port + lastPort.port++ + lastPort.Unlock() + + addr := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", port) + maddr, _ := ma.NewMultiaddr(addr) + return maddr +} + func TestNetworkSetup(t *testing.T) { ctx := context.Background() - id1 := tnet.RandIdentityOrFatal(t) - id2 := tnet.RandIdentityOrFatal(t) - id3 := tnet.RandIdentityOrFatal(t) + priv1, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + priv2, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + priv3, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) mn := New() defer mn.Close() // add peers to mock net - a1 := tnet.RandLocalTCPAddress() - a2 := tnet.RandLocalTCPAddress() - a3 := tnet.RandLocalTCPAddress() + a1 := randLocalTCPAddress() + a2 := randLocalTCPAddress() + a3 := randLocalTCPAddress() - h1, err := mn.AddPeer(id1.PrivateKey(), a1) + h1, err := mn.AddPeer(priv1, a1) if err != nil { t.Fatal(err) } p1 := h1.ID() - h2, err := mn.AddPeer(id2.PrivateKey(), a2) + h2, err := mn.AddPeer(priv2, a2) if err != nil { t.Fatal(err) } p2 := h2.ID() - h3, err := mn.AddPeer(id3.PrivateKey(), a3) + h3, err := mn.AddPeer(priv3, a3) if err != nil { t.Fatal(err) } @@ -315,10 +352,12 @@ func TestAdding(t *testing.T) { var peers []peer.ID for i := 0; i < 3; i++ { - id := tnet.RandIdentityOrFatal(t) - - a := tnet.RandLocalTCPAddress() - h, err := mn.AddPeer(id.PrivateKey(), a) + priv, _, err := crypto.GenerateEd25519Key(rand.Reader) + if err != nil { + t.Fatal(err) + } + a := randLocalTCPAddress() + h, err := mn.AddPeer(priv, a) if err != nil { t.Fatal(err) } diff --git a/p2p/net/pnet/protector.go b/p2p/net/pnet/protector.go index ed63a690be..643e904d29 100644 --- a/p2p/net/pnet/protector.go +++ b/p2p/net/pnet/protector.go @@ -4,7 +4,7 @@ import ( "errors" "net" - ipnet "github.com/libp2p/go-libp2p-core/pnet" + ipnet "github.com/libp2p/go-libp2p/core/pnet" ) // NewProtectedConn creates a new protected connection diff --git a/p2p/net/pnet/psk_conn.go b/p2p/net/pnet/psk_conn.go index 5d35d8794c..c600c8d093 100644 --- a/p2p/net/pnet/psk_conn.go +++ b/p2p/net/pnet/psk_conn.go @@ -6,7 +6,7 @@ import ( "io" "net" - "github.com/libp2p/go-libp2p-core/pnet" + "github.com/libp2p/go-libp2p/core/pnet" "github.com/davidlazar/go-crypto/salsa20" pool "github.com/libp2p/go-buffer-pool" diff --git a/p2p/net/swarm/dial_error.go b/p2p/net/swarm/dial_error.go index f2986348bf..711ee06072 100644 --- a/p2p/net/swarm/dial_error.go +++ b/p2p/net/swarm/dial_error.go @@ -5,7 +5,7 @@ import ( "os" "strings" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/swarm/dial_sync.go b/p2p/net/swarm/dial_sync.go index f24ecd3c41..2a8ff43176 100644 --- a/p2p/net/swarm/dial_sync.go +++ b/p2p/net/swarm/dial_sync.go @@ -4,8 +4,8 @@ import ( "context" "sync" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // dialWorkerFunc is used by dialSync to spawn a new dial worker diff --git a/p2p/net/swarm/dial_sync_test.go b/p2p/net/swarm/dial_sync_test.go index 976f460904..e2b8e88dac 100644 --- a/p2p/net/swarm/dial_sync_test.go +++ b/p2p/net/swarm/dial_sync_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/dial_test.go b/p2p/net/swarm/dial_test.go index bda5546f71..aed15d4ad3 100644 --- a/p2p/net/swarm/dial_test.go +++ b/p2p/net/swarm/dial_test.go @@ -7,18 +7,17 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + testutil "github.com/libp2p/go-libp2p/core/test" . "github.com/libp2p/go-libp2p/p2p/net/swarm" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - testutil "github.com/libp2p/go-libp2p-core/test" - "github.com/libp2p/go-libp2p-testing/ci" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" - "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/dial_worker.go b/p2p/net/swarm/dial_worker.go index cf9dfe5923..ff339d2f2b 100644 --- a/p2p/net/swarm/dial_worker.go +++ b/p2p/net/swarm/dial_worker.go @@ -4,8 +4,8 @@ import ( "context" "sync" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "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" diff --git a/p2p/net/swarm/dial_worker_test.go b/p2p/net/swarm/dial_worker_test.go index 80235a7491..bf7a5ca3ad 100644 --- a/p2p/net/swarm/dial_worker_test.go +++ b/p2p/net/swarm/dial_worker_test.go @@ -2,12 +2,18 @@ package swarm import ( "context" + "crypto/rand" "errors" "fmt" "sync" "testing" "time" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/sec/insecure" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" msmux "github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" @@ -16,26 +22,28 @@ import ( quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/sec/insecure" - "github.com/libp2p/go-libp2p-core/transport" - - tnet "github.com/libp2p/go-libp2p-testing/net" ma "github.com/multiformats/go-multiaddr" - "github.com/stretchr/testify/require" ) +func newPeer(t *testing.T) (crypto.PrivKey, peer.ID) { + priv, _, err := crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) + id, err := peer.IDFromPrivateKey(priv) + require.NoError(t, err) + return priv, id +} + func makeSwarm(t *testing.T) *Swarm { - p := tnet.RandPeerNetParamsOrFatal(t) + priv, id := newPeer(t) ps, err := pstoremem.NewPeerstore() require.NoError(t, err) - ps.AddPubKey(p.ID, p.PubKey) - ps.AddPrivKey(p.ID, p.PrivKey) + ps.AddPubKey(id, priv.GetPublic()) + ps.AddPrivKey(id, priv) t.Cleanup(func() { ps.Close() }) - s, err := NewSwarm(p.ID, ps, WithDialTimeout(time.Second)) + s, err := NewSwarm(id, ps, WithDialTimeout(time.Second)) require.NoError(t, err) upgrader := makeUpgrader(t, s) @@ -47,11 +55,11 @@ func makeSwarm(t *testing.T) *Swarm { if err := s.AddTransport(tcpTransport); err != nil { t.Fatal(err) } - if err := s.Listen(p.Addr); err != nil { + if err := s.Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0")); err != nil { t.Fatal(err) } - quicTransport, err := quic.NewTransport(p.PrivKey, nil, nil, nil) + quicTransport, err := quic.NewTransport(priv, nil, nil, nil) if err != nil { t.Fatal(err) } @@ -171,13 +179,13 @@ func TestDialWorkerLoopFailure(t *testing.T) { s1 := makeSwarm(t) defer s1.Close() - p2 := tnet.RandPeerNetParamsOrFatal(t) + _, p2 := newPeer(t) - s1.Peerstore().AddAddrs(p2.ID, []ma.Multiaddr{ma.StringCast("/ip4/11.0.0.1/tcp/1234"), ma.StringCast("/ip4/11.0.0.1/udp/1234/quic")}, peerstore.PermanentAddrTTL) + s1.Peerstore().AddAddrs(p2, []ma.Multiaddr{ma.StringCast("/ip4/11.0.0.1/tcp/1234"), ma.StringCast("/ip4/11.0.0.1/udp/1234/quic")}, peerstore.PermanentAddrTTL) reqch := make(chan dialRequest) resch := make(chan dialResponse) - worker := newDialWorker(s1, p2.ID, reqch) + worker := newDialWorker(s1, p2, reqch) go worker.loop() reqch <- dialRequest{ctx: context.Background(), resch: resch} @@ -196,12 +204,12 @@ func TestDialWorkerLoopConcurrentFailure(t *testing.T) { s1 := makeSwarm(t) defer s1.Close() - p2 := tnet.RandPeerNetParamsOrFatal(t) + _, p2 := newPeer(t) - s1.Peerstore().AddAddrs(p2.ID, []ma.Multiaddr{ma.StringCast("/ip4/11.0.0.1/tcp/1234"), ma.StringCast("/ip4/11.0.0.1/udp/1234/quic")}, peerstore.PermanentAddrTTL) + s1.Peerstore().AddAddrs(p2, []ma.Multiaddr{ma.StringCast("/ip4/11.0.0.1/tcp/1234"), ma.StringCast("/ip4/11.0.0.1/udp/1234/quic")}, peerstore.PermanentAddrTTL) reqch := make(chan dialRequest) - worker := newDialWorker(s1, p2.ID, reqch) + worker := newDialWorker(s1, p2, reqch) go worker.loop() const dials = 100 @@ -286,16 +294,16 @@ func TestDialWorkerLoopConcurrentFailureStress(t *testing.T) { s1 := makeSwarm(t) defer s1.Close() - p2 := tnet.RandPeerNetParamsOrFatal(t) + _, p2 := newPeer(t) var addrs []ma.Multiaddr for i := 0; i < 16; i++ { addrs = append(addrs, ma.StringCast(fmt.Sprintf("/ip4/11.0.0.%d/tcp/%d", i%256, 1234+i))) } - s1.Peerstore().AddAddrs(p2.ID, addrs, peerstore.PermanentAddrTTL) + s1.Peerstore().AddAddrs(p2, addrs, peerstore.PermanentAddrTTL) reqch := make(chan dialRequest) - worker := newDialWorker(s1, p2.ID, reqch) + worker := newDialWorker(s1, p2, reqch) go worker.loop() const dials = 100 diff --git a/p2p/net/swarm/limiter.go b/p2p/net/swarm/limiter.go index 6b49d8ec0b..ccfe7d2371 100644 --- a/p2p/net/swarm/limiter.go +++ b/p2p/net/swarm/limiter.go @@ -7,8 +7,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/swarm/limiter_test.go b/p2p/net/swarm/limiter_test.go index 47918ce565..046b4c754e 100644 --- a/p2p/net/swarm/limiter_test.go +++ b/p2p/net/swarm/limiter_test.go @@ -10,9 +10,9 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/test" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/test" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" diff --git a/p2p/net/swarm/peers_test.go b/p2p/net/swarm/peers_test.go index a2d8f820e2..44f1309f75 100644 --- a/p2p/net/swarm/peers_test.go +++ b/p2p/net/swarm/peers_test.go @@ -5,13 +5,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" . "github.com/libp2p/go-libp2p/p2p/net/swarm" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - ma "github.com/multiformats/go-multiaddr" - "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/simul_test.go b/p2p/net/swarm/simul_test.go index 5f3d6d34ae..33026d0e11 100644 --- a/p2p/net/swarm/simul_test.go +++ b/p2p/net/swarm/simul_test.go @@ -7,12 +7,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" . "github.com/libp2p/go-libp2p/p2p/net/swarm" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-testing/ci" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/swarm/swarm.go b/p2p/net/swarm/swarm.go index 532ae24451..80d67eb979 100644 --- a/p2p/net/swarm/swarm.go +++ b/p2p/net/swarm/swarm.go @@ -10,12 +10,12 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/metrics" - "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/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/metrics" + "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/transport" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/net/swarm/swarm_addr_test.go b/p2p/net/swarm/swarm_addr_test.go index 2bdc1ba3ae..af98400a4e 100644 --- a/p2p/net/swarm/swarm_addr_test.go +++ b/p2p/net/swarm/swarm_addr_test.go @@ -4,11 +4,10 @@ import ( "context" "testing" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/test" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/test" - ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/swarm_conn.go b/p2p/net/swarm/swarm_conn.go index 64fb2ed5df..779ee37374 100644 --- a/p2p/net/swarm/swarm_conn.go +++ b/p2p/net/swarm/swarm_conn.go @@ -8,10 +8,10 @@ import ( "sync/atomic" "time" - ic "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/transport" + ic "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/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/swarm/swarm_dial.go b/p2p/net/swarm/swarm_dial.go index b6f0625637..0e232a1881 100644 --- a/p2p/net/swarm/swarm_dial.go +++ b/p2p/net/swarm/swarm_dial.go @@ -7,10 +7,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -403,7 +403,7 @@ func (s *Swarm) dialAddr(ctx context.Context, p peer.ID, addr ma.Multiaddr) (tra return connC, nil } -// TODO We should have a `IsFdConsuming() bool` method on the `Transport` interface in go-libp2p-core/transport. +// TODO We should have a `IsFdConsuming() bool` method on the `Transport` interface in go-libp2p/core/transport. // This function checks if any of the transport protocols in the address requires a file descriptor. // For now: // A Non-circuit address which has the TCP/UNIX protocol is deemed FD consuming. diff --git a/p2p/net/swarm/swarm_listen.go b/p2p/net/swarm/swarm_listen.go index 9159c55960..044da2e8de 100644 --- a/p2p/net/swarm/swarm_listen.go +++ b/p2p/net/swarm/swarm_listen.go @@ -4,9 +4,9 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/swarm/swarm_net_test.go b/p2p/net/swarm/swarm_net_test.go index 1626f5e95c..1dbdc57bcc 100644 --- a/p2p/net/swarm/swarm_net_test.go +++ b/p2p/net/swarm/swarm_net_test.go @@ -7,10 +7,9 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" . "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/network" - "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/swarm_notif_test.go b/p2p/net/swarm/swarm_notif_test.go index ba4609d2fb..0b6d56122e 100644 --- a/p2p/net/swarm/swarm_notif_test.go +++ b/p2p/net/swarm/swarm_notif_test.go @@ -5,11 +5,10 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" . "github.com/libp2p/go-libp2p/p2p/net/swarm" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" diff --git a/p2p/net/swarm/swarm_stream.go b/p2p/net/swarm/swarm_stream.go index 109cce5800..7a5bb27503 100644 --- a/p2p/net/swarm/swarm_stream.go +++ b/p2p/net/swarm/swarm_stream.go @@ -6,8 +6,8 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" ) // Validate Stream conforms to the go-libp2p-net Stream interface diff --git a/p2p/net/swarm/swarm_test.go b/p2p/net/swarm/swarm_test.go index a5e193f03d..f25ee1f1c8 100644 --- a/p2p/net/swarm/swarm_test.go +++ b/p2p/net/swarm/swarm_test.go @@ -11,22 +11,19 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/protocol" - + "github.com/libp2p/go-libp2p/core/control" + "github.com/libp2p/go-libp2p/core/network" + mocknetwork "github.com/libp2p/go-libp2p/core/network/mocks" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-libp2p/p2p/net/swarm" . "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - + "github.com/golang/mock/gomock" logging "github.com/ipfs/go-log/v2" - mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" - - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/swarm_transport.go b/p2p/net/swarm/swarm_transport.go index 21728ac3b5..96a3a8e2cd 100644 --- a/p2p/net/swarm/swarm_transport.go +++ b/p2p/net/swarm/swarm_transport.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/swarm/testing/testing.go b/p2p/net/swarm/testing/testing.go index b250fff567..c3704e5d28 100644 --- a/p2p/net/swarm/testing/testing.go +++ b/p2p/net/swarm/testing/testing.go @@ -1,9 +1,19 @@ package testing import ( + "crypto/rand" "testing" "time" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/control" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/metrics" + "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/sec/insecure" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" msmux "github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" @@ -13,17 +23,6 @@ import ( quic "github.com/libp2p/go-libp2p/p2p/transport/quic" "github.com/libp2p/go-libp2p/p2p/transport/tcp" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/metrics" - "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/sec/insecure" - "github.com/libp2p/go-libp2p-core/transport" - - tnet "github.com/libp2p/go-libp2p-testing/net" ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) @@ -128,25 +127,21 @@ func GenSwarm(t *testing.T, opts ...Option) *swarm.Swarm { o(t, &cfg) } - var p tnet.PeerNetParams + var priv crypto.PrivKey if cfg.sk == nil { - p = tnet.RandPeerNetParamsOrFatal(t) + var err error + priv, _, err = crypto.GenerateEd25519Key(rand.Reader) + require.NoError(t, err) } else { - pk := cfg.sk.GetPublic() - id, err := peer.IDFromPublicKey(pk) - if err != nil { - t.Fatal(err) - } - p.PrivKey = cfg.sk - p.PubKey = pk - p.ID = id - p.Addr = tnet.ZeroLocalTCPAddress + priv = cfg.sk } + id, err := peer.IDFromPrivateKey(priv) + require.NoError(t, err) ps, err := pstoremem.NewPeerstore(pstoremem.WithClock(cfg.clock)) require.NoError(t, err) - ps.AddPubKey(p.ID, p.PubKey) - ps.AddPrivKey(p.ID, p.PrivKey) + ps.AddPubKey(id, priv.GetPublic()) + ps.AddPrivKey(id, priv) t.Cleanup(func() { ps.Close() }) swarmOpts := []swarm.Option{swarm.WithMetrics(metrics.NewBandwidthCounter())} @@ -159,7 +154,7 @@ func GenSwarm(t *testing.T, opts ...Option) *swarm.Swarm { if cfg.dialTimeout != 0 { swarmOpts = append(swarmOpts, swarm.WithDialTimeout(cfg.dialTimeout)) } - s, err := swarm.NewSwarm(p.ID, ps, swarmOpts...) + s, err := swarm.NewSwarm(id, ps, swarmOpts...) require.NoError(t, err) upgrader := GenUpgrader(t, s, tptu.WithConnectionGater(cfg.connectionGater)) @@ -175,13 +170,13 @@ func GenSwarm(t *testing.T, opts ...Option) *swarm.Swarm { t.Fatal(err) } if !cfg.dialOnly { - if err := s.Listen(p.Addr); err != nil { + if err := s.Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0")); err != nil { t.Fatal(err) } } } if !cfg.disableQUIC { - quicTransport, err := quic.NewTransport(p.PrivKey, nil, cfg.connectionGater, nil) + quicTransport, err := quic.NewTransport(priv, nil, cfg.connectionGater, nil) if err != nil { t.Fatal(err) } @@ -195,7 +190,7 @@ func GenSwarm(t *testing.T, opts ...Option) *swarm.Swarm { } } if !cfg.dialOnly { - s.Peerstore().AddAddrs(p.ID, s.ListenAddresses(), peerstore.PermanentAddrTTL) + s.Peerstore().AddAddrs(id, s.ListenAddresses(), peerstore.PermanentAddrTTL) } return s } diff --git a/p2p/net/swarm/transport_test.go b/p2p/net/swarm/transport_test.go index 3c863b23e7..fe7434753e 100644 --- a/p2p/net/swarm/transport_test.go +++ b/p2p/net/swarm/transport_test.go @@ -4,14 +4,12 @@ import ( "context" "testing" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/net/swarm" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - ma "github.com/multiformats/go-multiaddr" - "github.com/stretchr/testify/require" ) diff --git a/p2p/net/swarm/util_test.go b/p2p/net/swarm/util_test.go index 11124adb27..66246b554e 100644 --- a/p2p/net/swarm/util_test.go +++ b/p2p/net/swarm/util_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/libp2p/go-libp2p-core/test" - ma "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/test" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/upgrader/conn.go b/p2p/net/upgrader/conn.go index 4ee0edc407..2fa7af64be 100644 --- a/p2p/net/upgrader/conn.go +++ b/p2p/net/upgrader/conn.go @@ -3,8 +3,8 @@ package upgrader import ( "fmt" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/transport" ) type transportConn struct { diff --git a/p2p/net/upgrader/gater_test.go b/p2p/net/upgrader/gater_test.go index 2d6b889058..72b1d8fc0f 100644 --- a/p2p/net/upgrader/gater_test.go +++ b/p2p/net/upgrader/gater_test.go @@ -3,10 +3,10 @@ package upgrader_test import ( "sync" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/control" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/net/upgrader/listener.go b/p2p/net/upgrader/listener.go index 5e289a6701..c07299c1a5 100644 --- a/p2p/net/upgrader/listener.go +++ b/p2p/net/upgrader/listener.go @@ -5,8 +5,8 @@ import ( "fmt" "sync" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/transport" logging "github.com/ipfs/go-log/v2" tec "github.com/jbenet/go-temp-err-catcher" diff --git a/p2p/net/upgrader/listener_test.go b/p2p/net/upgrader/listener_test.go index 929df0bb17..82c3952ef8 100644 --- a/p2p/net/upgrader/listener_test.go +++ b/p2p/net/upgrader/listener_test.go @@ -11,18 +11,16 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" + mocknetwork "github.com/libp2p/go-libp2p/core/network/mocks" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/net/upgrader" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" - - mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network" + "github.com/golang/mock/gomock" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" - - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/p2p/net/upgrader/upgrader.go b/p2p/net/upgrader/upgrader.go index 4f8e712254..58347865a5 100644 --- a/p2p/net/upgrader/upgrader.go +++ b/p2p/net/upgrader/upgrader.go @@ -7,15 +7,14 @@ import ( "net" "time" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + ipnet "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/net/pnet" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ipnet "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" - manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/net/upgrader/upgrader_test.go b/p2p/net/upgrader/upgrader_test.go index be201eca60..5d62e5f9c2 100644 --- a/p2p/net/upgrader/upgrader_test.go +++ b/p2p/net/upgrader/upgrader_test.go @@ -6,21 +6,18 @@ import ( "net" "testing" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + mocknetwork "github.com/libp2p/go-libp2p/core/network/mocks" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec/insecure" + "github.com/libp2p/go-libp2p/core/test" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" "github.com/libp2p/go-libp2p/p2p/net/upgrader" - "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/sec/insecure" - "github.com/libp2p/go-libp2p-core/test" - "github.com/libp2p/go-libp2p-core/transport" - - mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network" - "github.com/golang/mock/gomock" ma "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" ) diff --git a/p2p/protocol/circuitv1/relay/options.go b/p2p/protocol/circuitv1/relay/options.go index 22e0478217..bfd2ed895f 100644 --- a/p2p/protocol/circuitv1/relay/options.go +++ b/p2p/protocol/circuitv1/relay/options.go @@ -1,7 +1,7 @@ package relay import ( - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) type Resources struct { diff --git a/p2p/protocol/circuitv1/relay/relay.go b/p2p/protocol/circuitv1/relay/relay.go index 3c626bd00f..3b6f7adc85 100644 --- a/p2p/protocol/circuitv1/relay/relay.go +++ b/p2p/protocol/circuitv1/relay/relay.go @@ -8,13 +8,12 @@ import ( "sync/atomic" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - logging "github.com/ipfs/go-log/v2" pool "github.com/libp2p/go-buffer-pool" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/protocol/circuitv2/client/client.go b/p2p/protocol/circuitv2/client/client.go index bdd9bf9eb8..aa302e7e16 100644 --- a/p2p/protocol/circuitv2/client/client.go +++ b/p2p/protocol/circuitv2/client/client.go @@ -5,12 +5,11 @@ import ( "io" "sync" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - logging "github.com/ipfs/go-log/v2" ) diff --git a/p2p/protocol/circuitv2/client/conn.go b/p2p/protocol/circuitv2/client/conn.go index fcca1bea26..23bde93d5e 100644 --- a/p2p/protocol/circuitv2/client/conn.go +++ b/p2p/protocol/circuitv2/client/conn.go @@ -5,8 +5,8 @@ import ( "net" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "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" diff --git a/p2p/protocol/circuitv2/client/dial.go b/p2p/protocol/circuitv2/client/dial.go index 4a1e0e6ea6..2e5fc73b5d 100644 --- a/p2p/protocol/circuitv2/client/dial.go +++ b/p2p/protocol/circuitv2/client/dial.go @@ -5,15 +5,14 @@ import ( "fmt" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/client/handlers.go b/p2p/protocol/circuitv2/client/handlers.go index fa338f8f45..ef50b8e826 100644 --- a/p2p/protocol/circuitv2/client/handlers.go +++ b/p2p/protocol/circuitv2/client/handlers.go @@ -3,11 +3,10 @@ package client import ( "time" + "github.com/libp2p/go-libp2p/core/network" pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - - "github.com/libp2p/go-libp2p-core/network" ) var ( diff --git a/p2p/protocol/circuitv2/client/reservation.go b/p2p/protocol/circuitv2/client/reservation.go index aebcfe74c6..1cd451ad13 100644 --- a/p2p/protocol/circuitv2/client/reservation.go +++ b/p2p/protocol/circuitv2/client/reservation.go @@ -5,15 +5,14 @@ import ( "fmt" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/client/reservation_test.go b/p2p/protocol/circuitv2/client/reservation_test.go index f2df0abd6c..c1abcc1155 100644 --- a/p2p/protocol/circuitv2/client/reservation_test.go +++ b/p2p/protocol/circuitv2/client/reservation_test.go @@ -7,14 +7,13 @@ import ( "time" "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/require" ) diff --git a/p2p/protocol/circuitv2/client/transport.go b/p2p/protocol/circuitv2/client/transport.go index cd1c302d3a..97fc1ce1a2 100644 --- a/p2p/protocol/circuitv2/client/transport.go +++ b/p2p/protocol/circuitv2/client/transport.go @@ -5,11 +5,10 @@ import ( "fmt" "io" - "github.com/libp2p/go-libp2p-core/network" - - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/proto/voucher.go b/p2p/protocol/circuitv2/proto/voucher.go index fe8e3aeece..fd50fccce6 100644 --- a/p2p/protocol/circuitv2/proto/voucher.go +++ b/p2p/protocol/circuitv2/proto/voucher.go @@ -3,10 +3,9 @@ package proto import ( "time" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" - - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" ) const RecordDomain = "libp2p-relay-rsvp" diff --git a/p2p/protocol/circuitv2/proto/voucher_test.go b/p2p/protocol/circuitv2/proto/voucher_test.go index 148bd77a9b..643dd0a5df 100644 --- a/p2p/protocol/circuitv2/proto/voucher_test.go +++ b/p2p/protocol/circuitv2/proto/voucher_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" ) func TestReservationVoucher(t *testing.T) { diff --git a/p2p/protocol/circuitv2/relay/acl.go b/p2p/protocol/circuitv2/relay/acl.go index 0501051327..4191556a35 100644 --- a/p2p/protocol/circuitv2/relay/acl.go +++ b/p2p/protocol/circuitv2/relay/acl.go @@ -1,7 +1,7 @@ package relay import ( - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/relay/compat_test.go b/p2p/protocol/circuitv2/relay/compat_test.go index 88252f0110..693803f598 100644 --- a/p2p/protocol/circuitv2/relay/compat_test.go +++ b/p2p/protocol/circuitv2/relay/compat_test.go @@ -7,14 +7,13 @@ import ( "io" "testing" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" compatv1 "github.com/libp2p/go-libp2p/p2p/protocol/internal/circuitv1-deprecated" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/relay/constraints.go b/p2p/protocol/circuitv2/relay/constraints.go index 1b0087ec89..24353086f6 100644 --- a/p2p/protocol/circuitv2/relay/constraints.go +++ b/p2p/protocol/circuitv2/relay/constraints.go @@ -6,7 +6,8 @@ import ( "time" asnutil "github.com/libp2p/go-libp2p-asn-util" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/protocol/circuitv2/relay/constraints_test.go b/p2p/protocol/circuitv2/relay/constraints_test.go index 0eaaa680d1..352fe22405 100644 --- a/p2p/protocol/circuitv2/relay/constraints_test.go +++ b/p2p/protocol/circuitv2/relay/constraints_test.go @@ -8,7 +8,8 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p-core/test" + "github.com/libp2p/go-libp2p/core/test" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/relay/relay.go b/p2p/protocol/circuitv2/relay/relay.go index 2ff153f344..5e2d9f1835 100644 --- a/p2p/protocol/circuitv2/relay/relay.go +++ b/p2p/protocol/circuitv2/relay/relay.go @@ -8,15 +8,14 @@ import ( "sync/atomic" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" - logging "github.com/ipfs/go-log/v2" pool "github.com/libp2p/go-buffer-pool" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/protocol/circuitv2/relay/relay_test.go b/p2p/protocol/circuitv2/relay/relay_test.go index 78ed022cb3..33a850167d 100644 --- a/p2p/protocol/circuitv2/relay/relay_test.go +++ b/p2p/protocol/circuitv2/relay/relay_test.go @@ -9,6 +9,12 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/metrics" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" bhost "github.com/libp2p/go-libp2p/p2p/host/blank" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" "github.com/libp2p/go-libp2p/p2p/net/swarm" @@ -17,13 +23,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" "github.com/libp2p/go-libp2p/p2p/transport/tcp" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/circuitv2/util/pbconv.go b/p2p/protocol/circuitv2/util/pbconv.go index a5b73f6288..ae1b9b50b3 100644 --- a/p2p/protocol/circuitv2/util/pbconv.go +++ b/p2p/protocol/circuitv2/util/pbconv.go @@ -3,11 +3,10 @@ package util import ( "errors" + "github.com/libp2p/go-libp2p/core/peer" pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/holepunch/holepunch_test.go b/p2p/protocol/holepunch/holepunch_test.go index d4f68adb9e..5c364ff013 100644 --- a/p2p/protocol/holepunch/holepunch_test.go +++ b/p2p/protocol/holepunch/holepunch_test.go @@ -7,25 +7,21 @@ import ( "testing" "time" - "github.com/libp2p/go-libp2p/p2p/host/autorelay" - "github.com/libp2p/go-libp2p" - - "github.com/libp2p/go-libp2p-core/host" - "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-testing/race" - + "github.com/libp2p/go-libp2p/core/host" + "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/p2p/host/autorelay" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" "github.com/libp2p/go-libp2p/p2p/protocol/holepunch" holepunch_pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - "github.com/libp2p/go-msgio/protoio" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" - "github.com/stretchr/testify/require" ) diff --git a/p2p/protocol/holepunch/holepuncher.go b/p2p/protocol/holepunch/holepuncher.go index 810608f204..7f2bbbd121 100644 --- a/p2p/protocol/holepunch/holepuncher.go +++ b/p2p/protocol/holepunch/holepuncher.go @@ -7,13 +7,12 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-msgio/protoio" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/protocol/holepunch/svc.go b/p2p/protocol/holepunch/svc.go index 3bfff1dd75..1df779fc37 100644 --- a/p2p/protocol/holepunch/svc.go +++ b/p2p/protocol/holepunch/svc.go @@ -7,15 +7,14 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-msgio/protoio" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/protocol/holepunch/tracer.go b/p2p/protocol/holepunch/tracer.go index 1512ba103d..87aa61367e 100644 --- a/p2p/protocol/holepunch/tracer.go +++ b/p2p/protocol/holepunch/tracer.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/holepunch/util.go b/p2p/protocol/holepunch/util.go index af70775704..825f855ee8 100644 --- a/p2p/protocol/holepunch/util.go +++ b/p2p/protocol/holepunch/util.go @@ -3,9 +3,10 @@ package holepunch import ( "context" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "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" ) diff --git a/p2p/protocol/identify/id.go b/p2p/protocol/identify/id.go index 8e520deace..4794619d9a 100644 --- a/p2p/protocol/identify/id.go +++ b/p2p/protocol/identify/id.go @@ -7,13 +7,13 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "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/record" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "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/record" "github.com/libp2p/go-libp2p/p2p/host/eventbus" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" diff --git a/p2p/protocol/identify/id_delta.go b/p2p/protocol/identify/id_delta.go index 467a101dee..7f7c75f12d 100644 --- a/p2p/protocol/identify/id_delta.go +++ b/p2p/protocol/identify/id_delta.go @@ -3,11 +3,10 @@ package identify import ( "time" - "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/protocol" - + "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/protocol" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" "github.com/libp2p/go-msgio/protoio" diff --git a/p2p/protocol/identify/id_glass_test.go b/p2p/protocol/identify/id_glass_test.go index de83d8be6b..e716f0a977 100644 --- a/p2p/protocol/identify/id_glass_test.go +++ b/p2p/protocol/identify/id_glass_test.go @@ -5,12 +5,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" blhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/p2p/protocol/identify/id_push.go b/p2p/protocol/identify/id_push.go index 1f644d1ee9..cbb47a9fab 100644 --- a/p2p/protocol/identify/id_push.go +++ b/p2p/protocol/identify/id_push.go @@ -1,7 +1,7 @@ package identify import ( - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) // IDPush is the protocol.ID of the Identify push protocol. It sends full identify messages containing diff --git a/p2p/protocol/identify/id_test.go b/p2p/protocol/identify/id_test.go index ae6ed4b256..d86fc915e6 100644 --- a/p2p/protocol/identify/id_test.go +++ b/p2p/protocol/identify/id_test.go @@ -10,6 +10,15 @@ import ( "time" "github.com/libp2p/go-libp2p" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "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" + "github.com/libp2p/go-libp2p/core/record" + coretest "github.com/libp2p/go-libp2p/core/test" blhost "github.com/libp2p/go-libp2p/p2p/host/blank" "github.com/libp2p/go-libp2p/p2p/host/eventbus" "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" @@ -19,16 +28,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/protocol/identify" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "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" - "github.com/libp2p/go-libp2p-core/record" - coretest "github.com/libp2p/go-libp2p-core/test" - mockClock "github.com/benbjohnson/clock" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-msgio/protoio" diff --git a/p2p/protocol/identify/obsaddr.go b/p2p/protocol/identify/obsaddr.go index 31e7269263..bd72175dc1 100644 --- a/p2p/protocol/identify/obsaddr.go +++ b/p2p/protocol/identify/obsaddr.go @@ -7,10 +7,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peerstore" "github.com/libp2p/go-libp2p/p2p/host/eventbus" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/protocol/identify/obsaddr_test.go b/p2p/protocol/identify/obsaddr_test.go index ea5dc0ae36..aa347e59eb 100644 --- a/p2p/protocol/identify/obsaddr_test.go +++ b/p2p/protocol/identify/obsaddr_test.go @@ -5,16 +5,15 @@ import ( "testing" "time" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/host/eventbus" mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/protocol/identify/pb/identify.pb.go b/p2p/protocol/identify/pb/identify.pb.go index 27d77f7c0a..3cfed82707 100644 --- a/p2p/protocol/identify/pb/identify.pb.go +++ b/p2p/protocol/identify/pb/identify.pb.go @@ -5,10 +5,11 @@ package identify_pb import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. @@ -102,8 +103,8 @@ type Identify struct { // signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord, // signed by the sending node. It contains the same addresses as the listenAddrs field, but // in a form that lets us share authenticated addrs with other peers. - // see github.com/libp2p/go-libp2p-core/record/pb/envelope.proto and - // github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto for message definitions. + // see github.com/libp2p/go-libp2p/core/record/pb/envelope.proto and + // github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto for message definitions. SignedPeerRecord []byte `protobuf:"bytes,8,opt,name=signedPeerRecord" json:"signedPeerRecord,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` diff --git a/p2p/protocol/identify/pb/identify.proto b/p2p/protocol/identify/pb/identify.proto index afc85253f6..bdb283305b 100644 --- a/p2p/protocol/identify/pb/identify.proto +++ b/p2p/protocol/identify/pb/identify.proto @@ -40,7 +40,7 @@ message Identify { // signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord, // signed by the sending node. It contains the same addresses as the listenAddrs field, but // in a form that lets us share authenticated addrs with other peers. - // see github.com/libp2p/go-libp2p-core/record/pb/envelope.proto and - // github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto for message definitions. + // see github.com/libp2p/go-libp2p/core/record/pb/envelope.proto and + // github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto for message definitions. optional bytes signedPeerRecord = 8; } diff --git a/p2p/protocol/identify/peer_loop.go b/p2p/protocol/identify/peer_loop.go index 5fd312585d..af8549339e 100644 --- a/p2p/protocol/identify/peer_loop.go +++ b/p2p/protocol/identify/peer_loop.go @@ -7,11 +7,10 @@ import ( "sync" "time" - "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/record" - + "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/record" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" "github.com/libp2p/go-msgio/protoio" diff --git a/p2p/protocol/identify/peer_loop_test.go b/p2p/protocol/identify/peer_loop_test.go index c6bbbd3fc4..54fe63b243 100644 --- a/p2p/protocol/identify/peer_loop_test.go +++ b/p2p/protocol/identify/peer_loop_test.go @@ -5,12 +5,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" blhost "github.com/libp2p/go-libp2p/p2p/host/blank" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/require" ) diff --git a/p2p/protocol/internal/circuitv1-deprecated/conn.go b/p2p/protocol/internal/circuitv1-deprecated/conn.go index 82b86d1585..19d2964e38 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/conn.go +++ b/p2p/protocol/internal/circuitv1-deprecated/conn.go @@ -5,9 +5,9 @@ import ( "net" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "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" diff --git a/p2p/protocol/internal/circuitv1-deprecated/dial.go b/p2p/protocol/internal/circuitv1-deprecated/dial.go index f454bcc0f7..acc1217c94 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/dial.go +++ b/p2p/protocol/internal/circuitv1-deprecated/dial.go @@ -4,10 +4,10 @@ import ( "context" "fmt" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/internal/circuitv1-deprecated/relay.go b/p2p/protocol/internal/circuitv1-deprecated/relay.go index e468dd9032..f3a491d2f0 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/relay.go +++ b/p2p/protocol/internal/circuitv1-deprecated/relay.go @@ -10,11 +10,11 @@ import ( pb "github.com/libp2p/go-libp2p/p2p/protocol/internal/circuitv1-deprecated/pb" - "github.com/libp2p/go-libp2p-core/host" - "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/transport" + "github.com/libp2p/go-libp2p/core/host" + "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/transport" pool "github.com/libp2p/go-buffer-pool" diff --git a/p2p/protocol/internal/circuitv1-deprecated/relay_test.go b/p2p/protocol/internal/circuitv1-deprecated/relay_test.go index 6e6f3b277f..9b76cffcdc 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/relay_test.go +++ b/p2p/protocol/internal/circuitv1-deprecated/relay_test.go @@ -16,7 +16,7 @@ import ( . "github.com/libp2p/go-libp2p/p2p/protocol/internal/circuitv1-deprecated" pb "github.com/libp2p/go-libp2p/p2p/protocol/internal/circuitv1-deprecated/pb" - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/p2p/protocol/internal/circuitv1-deprecated/transport.go b/p2p/protocol/internal/circuitv1-deprecated/transport.go index 39515876bf..d37b59b6de 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/transport.go +++ b/p2p/protocol/internal/circuitv1-deprecated/transport.go @@ -4,8 +4,8 @@ import ( "fmt" "io" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/internal/circuitv1-deprecated/transport_test.go b/p2p/protocol/internal/circuitv1-deprecated/transport_test.go index 2dfa9df40d..02b3716155 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/transport_test.go +++ b/p2p/protocol/internal/circuitv1-deprecated/transport_test.go @@ -13,9 +13,9 @@ import ( swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" . "github.com/libp2p/go-libp2p/p2p/protocol/internal/circuitv1-deprecated" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peerstore" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/protocol/internal/circuitv1-deprecated/util.go b/p2p/protocol/internal/circuitv1-deprecated/util.go index c04326c615..966d9c59ae 100644 --- a/p2p/protocol/internal/circuitv1-deprecated/util.go +++ b/p2p/protocol/internal/circuitv1-deprecated/util.go @@ -6,7 +6,7 @@ import ( pb "github.com/libp2p/go-libp2p/p2p/protocol/internal/circuitv1-deprecated/pb" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" pool "github.com/libp2p/go-buffer-pool" "github.com/libp2p/go-msgio/protoio" diff --git a/p2p/protocol/ping/ping.go b/p2p/protocol/ping/ping.go index 2a977de4b2..583eea5c32 100644 --- a/p2p/protocol/ping/ping.go +++ b/p2p/protocol/ping/ping.go @@ -12,9 +12,9 @@ import ( logging "github.com/ipfs/go-log/v2" pool "github.com/libp2p/go-buffer-pool" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) var log = logging.Logger("ping") diff --git a/p2p/protocol/ping/ping_test.go b/p2p/protocol/ping/ping_test.go index 51e7f18f0e..afda08165e 100644 --- a/p2p/protocol/ping/ping_test.go +++ b/p2p/protocol/ping/ping_test.go @@ -5,12 +5,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/peer" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" "github.com/libp2p/go-libp2p/p2p/protocol/ping" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/security/noise/benchmark_test.go b/p2p/security/noise/benchmark_test.go index 0019eb9ab8..52454f5959 100644 --- a/p2p/security/noise/benchmark_test.go +++ b/p2p/security/noise/benchmark_test.go @@ -10,8 +10,8 @@ import ( "golang.org/x/crypto/chacha20poly1305" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/sec" ) type testMode int diff --git a/p2p/security/noise/crypto_test.go b/p2p/security/noise/crypto_test.go index 87efb8487f..35837a5a6c 100644 --- a/p2p/security/noise/crypto_test.go +++ b/p2p/security/noise/crypto_test.go @@ -6,7 +6,7 @@ import ( "net" "testing" - "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p/core/crypto" ) func TestEncryptAndDecrypt_InitToResp(t *testing.T) { diff --git a/p2p/security/noise/handshake.go b/p2p/security/noise/handshake.go index 504a2b155c..b71d7ef89b 100644 --- a/p2p/security/noise/handshake.go +++ b/p2p/security/noise/handshake.go @@ -15,8 +15,8 @@ import ( "github.com/libp2p/go-libp2p/p2p/security/noise/pb" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" "github.com/flynn/noise" "github.com/gogo/protobuf/proto" diff --git a/p2p/security/noise/session.go b/p2p/security/noise/session.go index 9770178a5c..a563e58b5d 100644 --- a/p2p/security/noise/session.go +++ b/p2p/security/noise/session.go @@ -9,8 +9,8 @@ import ( "github.com/flynn/noise" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ) type secureSession struct { diff --git a/p2p/security/noise/session_test.go b/p2p/security/noise/session_test.go index ff2d69b5fc..85de01b2ba 100644 --- a/p2p/security/noise/session_test.go +++ b/p2p/security/noise/session_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p/core/crypto" "github.com/stretchr/testify/require" ) diff --git a/p2p/security/noise/session_transport.go b/p2p/security/noise/session_transport.go index b996d95b16..b4414136ec 100644 --- a/p2p/security/noise/session_transport.go +++ b/p2p/security/noise/session_transport.go @@ -4,9 +4,9 @@ import ( "context" "net" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/security/noise/transport.go b/p2p/security/noise/transport.go index 689a5e123c..f935b82a73 100644 --- a/p2p/security/noise/transport.go +++ b/p2p/security/noise/transport.go @@ -4,10 +4,11 @@ import ( "context" "net" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + manet "github.com/multiformats/go-multiaddr/net" ) @@ -17,7 +18,7 @@ const ID = "/noise" var _ sec.SecureTransport = &Transport{} // Transport implements the interface sec.SecureTransport -// https://godoc.org/github.com/libp2p/go-libp2p-core/sec#SecureConn +// https://godoc.org/github.com/libp2p/go-libp2p/core/sec#SecureConn type Transport struct { localID peer.ID privateKey crypto.PrivKey diff --git a/p2p/security/noise/transport_test.go b/p2p/security/noise/transport_test.go index 4ce476139c..5269be2945 100644 --- a/p2p/security/noise/transport_test.go +++ b/p2p/security/noise/transport_test.go @@ -13,9 +13,9 @@ import ( "golang.org/x/crypto/chacha20poly1305" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/p2p/security/tls/cmd/tlsdiag/client.go b/p2p/security/tls/cmd/tlsdiag/client.go index 841a7385d0..7f1a7efecd 100644 --- a/p2p/security/tls/cmd/tlsdiag/client.go +++ b/p2p/security/tls/cmd/tlsdiag/client.go @@ -10,7 +10,7 @@ import ( libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) func StartClient() error { diff --git a/p2p/security/tls/cmd/tlsdiag/key.go b/p2p/security/tls/cmd/tlsdiag/key.go index 557a485c35..c192d221e6 100644 --- a/p2p/security/tls/cmd/tlsdiag/key.go +++ b/p2p/security/tls/cmd/tlsdiag/key.go @@ -4,7 +4,7 @@ import ( "crypto/rand" "fmt" - ic "github.com/libp2p/go-libp2p-core/crypto" + ic "github.com/libp2p/go-libp2p/core/crypto" ) func generateKey(keyType string) (priv ic.PrivKey, err error) { diff --git a/p2p/security/tls/cmd/tlsdiag/server.go b/p2p/security/tls/cmd/tlsdiag/server.go index 5f85bc7299..16f51f4a1b 100644 --- a/p2p/security/tls/cmd/tlsdiag/server.go +++ b/p2p/security/tls/cmd/tlsdiag/server.go @@ -9,7 +9,7 @@ import ( libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) func StartServer() error { diff --git a/p2p/security/tls/conn.go b/p2p/security/tls/conn.go index cf32fa459d..6353eac80b 100644 --- a/p2p/security/tls/conn.go +++ b/p2p/security/tls/conn.go @@ -3,9 +3,9 @@ package libp2ptls import ( "crypto/tls" - ci "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + ci "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" ) type conn struct { diff --git a/p2p/security/tls/crypto.go b/p2p/security/tls/crypto.go index 698cccf4ba..aa16b334fc 100644 --- a/p2p/security/tls/crypto.go +++ b/p2p/security/tls/crypto.go @@ -18,8 +18,8 @@ import ( "golang.org/x/sys/cpu" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ) const certValidityPeriod = 100 * 365 * 24 * time.Hour // ~100 years diff --git a/p2p/security/tls/transport.go b/p2p/security/tls/transport.go index 90c714911e..f6aa64f6ab 100644 --- a/p2p/security/tls/transport.go +++ b/p2p/security/tls/transport.go @@ -9,10 +9,11 @@ import ( "os" "runtime/debug" - "github.com/libp2p/go-libp2p-core/canonicallog" - ci "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/canonicallog" + ci "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/p2p/security/tls/transport_test.go b/p2p/security/tls/transport_test.go index 1d272f0fbe..ef0009ebd7 100644 --- a/p2p/security/tls/transport_test.go +++ b/p2p/security/tls/transport_test.go @@ -20,9 +20,9 @@ import ( "testing" "time" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/p2p/test/backpressure/backpressure_test.go b/p2p/test/backpressure/backpressure_test.go index 20336f02e8..e7dfe91e66 100644 --- a/p2p/test/backpressure/backpressure_test.go +++ b/p2p/test/backpressure/backpressure_test.go @@ -6,12 +6,11 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/protocol" - logging "github.com/ipfs/go-log/v2" "github.com/stretchr/testify/require" ) diff --git a/p2p/test/reconnects/reconnect_test.go b/p2p/test/reconnects/reconnect_test.go index 72523ffd26..07e7f22196 100644 --- a/p2p/test/reconnects/reconnect_test.go +++ b/p2p/test/reconnects/reconnect_test.go @@ -9,14 +9,13 @@ import ( "testing" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/stretchr/testify/require" ) diff --git a/p2p/test/resource-manager/echo.go b/p2p/test/resource-manager/echo.go index 90acec56e4..8689bab99a 100644 --- a/p2p/test/resource-manager/echo.go +++ b/p2p/test/resource-manager/echo.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" logging "github.com/ipfs/go-log/v2" ) diff --git a/p2p/test/resource-manager/echo_test.go b/p2p/test/resource-manager/echo_test.go index f181cb1087..cb26e918ce 100644 --- a/p2p/test/resource-manager/echo_test.go +++ b/p2p/test/resource-manager/echo_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" "github.com/stretchr/testify/require" ) diff --git a/p2p/test/resource-manager/rcmgr_test.go b/p2p/test/resource-manager/rcmgr_test.go index cd1c10bd6a..634b725362 100644 --- a/p2p/test/resource-manager/rcmgr_test.go +++ b/p2p/test/resource-manager/rcmgr_test.go @@ -10,11 +10,10 @@ import ( "time" "github.com/libp2p/go-libp2p" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/stretchr/testify/require" ) diff --git a/p2p/transport/quic/cmd/client/main.go b/p2p/transport/quic/cmd/client/main.go index 90355fe7e8..f8071b6e6d 100644 --- a/p2p/transport/quic/cmd/client/main.go +++ b/p2p/transport/quic/cmd/client/main.go @@ -8,9 +8,10 @@ import ( "log" "os" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/quic/cmd/server/main.go b/p2p/transport/quic/cmd/server/main.go index 066e981bbc..e6585137f2 100644 --- a/p2p/transport/quic/cmd/server/main.go +++ b/p2p/transport/quic/cmd/server/main.go @@ -7,10 +7,11 @@ import ( "log" "os" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - tpt "github.com/libp2p/go-libp2p-core/transport" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + tpt "github.com/libp2p/go-libp2p/core/transport" libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/quic/conn.go b/p2p/transport/quic/conn.go index 778460c6c9..58537b6b18 100644 --- a/p2p/transport/quic/conn.go +++ b/p2p/transport/quic/conn.go @@ -3,10 +3,10 @@ package libp2pquic import ( "context" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - tpt "github.com/libp2p/go-libp2p-core/transport" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + tpt "github.com/libp2p/go-libp2p/core/transport" "github.com/lucas-clemente/quic-go" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/transport/quic/conn_test.go b/p2p/transport/quic/conn_test.go index b409f4df50..fe1e01ac15 100644 --- a/p2p/transport/quic/conn_test.go +++ b/p2p/transport/quic/conn_test.go @@ -13,21 +13,19 @@ import ( "testing" "time" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - tpt "github.com/libp2p/go-libp2p-core/transport" - - mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + mocknetwork "github.com/libp2p/go-libp2p/core/network/mocks" + "github.com/libp2p/go-libp2p/core/peer" + tpt "github.com/libp2p/go-libp2p/core/transport" + "github.com/golang/mock/gomock" quicproxy "github.com/lucas-clemente/quic-go/integrationtests/tools/proxy" ma "github.com/multiformats/go-multiaddr" - - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) -//go:generate sh -c "mockgen -package libp2pquic -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p-core/connmgr ConnectionGater && goimports -w mock_connection_gater_test.go" +//go:generate sh -c "mockgen -package libp2pquic -destination mock_connection_gater_test.go github.com/libp2p/go-libp2p/core/connmgr ConnectionGater && goimports -w mock_connection_gater_test.go" func createPeer(t *testing.T) (peer.ID, ic.PrivKey) { var priv ic.PrivKey diff --git a/p2p/transport/quic/listener.go b/p2p/transport/quic/listener.go index 955c0f6c07..ddf18441c3 100644 --- a/p2p/transport/quic/listener.go +++ b/p2p/transport/quic/listener.go @@ -5,13 +5,12 @@ import ( "crypto/tls" "net" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + tpt "github.com/libp2p/go-libp2p/core/transport" p2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - tpt "github.com/libp2p/go-libp2p-core/transport" - "github.com/lucas-clemente/quic-go" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/quic/listener_test.go b/p2p/transport/quic/listener_test.go index 7a72f76c57..7c8494ae91 100644 --- a/p2p/transport/quic/listener_test.go +++ b/p2p/transport/quic/listener_test.go @@ -12,9 +12,9 @@ import ( "testing" "time" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - tpt "github.com/libp2p/go-libp2p-core/transport" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + tpt "github.com/libp2p/go-libp2p/core/transport" "github.com/lucas-clemente/quic-go" ma "github.com/multiformats/go-multiaddr" diff --git a/p2p/transport/quic/mock_connection_gater_test.go b/p2p/transport/quic/mock_connection_gater_test.go index 3a2cdcdb62..4ee4008536 100644 --- a/p2p/transport/quic/mock_connection_gater_test.go +++ b/p2p/transport/quic/mock_connection_gater_test.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/libp2p/go-libp2p-core/connmgr (interfaces: ConnectionGater) +// Source: github.com/libp2p/go-libp2p/core/connmgr (interfaces: ConnectionGater) // Package libp2pquic is a generated GoMock package. package libp2pquic @@ -8,9 +8,9 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - control "github.com/libp2p/go-libp2p-core/control" - network "github.com/libp2p/go-libp2p-core/network" - peer "github.com/libp2p/go-libp2p-core/peer" + control "github.com/libp2p/go-libp2p/core/control" + network "github.com/libp2p/go-libp2p/core/network" + peer "github.com/libp2p/go-libp2p/core/peer" multiaddr "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/quic/stream.go b/p2p/transport/quic/stream.go index 883b0cc348..5d276dab80 100644 --- a/p2p/transport/quic/stream.go +++ b/p2p/transport/quic/stream.go @@ -3,7 +3,7 @@ package libp2pquic import ( "errors" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" "github.com/lucas-clemente/quic-go" ) diff --git a/p2p/transport/quic/transport.go b/p2p/transport/quic/transport.go index cee7b1374b..3702c50557 100644 --- a/p2p/transport/quic/transport.go +++ b/p2p/transport/quic/transport.go @@ -12,15 +12,14 @@ import ( "golang.org/x/crypto/hkdf" + "github.com/libp2p/go-libp2p/core/connmgr" + ic "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/pnet" + tpt "github.com/libp2p/go-libp2p/core/transport" p2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - "github.com/libp2p/go-libp2p-core/connmgr" - ic "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/pnet" - tpt "github.com/libp2p/go-libp2p-core/transport" - ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" manet "github.com/multiformats/go-multiaddr/net" diff --git a/p2p/transport/quic/transport_test.go b/p2p/transport/quic/transport_test.go index 64bf24e0ae..26cabbd7c4 100644 --- a/p2p/transport/quic/transport_test.go +++ b/p2p/transport/quic/transport_test.go @@ -11,13 +11,12 @@ import ( "net" "testing" - "github.com/stretchr/testify/require" - - ic "github.com/libp2p/go-libp2p-core/crypto" - tpt "github.com/libp2p/go-libp2p-core/transport" - ma "github.com/multiformats/go-multiaddr" + ic "github.com/libp2p/go-libp2p/core/crypto" + tpt "github.com/libp2p/go-libp2p/core/transport" "github.com/lucas-clemente/quic-go" + ma "github.com/multiformats/go-multiaddr" + "github.com/stretchr/testify/require" ) func getTransport(t *testing.T) tpt.Transport { diff --git a/p2p/transport/tcp/tcp.go b/p2p/transport/tcp/tcp.go index 120feee8d4..9e6f538626 100644 --- a/p2p/transport/tcp/tcp.go +++ b/p2p/transport/tcp/tcp.go @@ -9,12 +9,11 @@ import ( "syscall" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/net/reuseport" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" diff --git a/p2p/transport/tcp/tcp_test.go b/p2p/transport/tcp/tcp_test.go index 9874cadea9..f73e511a10 100644 --- a/p2p/transport/tcp/tcp_test.go +++ b/p2p/transport/tcp/tcp_test.go @@ -5,23 +5,20 @@ import ( "errors" "testing" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + mocknetwork "github.com/libp2p/go-libp2p/core/network/mocks" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/sec/insecure" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" tptu "github.com/libp2p/go-libp2p/p2p/net/upgrader" ttransport "github.com/libp2p/go-libp2p/p2p/transport/testsuite" - "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/sec" - "github.com/libp2p/go-libp2p-core/sec/insecure" - "github.com/libp2p/go-libp2p-core/transport" - - mocknetwork "github.com/libp2p/go-libp2p-testing/mocks/network" - - ma "github.com/multiformats/go-multiaddr" - "github.com/golang/mock/gomock" + ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" ) diff --git a/p2p/transport/testsuite/stream_suite.go b/p2p/transport/testsuite/stream_suite.go index 439fd068d2..b139976b91 100644 --- a/p2p/transport/testsuite/stream_suite.go +++ b/p2p/transport/testsuite/stream_suite.go @@ -15,10 +15,10 @@ import ( crand "crypto/rand" mrand "math/rand" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" "github.com/libp2p/go-libp2p-testing/race" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/testsuite/transport_suite.go b/p2p/transport/testsuite/transport_suite.go index bba9747474..bd8892e807 100644 --- a/p2p/transport/testsuite/transport_suite.go +++ b/p2p/transport/testsuite/transport_suite.go @@ -8,8 +8,8 @@ import ( "sync" "testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/testsuite/utils_suite.go b/p2p/transport/testsuite/utils_suite.go index 201d43d9d7..5e488397a5 100644 --- a/p2p/transport/testsuite/utils_suite.go +++ b/p2p/transport/testsuite/utils_suite.go @@ -5,8 +5,8 @@ import ( "runtime" "testing" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/p2p/transport/websocket/websocket.go b/p2p/transport/websocket/websocket.go index af74ccfbf6..42c4c618f4 100644 --- a/p2p/transport/websocket/websocket.go +++ b/p2p/transport/websocket/websocket.go @@ -7,9 +7,9 @@ import ( "net/http" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" diff --git a/p2p/transport/websocket/websocket_test.go b/p2p/transport/websocket/websocket_test.go index 167fe31c1f..77dda801f8 100644 --- a/p2p/transport/websocket/websocket_test.go +++ b/p2p/transport/websocket/websocket_test.go @@ -14,19 +14,18 @@ import ( "testing" "time" + "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/sec" + "github.com/libp2p/go-libp2p/core/sec/insecure" + "github.com/libp2p/go-libp2p/core/test" + "github.com/libp2p/go-libp2p/core/transport" + "github.com/libp2p/go-libp2p/p2p/muxer/yamux" csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" tptu "github.com/libp2p/go-libp2p/p2p/net/upgrader" ttransport "github.com/libp2p/go-libp2p/p2p/transport/testsuite" - "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/sec" - "github.com/libp2p/go-libp2p-core/sec/insecure" - "github.com/libp2p/go-libp2p-core/test" - "github.com/libp2p/go-libp2p-core/transport" - "github.com/libp2p/go-libp2p/p2p/muxer/yamux" - ma "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/require" )