Integrate BACKBEAT SDK and resolve KACHING license validation
Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1002
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go
generated
vendored
Normal file
1002
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
206
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/metrics.go
generated
vendored
Normal file
206
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/metrics.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
package identify
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/event"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/p2p/metricshelper"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const metricNamespace = "libp2p_identify"
|
||||
|
||||
var (
|
||||
pushesTriggered = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "identify_pushes_triggered_total",
|
||||
Help: "Pushes Triggered",
|
||||
},
|
||||
[]string{"trigger"},
|
||||
)
|
||||
identify = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "identify_total",
|
||||
Help: "Identify",
|
||||
},
|
||||
[]string{"dir"},
|
||||
)
|
||||
identifyPush = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "identify_push_total",
|
||||
Help: "Identify Push",
|
||||
},
|
||||
[]string{"dir"},
|
||||
)
|
||||
connPushSupportTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "conn_push_support_total",
|
||||
Help: "Identify Connection Push Support",
|
||||
},
|
||||
[]string{"support"},
|
||||
)
|
||||
protocolsCount = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "protocols_count",
|
||||
Help: "Protocols Count",
|
||||
},
|
||||
)
|
||||
addrsCount = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "addrs_count",
|
||||
Help: "Address Count",
|
||||
},
|
||||
)
|
||||
numProtocolsReceived = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "protocols_received",
|
||||
Help: "Number of Protocols received",
|
||||
Buckets: buckets,
|
||||
},
|
||||
)
|
||||
numAddrsReceived = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "addrs_received",
|
||||
Help: "Number of addrs received",
|
||||
Buckets: buckets,
|
||||
},
|
||||
)
|
||||
collectors = []prometheus.Collector{
|
||||
pushesTriggered,
|
||||
identify,
|
||||
identifyPush,
|
||||
connPushSupportTotal,
|
||||
protocolsCount,
|
||||
addrsCount,
|
||||
numProtocolsReceived,
|
||||
numAddrsReceived,
|
||||
}
|
||||
// 1 to 20 and then up to 100 in steps of 5
|
||||
buckets = append(
|
||||
prometheus.LinearBuckets(1, 1, 20),
|
||||
prometheus.LinearBuckets(25, 5, 16)...,
|
||||
)
|
||||
)
|
||||
|
||||
type MetricsTracer interface {
|
||||
// TriggeredPushes counts IdentifyPushes triggered by event
|
||||
TriggeredPushes(event any)
|
||||
|
||||
// ConnPushSupport counts peers by Push Support
|
||||
ConnPushSupport(identifyPushSupport)
|
||||
|
||||
// IdentifyReceived tracks metrics on receiving an identify response
|
||||
IdentifyReceived(isPush bool, numProtocols int, numAddrs int)
|
||||
|
||||
// IdentifySent tracks metrics on sending an identify response
|
||||
IdentifySent(isPush bool, numProtocols int, numAddrs int)
|
||||
}
|
||||
|
||||
type metricsTracer struct{}
|
||||
|
||||
var _ MetricsTracer = &metricsTracer{}
|
||||
|
||||
type metricsTracerSetting struct {
|
||||
reg prometheus.Registerer
|
||||
}
|
||||
|
||||
type MetricsTracerOption func(*metricsTracerSetting)
|
||||
|
||||
func WithRegisterer(reg prometheus.Registerer) MetricsTracerOption {
|
||||
return func(s *metricsTracerSetting) {
|
||||
if reg != nil {
|
||||
s.reg = reg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewMetricsTracer(opts ...MetricsTracerOption) MetricsTracer {
|
||||
setting := &metricsTracerSetting{reg: prometheus.DefaultRegisterer}
|
||||
for _, opt := range opts {
|
||||
opt(setting)
|
||||
}
|
||||
metricshelper.RegisterCollectors(setting.reg, collectors...)
|
||||
return &metricsTracer{}
|
||||
}
|
||||
|
||||
func (t *metricsTracer) TriggeredPushes(ev any) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
typ := "unknown"
|
||||
switch ev.(type) {
|
||||
case event.EvtLocalProtocolsUpdated:
|
||||
typ = "protocols_updated"
|
||||
case event.EvtLocalAddressesUpdated:
|
||||
typ = "addresses_updated"
|
||||
}
|
||||
*tags = append(*tags, typ)
|
||||
pushesTriggered.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (t *metricsTracer) IncrementPushSupport(s identifyPushSupport) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
*tags = append(*tags, getPushSupport(s))
|
||||
connPushSupportTotal.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (t *metricsTracer) IdentifySent(isPush bool, numProtocols int, numAddrs int) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
if isPush {
|
||||
*tags = append(*tags, metricshelper.GetDirection(network.DirOutbound))
|
||||
identifyPush.WithLabelValues(*tags...).Inc()
|
||||
} else {
|
||||
*tags = append(*tags, metricshelper.GetDirection(network.DirInbound))
|
||||
identify.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
protocolsCount.Set(float64(numProtocols))
|
||||
addrsCount.Set(float64(numAddrs))
|
||||
}
|
||||
|
||||
func (t *metricsTracer) IdentifyReceived(isPush bool, numProtocols int, numAddrs int) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
if isPush {
|
||||
*tags = append(*tags, metricshelper.GetDirection(network.DirInbound))
|
||||
identifyPush.WithLabelValues(*tags...).Inc()
|
||||
} else {
|
||||
*tags = append(*tags, metricshelper.GetDirection(network.DirOutbound))
|
||||
identify.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
numProtocolsReceived.Observe(float64(numProtocols))
|
||||
numAddrsReceived.Observe(float64(numAddrs))
|
||||
}
|
||||
|
||||
func (t *metricsTracer) ConnPushSupport(support identifyPushSupport) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
*tags = append(*tags, getPushSupport(support))
|
||||
connPushSupportTotal.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func getPushSupport(s identifyPushSupport) string {
|
||||
switch s {
|
||||
case identifyPushSupported:
|
||||
return "supported"
|
||||
case identifyPushUnsupported:
|
||||
return "not supported"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
640
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go
generated
vendored
Normal file
640
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go
generated
vendored
Normal file
@@ -0,0 +1,640 @@
|
||||
package identify
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"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"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
// ActivationThresh sets how many times an address must be seen as "activated"
|
||||
// and therefore advertised to other peers as an address that the local peer
|
||||
// can be contacted on. The "seen" events expire by default after 40 minutes
|
||||
// (OwnObservedAddressTTL * ActivationThreshold). The are cleaned up during
|
||||
// the GC rounds set by GCInterval.
|
||||
var ActivationThresh = 4
|
||||
|
||||
// GCInterval specicies how often to make a round cleaning seen events and
|
||||
// observed addresses. An address will be cleaned if it has not been seen in
|
||||
// OwnObservedAddressTTL (10 minutes). A "seen" event will be cleaned up if
|
||||
// it is older than OwnObservedAddressTTL * ActivationThresh (40 minutes).
|
||||
var GCInterval = 10 * time.Minute
|
||||
|
||||
// observedAddrManagerWorkerChannelSize defines how many addresses can be enqueued
|
||||
// for adding to an ObservedAddrManager.
|
||||
var observedAddrManagerWorkerChannelSize = 16
|
||||
|
||||
// maxObservedAddrsPerIPAndTransport is the maximum number of observed addresses
|
||||
// we will return for each (IPx/TCP or UDP) group.
|
||||
var maxObservedAddrsPerIPAndTransport = 2
|
||||
|
||||
// observation records an address observation from an "observer" (where every IP
|
||||
// address is a unique observer).
|
||||
type observation struct {
|
||||
// seenTime is the last time this observation was made.
|
||||
seenTime time.Time
|
||||
// inbound indicates whether or not this observation has been made from
|
||||
// an inbound connection. This remains true even if we an observation
|
||||
// from a subsequent outbound connection.
|
||||
inbound bool
|
||||
}
|
||||
|
||||
// observedAddr is an entry for an address reported by our peers.
|
||||
// We only use addresses that:
|
||||
// - have been observed at least 4 times in last 40 minutes. (counter symmetric nats)
|
||||
// - have been observed at least once recently (10 minutes), because our position in the
|
||||
// network, or network port mapppings, may have changed.
|
||||
type observedAddr struct {
|
||||
addr ma.Multiaddr
|
||||
seenBy map[string]observation // peer(observer) address -> observation info
|
||||
lastSeen time.Time
|
||||
numInbound int
|
||||
}
|
||||
|
||||
func (oa *observedAddr) activated() bool {
|
||||
|
||||
// We only activate if other peers observed the same address
|
||||
// of ours at least 4 times. SeenBy peers are removed by GC if
|
||||
// they say the address more than ttl*ActivationThresh
|
||||
return len(oa.seenBy) >= ActivationThresh
|
||||
}
|
||||
|
||||
// GroupKey returns the group in which this observation belongs. Currently, an
|
||||
// observed address's group is just the address with all ports set to 0. This
|
||||
// means we can advertise the most commonly observed external ports without
|
||||
// advertising _every_ observed port.
|
||||
func (oa *observedAddr) groupKey() string {
|
||||
key := make([]byte, 0, len(oa.addr.Bytes()))
|
||||
ma.ForEach(oa.addr, func(c ma.Component) bool {
|
||||
switch proto := c.Protocol(); proto.Code {
|
||||
case ma.P_TCP, ma.P_UDP:
|
||||
key = append(key, proto.VCode...)
|
||||
key = append(key, 0, 0) // zero in two bytes
|
||||
default:
|
||||
key = append(key, c.Bytes()...)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
return string(key)
|
||||
}
|
||||
|
||||
type newObservation struct {
|
||||
conn network.Conn
|
||||
observed ma.Multiaddr
|
||||
}
|
||||
|
||||
// ObservedAddrManager keeps track of a ObservedAddrs.
|
||||
type ObservedAddrManager struct {
|
||||
host host.Host
|
||||
|
||||
closeOnce sync.Once
|
||||
refCount sync.WaitGroup
|
||||
ctx context.Context // the context is canceled when Close is called
|
||||
ctxCancel context.CancelFunc
|
||||
|
||||
// latest observation from active connections
|
||||
// we'll "re-observe" these when we gc
|
||||
activeConnsMu sync.Mutex
|
||||
// active connection -> most recent observation
|
||||
activeConns map[network.Conn]ma.Multiaddr
|
||||
|
||||
mu sync.RWMutex
|
||||
closed bool
|
||||
// local(internal) address -> list of observed(external) addresses
|
||||
addrs map[string][]*observedAddr
|
||||
ttl time.Duration
|
||||
refreshTimer *time.Timer
|
||||
|
||||
// this is the worker channel
|
||||
wch chan newObservation
|
||||
|
||||
reachabilitySub event.Subscription
|
||||
reachability network.Reachability
|
||||
|
||||
currentUDPNATDeviceType network.NATDeviceType
|
||||
currentTCPNATDeviceType network.NATDeviceType
|
||||
emitNATDeviceTypeChanged event.Emitter
|
||||
}
|
||||
|
||||
// NewObservedAddrManager returns a new address manager using
|
||||
// peerstore.OwnObservedAddressTTL as the TTL.
|
||||
func NewObservedAddrManager(host host.Host) (*ObservedAddrManager, error) {
|
||||
oas := &ObservedAddrManager{
|
||||
addrs: make(map[string][]*observedAddr),
|
||||
ttl: peerstore.OwnObservedAddrTTL,
|
||||
wch: make(chan newObservation, observedAddrManagerWorkerChannelSize),
|
||||
host: host,
|
||||
activeConns: make(map[network.Conn]ma.Multiaddr),
|
||||
// refresh every ttl/2 so we don't forget observations from connected peers
|
||||
refreshTimer: time.NewTimer(peerstore.OwnObservedAddrTTL / 2),
|
||||
}
|
||||
oas.ctx, oas.ctxCancel = context.WithCancel(context.Background())
|
||||
|
||||
reachabilitySub, err := host.EventBus().Subscribe(new(event.EvtLocalReachabilityChanged), eventbus.Name("identify (obsaddr)"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to subscribe to reachability event: %s", err)
|
||||
}
|
||||
oas.reachabilitySub = reachabilitySub
|
||||
|
||||
emitter, err := host.EventBus().Emitter(new(event.EvtNATDeviceTypeChanged), eventbus.Stateful)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create emitter for NATDeviceType: %s", err)
|
||||
}
|
||||
oas.emitNATDeviceTypeChanged = emitter
|
||||
|
||||
oas.host.Network().Notify((*obsAddrNotifiee)(oas))
|
||||
oas.refCount.Add(1)
|
||||
go oas.worker()
|
||||
return oas, nil
|
||||
}
|
||||
|
||||
// AddrsFor return all activated observed addresses associated with the given
|
||||
// (resolved) listen address.
|
||||
func (oas *ObservedAddrManager) AddrsFor(addr ma.Multiaddr) (addrs []ma.Multiaddr) {
|
||||
oas.mu.RLock()
|
||||
defer oas.mu.RUnlock()
|
||||
|
||||
if len(oas.addrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
observedAddrs, ok := oas.addrs[string(addr.Bytes())]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
return oas.filter(observedAddrs)
|
||||
}
|
||||
|
||||
// Addrs return all activated observed addresses
|
||||
func (oas *ObservedAddrManager) Addrs() []ma.Multiaddr {
|
||||
oas.mu.RLock()
|
||||
defer oas.mu.RUnlock()
|
||||
|
||||
if len(oas.addrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var allObserved []*observedAddr
|
||||
for _, addrs := range oas.addrs {
|
||||
allObserved = append(allObserved, addrs...)
|
||||
}
|
||||
return oas.filter(allObserved)
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) filter(observedAddrs []*observedAddr) []ma.Multiaddr {
|
||||
pmap := make(map[string][]*observedAddr)
|
||||
now := time.Now()
|
||||
|
||||
for i := range observedAddrs {
|
||||
a := observedAddrs[i]
|
||||
if now.Sub(a.lastSeen) <= oas.ttl && a.activated() {
|
||||
// group addresses by their IPX/Transport Protocol(TCP or UDP) pattern.
|
||||
pat := a.groupKey()
|
||||
pmap[pat] = append(pmap[pat], a)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
addrs := make([]ma.Multiaddr, 0, len(observedAddrs))
|
||||
for pat := range pmap {
|
||||
s := pmap[pat]
|
||||
|
||||
slices.SortFunc(s, func(first, second *observedAddr) int {
|
||||
// We prefer inbound connection observations over outbound.
|
||||
if first.numInbound > second.numInbound {
|
||||
return -1
|
||||
}
|
||||
// For ties, we prefer the ones with more votes.
|
||||
if first.numInbound == second.numInbound && len(first.seenBy) > len(second.seenBy) {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
})
|
||||
|
||||
for i := 0; i < maxObservedAddrsPerIPAndTransport && i < len(s); i++ {
|
||||
addrs = append(addrs, s[i].addr)
|
||||
}
|
||||
}
|
||||
|
||||
return addrs
|
||||
}
|
||||
|
||||
// Record records an address observation, if valid.
|
||||
func (oas *ObservedAddrManager) Record(conn network.Conn, observed ma.Multiaddr) {
|
||||
select {
|
||||
case oas.wch <- newObservation{
|
||||
conn: conn,
|
||||
observed: observed,
|
||||
}:
|
||||
default:
|
||||
log.Debugw("dropping address observation due to full buffer",
|
||||
"from", conn.RemoteMultiaddr(),
|
||||
"observed", observed,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) worker() {
|
||||
defer oas.refCount.Done()
|
||||
|
||||
ticker := time.NewTicker(GCInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
subChan := oas.reachabilitySub.Out()
|
||||
for {
|
||||
select {
|
||||
case evt, ok := <-subChan:
|
||||
if !ok {
|
||||
subChan = nil
|
||||
continue
|
||||
}
|
||||
ev := evt.(event.EvtLocalReachabilityChanged)
|
||||
oas.reachability = ev.Reachability
|
||||
case obs := <-oas.wch:
|
||||
oas.maybeRecordObservation(obs.conn, obs.observed)
|
||||
case <-ticker.C:
|
||||
oas.gc()
|
||||
case <-oas.refreshTimer.C:
|
||||
oas.refresh()
|
||||
case <-oas.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) refresh() {
|
||||
oas.activeConnsMu.Lock()
|
||||
recycledObservations := make([]newObservation, 0, len(oas.activeConns))
|
||||
for conn, observed := range oas.activeConns {
|
||||
recycledObservations = append(recycledObservations, newObservation{
|
||||
conn: conn,
|
||||
observed: observed,
|
||||
})
|
||||
}
|
||||
oas.activeConnsMu.Unlock()
|
||||
|
||||
oas.mu.Lock()
|
||||
defer oas.mu.Unlock()
|
||||
for _, obs := range recycledObservations {
|
||||
oas.recordObservationUnlocked(obs.conn, obs.observed)
|
||||
}
|
||||
// refresh every ttl/2 so we don't forget observations from connected peers
|
||||
oas.refreshTimer.Reset(oas.ttl / 2)
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) gc() {
|
||||
oas.mu.Lock()
|
||||
defer oas.mu.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
for local, observedAddrs := range oas.addrs {
|
||||
filteredAddrs := observedAddrs[:0]
|
||||
for _, a := range observedAddrs {
|
||||
// clean up SeenBy set
|
||||
for k, ob := range a.seenBy {
|
||||
if now.Sub(ob.seenTime) > oas.ttl*time.Duration(ActivationThresh) {
|
||||
delete(a.seenBy, k)
|
||||
if ob.inbound {
|
||||
a.numInbound--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// leave only alive observed addresses
|
||||
if now.Sub(a.lastSeen) <= oas.ttl {
|
||||
filteredAddrs = append(filteredAddrs, a)
|
||||
}
|
||||
}
|
||||
if len(filteredAddrs) > 0 {
|
||||
oas.addrs[local] = filteredAddrs
|
||||
} else {
|
||||
delete(oas.addrs, local)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) addConn(conn network.Conn, observed ma.Multiaddr) {
|
||||
oas.activeConnsMu.Lock()
|
||||
defer oas.activeConnsMu.Unlock()
|
||||
|
||||
// We need to make sure we haven't received a disconnect event for this
|
||||
// connection yet. The only way to do that right now is to make sure the
|
||||
// swarm still has the connection.
|
||||
//
|
||||
// Doing this under a lock that we _also_ take in a disconnect event
|
||||
// handler ensures everything happens in the right order.
|
||||
for _, c := range oas.host.Network().ConnsToPeer(conn.RemotePeer()) {
|
||||
if c == conn {
|
||||
oas.activeConns[conn] = observed
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) removeConn(conn network.Conn) {
|
||||
// DO NOT remove this lock.
|
||||
// This ensures we don't call addConn at the same time:
|
||||
// 1. see that we have a connection and pause inside addConn right before recording it.
|
||||
// 2. process a disconnect event.
|
||||
// 3. record the connection (leaking it).
|
||||
|
||||
oas.activeConnsMu.Lock()
|
||||
delete(oas.activeConns, conn)
|
||||
oas.activeConnsMu.Unlock()
|
||||
}
|
||||
|
||||
type normalizeMultiaddrer interface {
|
||||
NormalizeMultiaddr(addr ma.Multiaddr) ma.Multiaddr
|
||||
}
|
||||
|
||||
type addrsProvider interface {
|
||||
Addrs() []ma.Multiaddr
|
||||
}
|
||||
|
||||
type listenAddrsProvider interface {
|
||||
ListenAddresses() []ma.Multiaddr
|
||||
InterfaceListenAddresses() ([]ma.Multiaddr, error)
|
||||
}
|
||||
|
||||
func shouldRecordObservation(host addrsProvider, network listenAddrsProvider, conn network.ConnMultiaddrs, observed ma.Multiaddr) bool {
|
||||
// First, determine if this observation is even worth keeping...
|
||||
|
||||
// Ignore observations from loopback nodes. We already know our loopback
|
||||
// addresses.
|
||||
if manet.IsIPLoopback(observed) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Provided by NAT64 peers, these addresses are specific to the peer and not publicly routable
|
||||
if manet.IsNAT64IPv4ConvertedIPv6Addr(observed) {
|
||||
return false
|
||||
}
|
||||
|
||||
// we should only use ObservedAddr when our connection's LocalAddr is one
|
||||
// of our ListenAddrs. If we Dial out using an ephemeral addr, knowing that
|
||||
// address's external mapping is not very useful because the port will not be
|
||||
// the same as the listen addr.
|
||||
ifaceaddrs, err := network.InterfaceListenAddresses()
|
||||
if err != nil {
|
||||
log.Infof("failed to get interface listen addrs", err)
|
||||
return false
|
||||
}
|
||||
|
||||
normalizer, canNormalize := host.(normalizeMultiaddrer)
|
||||
|
||||
if canNormalize {
|
||||
for i, a := range ifaceaddrs {
|
||||
ifaceaddrs[i] = normalizer.NormalizeMultiaddr(a)
|
||||
}
|
||||
}
|
||||
|
||||
local := conn.LocalMultiaddr()
|
||||
if canNormalize {
|
||||
local = normalizer.NormalizeMultiaddr(local)
|
||||
}
|
||||
|
||||
listenAddrs := network.ListenAddresses()
|
||||
if canNormalize {
|
||||
for i, a := range listenAddrs {
|
||||
listenAddrs[i] = normalizer.NormalizeMultiaddr(a)
|
||||
}
|
||||
}
|
||||
|
||||
if !ma.Contains(ifaceaddrs, local) && !ma.Contains(listenAddrs, local) {
|
||||
// not in our list
|
||||
return false
|
||||
}
|
||||
|
||||
hostAddrs := host.Addrs()
|
||||
if canNormalize {
|
||||
for i, a := range hostAddrs {
|
||||
hostAddrs[i] = normalizer.NormalizeMultiaddr(a)
|
||||
}
|
||||
}
|
||||
|
||||
// We should reject the connection if the observation doesn't match the
|
||||
// transports of one of our advertised addresses.
|
||||
if !HasConsistentTransport(observed, hostAddrs) &&
|
||||
!HasConsistentTransport(observed, listenAddrs) {
|
||||
log.Debugw(
|
||||
"observed multiaddr doesn't match the transports of any announced addresses",
|
||||
"from", conn.RemoteMultiaddr(),
|
||||
"observed", observed,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) maybeRecordObservation(conn network.Conn, observed ma.Multiaddr) {
|
||||
shouldRecord := shouldRecordObservation(oas.host, oas.host.Network(), conn, observed)
|
||||
if shouldRecord {
|
||||
// Ok, the observation is good, record it.
|
||||
log.Debugw("added own observed listen addr", "observed", observed)
|
||||
defer oas.addConn(conn, observed)
|
||||
|
||||
oas.mu.Lock()
|
||||
defer oas.mu.Unlock()
|
||||
oas.recordObservationUnlocked(conn, observed)
|
||||
|
||||
if oas.reachability == network.ReachabilityPrivate {
|
||||
oas.emitAllNATTypes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) recordObservationUnlocked(conn network.Conn, observed ma.Multiaddr) {
|
||||
now := time.Now()
|
||||
observerString := observerGroup(conn.RemoteMultiaddr())
|
||||
localString := string(conn.LocalMultiaddr().Bytes())
|
||||
ob := observation{
|
||||
seenTime: now,
|
||||
inbound: conn.Stat().Direction == network.DirInbound,
|
||||
}
|
||||
|
||||
// check if observed address seen yet, if so, update it
|
||||
for _, observedAddr := range oas.addrs[localString] {
|
||||
if observedAddr.addr.Equal(observed) {
|
||||
// Don't trump an outbound observation with an inbound
|
||||
// one.
|
||||
wasInbound := observedAddr.seenBy[observerString].inbound
|
||||
isInbound := ob.inbound
|
||||
ob.inbound = isInbound || wasInbound
|
||||
|
||||
if !wasInbound && isInbound {
|
||||
observedAddr.numInbound++
|
||||
}
|
||||
|
||||
observedAddr.seenBy[observerString] = ob
|
||||
observedAddr.lastSeen = now
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// observed address not seen yet, append it
|
||||
oa := &observedAddr{
|
||||
addr: observed,
|
||||
seenBy: map[string]observation{
|
||||
observerString: ob,
|
||||
},
|
||||
lastSeen: now,
|
||||
}
|
||||
if ob.inbound {
|
||||
oa.numInbound++
|
||||
}
|
||||
oas.addrs[localString] = append(oas.addrs[localString], oa)
|
||||
}
|
||||
|
||||
// For a given transport Protocol (TCP/UDP):
|
||||
//
|
||||
// 1. If we have an activated address, we are behind an Cone NAT.
|
||||
// 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.
|
||||
//
|
||||
// 2. If four different peers observe a different address for us on outbound connections, we
|
||||
// are MOST probably behind a Symmetric NAT.
|
||||
//
|
||||
// Please see the documentation on the enumerations for `network.NATDeviceType` for more details about these NAT Device types
|
||||
// and how they relate to NAT traversal via Hole Punching.
|
||||
func (oas *ObservedAddrManager) emitAllNATTypes() {
|
||||
var allObserved []*observedAddr
|
||||
for _, addrs := range oas.addrs {
|
||||
allObserved = append(allObserved, addrs...)
|
||||
}
|
||||
|
||||
hasChanged, natType := oas.emitSpecificNATType(allObserved, ma.P_TCP, network.NATTransportTCP, oas.currentTCPNATDeviceType)
|
||||
if hasChanged {
|
||||
oas.currentTCPNATDeviceType = natType
|
||||
}
|
||||
|
||||
hasChanged, natType = oas.emitSpecificNATType(allObserved, ma.P_UDP, network.NATTransportUDP, oas.currentUDPNATDeviceType)
|
||||
if hasChanged {
|
||||
oas.currentUDPNATDeviceType = natType
|
||||
}
|
||||
}
|
||||
|
||||
// returns true along with the new NAT device type if the NAT device type for the given protocol has changed.
|
||||
// returns false otherwise.
|
||||
func (oas *ObservedAddrManager) emitSpecificNATType(addrs []*observedAddr, protoCode int, transportProto network.NATTransportProtocol,
|
||||
currentNATType network.NATDeviceType) (bool, network.NATDeviceType) {
|
||||
now := time.Now()
|
||||
seenBy := make(map[string]struct{})
|
||||
cnt := 0
|
||||
|
||||
for _, oa := range addrs {
|
||||
_, err := oa.addr.ValueForProtocol(protoCode)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// if we have an activated addresses, it's a Cone NAT.
|
||||
if now.Sub(oa.lastSeen) <= oas.ttl && oa.activated() {
|
||||
if currentNATType != network.NATDeviceTypeCone {
|
||||
oas.emitNATDeviceTypeChanged.Emit(event.EvtNATDeviceTypeChanged{
|
||||
TransportProtocol: transportProto,
|
||||
NatDeviceType: network.NATDeviceTypeCone,
|
||||
})
|
||||
return true, network.NATDeviceTypeCone
|
||||
}
|
||||
|
||||
// our current NAT Device Type is already CONE, nothing to do here.
|
||||
return false, 0
|
||||
}
|
||||
|
||||
// An observed address on an outbound connection that has ONLY been seen by one peer
|
||||
if now.Sub(oa.lastSeen) <= oas.ttl && oa.numInbound == 0 && len(oa.seenBy) == 1 {
|
||||
cnt++
|
||||
for s := range oa.seenBy {
|
||||
seenBy[s] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If four different peers observe a different address for us on each of four outbound connections, we
|
||||
// are MOST probably behind a Symmetric NAT.
|
||||
if cnt >= ActivationThresh && len(seenBy) >= ActivationThresh {
|
||||
if currentNATType != network.NATDeviceTypeSymmetric {
|
||||
oas.emitNATDeviceTypeChanged.Emit(event.EvtNATDeviceTypeChanged{
|
||||
TransportProtocol: transportProto,
|
||||
NatDeviceType: network.NATDeviceTypeSymmetric,
|
||||
})
|
||||
return true, network.NATDeviceTypeSymmetric
|
||||
}
|
||||
}
|
||||
|
||||
return false, 0
|
||||
}
|
||||
|
||||
func (oas *ObservedAddrManager) Close() error {
|
||||
oas.closeOnce.Do(func() {
|
||||
oas.ctxCancel()
|
||||
|
||||
oas.mu.Lock()
|
||||
oas.closed = true
|
||||
oas.refreshTimer.Stop()
|
||||
oas.mu.Unlock()
|
||||
|
||||
oas.refCount.Wait()
|
||||
oas.reachabilitySub.Close()
|
||||
oas.host.Network().StopNotify((*obsAddrNotifiee)(oas))
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// observerGroup is a function that determines what part of
|
||||
// a multiaddr counts as a different observer. for example,
|
||||
// two ipfs nodes at the same IP/TCP transport would get
|
||||
// the exact same NAT mapping; they would count as the
|
||||
// same observer. This may protect against NATs who assign
|
||||
// different ports to addresses at different IP hosts, but
|
||||
// not TCP ports.
|
||||
//
|
||||
// Here, we use the root multiaddr address. This is mostly
|
||||
// IP addresses. In practice, this is what we want.
|
||||
func observerGroup(m ma.Multiaddr) string {
|
||||
// TODO: If IPv6 rolls out we should mark /64 routing zones as one group
|
||||
first, _ := ma.SplitFirst(m)
|
||||
return string(first.Bytes())
|
||||
}
|
||||
|
||||
// SetTTL sets the TTL of an observed address manager.
|
||||
func (oas *ObservedAddrManager) SetTTL(ttl time.Duration) {
|
||||
oas.mu.Lock()
|
||||
defer oas.mu.Unlock()
|
||||
if oas.closed {
|
||||
return
|
||||
}
|
||||
oas.ttl = ttl
|
||||
// refresh every ttl/2 so we don't forget observations from connected peers
|
||||
oas.refreshTimer.Reset(ttl / 2)
|
||||
}
|
||||
|
||||
// TTL gets the TTL of an observed address manager.
|
||||
func (oas *ObservedAddrManager) TTL() time.Duration {
|
||||
oas.mu.RLock()
|
||||
defer oas.mu.RUnlock()
|
||||
return oas.ttl
|
||||
}
|
||||
|
||||
type obsAddrNotifiee ObservedAddrManager
|
||||
|
||||
func (on *obsAddrNotifiee) Listen(n network.Network, a ma.Multiaddr) {}
|
||||
func (on *obsAddrNotifiee) ListenClose(n network.Network, a ma.Multiaddr) {}
|
||||
func (on *obsAddrNotifiee) Connected(n network.Network, v network.Conn) {}
|
||||
func (on *obsAddrNotifiee) Disconnected(n network.Network, v network.Conn) {
|
||||
(*ObservedAddrManager)(on).removeConn(v)
|
||||
}
|
||||
40
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/opts.go
generated
vendored
Normal file
40
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/opts.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package identify
|
||||
|
||||
type config struct {
|
||||
protocolVersion string
|
||||
userAgent string
|
||||
disableSignedPeerRecord bool
|
||||
metricsTracer MetricsTracer
|
||||
}
|
||||
|
||||
// Option is an option function for identify.
|
||||
type Option func(*config)
|
||||
|
||||
// ProtocolVersion sets the protocol version string that will be used to
|
||||
// identify the family of protocols used by the peer.
|
||||
func ProtocolVersion(s string) Option {
|
||||
return func(cfg *config) {
|
||||
cfg.protocolVersion = s
|
||||
}
|
||||
}
|
||||
|
||||
// UserAgent sets the user agent this node will identify itself with to peers.
|
||||
func UserAgent(ua string) Option {
|
||||
return func(cfg *config) {
|
||||
cfg.userAgent = ua
|
||||
}
|
||||
}
|
||||
|
||||
// DisableSignedPeerRecord disables populating signed peer records on the outgoing Identify response
|
||||
// and ONLY sends the unsigned addresses.
|
||||
func DisableSignedPeerRecord() Option {
|
||||
return func(cfg *config) {
|
||||
cfg.disableSignedPeerRecord = true
|
||||
}
|
||||
}
|
||||
|
||||
func WithMetricsTracer(tr MetricsTracer) Option {
|
||||
return func(cfg *config) {
|
||||
cfg.metricsTracer = tr
|
||||
}
|
||||
}
|
||||
219
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go
generated
vendored
Normal file
219
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: pb/identify.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Identify struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// protocolVersion determines compatibility between peers
|
||||
ProtocolVersion *string `protobuf:"bytes,5,opt,name=protocolVersion" json:"protocolVersion,omitempty"` // e.g. ipfs/1.0.0
|
||||
// agentVersion is like a UserAgent string in browsers, or client version in bittorrent
|
||||
// includes the client name and client.
|
||||
AgentVersion *string `protobuf:"bytes,6,opt,name=agentVersion" json:"agentVersion,omitempty"` // e.g. go-ipfs/0.1.0
|
||||
// publicKey is this node's public key (which also gives its node.ID)
|
||||
// - may not need to be sent, as secure channel implies it has been sent.
|
||||
// - then again, if we change / disable secure channel, may still want it.
|
||||
PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey" json:"publicKey,omitempty"`
|
||||
// listenAddrs are the multiaddrs the sender node listens for open connections on
|
||||
ListenAddrs [][]byte `protobuf:"bytes,2,rep,name=listenAddrs" json:"listenAddrs,omitempty"`
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
|
||||
// this is useful information to convey to the other side, as it helps the remote endpoint
|
||||
// determine whether its connection to the local peer goes through NAT.
|
||||
ObservedAddr []byte `protobuf:"bytes,4,opt,name=observedAddr" json:"observedAddr,omitempty"`
|
||||
// protocols are the services this node is running
|
||||
Protocols []string `protobuf:"bytes,3,rep,name=protocols" json:"protocols,omitempty"`
|
||||
// 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.
|
||||
SignedPeerRecord []byte `protobuf:"bytes,8,opt,name=signedPeerRecord" json:"signedPeerRecord,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Identify) Reset() {
|
||||
*x = Identify{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_identify_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Identify) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Identify) ProtoMessage() {}
|
||||
|
||||
func (x *Identify) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_identify_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Identify.ProtoReflect.Descriptor instead.
|
||||
func (*Identify) Descriptor() ([]byte, []int) {
|
||||
return file_pb_identify_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Identify) GetProtocolVersion() string {
|
||||
if x != nil && x.ProtocolVersion != nil {
|
||||
return *x.ProtocolVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identify) GetAgentVersion() string {
|
||||
if x != nil && x.AgentVersion != nil {
|
||||
return *x.AgentVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Identify) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Identify) GetListenAddrs() [][]byte {
|
||||
if x != nil {
|
||||
return x.ListenAddrs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Identify) GetObservedAddr() []byte {
|
||||
if x != nil {
|
||||
return x.ObservedAddr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Identify) GetProtocols() []string {
|
||||
if x != nil {
|
||||
return x.Protocols
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Identify) GetSignedPeerRecord() []byte {
|
||||
if x != nil {
|
||||
return x.SignedPeerRecord
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pb_identify_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pb_identify_proto_rawDesc = []byte{
|
||||
0x0a, 0x11, 0x70, 0x62, 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x62,
|
||||
0x22, 0x86, 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x28, 0x0a,
|
||||
0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61,
|
||||
0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
|
||||
0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x69, 0x73,
|
||||
0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b,
|
||||
0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6f,
|
||||
0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x2a, 0x0a,
|
||||
0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72,
|
||||
0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50,
|
||||
0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pb_identify_proto_rawDescOnce sync.Once
|
||||
file_pb_identify_proto_rawDescData = file_pb_identify_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pb_identify_proto_rawDescGZIP() []byte {
|
||||
file_pb_identify_proto_rawDescOnce.Do(func() {
|
||||
file_pb_identify_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_identify_proto_rawDescData)
|
||||
})
|
||||
return file_pb_identify_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pb_identify_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_pb_identify_proto_goTypes = []interface{}{
|
||||
(*Identify)(nil), // 0: identify.pb.Identify
|
||||
}
|
||||
var file_pb_identify_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pb_identify_proto_init() }
|
||||
func file_pb_identify_proto_init() {
|
||||
if File_pb_identify_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pb_identify_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Identify); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_pb_identify_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pb_identify_proto_goTypes,
|
||||
DependencyIndexes: file_pb_identify_proto_depIdxs,
|
||||
MessageInfos: file_pb_identify_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pb_identify_proto = out.File
|
||||
file_pb_identify_proto_rawDesc = nil
|
||||
file_pb_identify_proto_goTypes = nil
|
||||
file_pb_identify_proto_depIdxs = nil
|
||||
}
|
||||
36
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto
generated
vendored
Normal file
36
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package identify.pb;
|
||||
|
||||
message Identify {
|
||||
|
||||
// protocolVersion determines compatibility between peers
|
||||
optional string protocolVersion = 5; // e.g. ipfs/1.0.0
|
||||
|
||||
// agentVersion is like a UserAgent string in browsers, or client version in bittorrent
|
||||
// includes the client name and client.
|
||||
optional string agentVersion = 6; // e.g. go-ipfs/0.1.0
|
||||
|
||||
// publicKey is this node's public key (which also gives its node.ID)
|
||||
// - may not need to be sent, as secure channel implies it has been sent.
|
||||
// - then again, if we change / disable secure channel, may still want it.
|
||||
optional bytes publicKey = 1;
|
||||
|
||||
// listenAddrs are the multiaddrs the sender node listens for open connections on
|
||||
repeated bytes listenAddrs = 2;
|
||||
|
||||
// oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
|
||||
// this is useful information to convey to the other side, as it helps the remote endpoint
|
||||
// determine whether its connection to the local peer goes through NAT.
|
||||
optional bytes observedAddr = 4;
|
||||
|
||||
// protocols are the services this node is running
|
||||
repeated string protocols = 3;
|
||||
|
||||
// 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.
|
||||
optional bytes signedPeerRecord = 8;
|
||||
}
|
||||
43
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/user_agent.go
generated
vendored
Normal file
43
vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/user_agent.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package identify
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bi, ok := debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
version := bi.Main.Version
|
||||
// version will only be non-empty if built as a dependency of another module
|
||||
if version == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if version != "(devel)" {
|
||||
defaultUserAgent = fmt.Sprintf("%s@%s", bi.Main.Path, bi.Main.Version)
|
||||
return
|
||||
}
|
||||
|
||||
var revision string
|
||||
var dirty bool
|
||||
for _, bs := range bi.Settings {
|
||||
switch bs.Key {
|
||||
case "vcs.revision":
|
||||
revision = bs.Value
|
||||
if len(revision) > 9 {
|
||||
revision = revision[:9]
|
||||
}
|
||||
case "vcs.modified":
|
||||
if bs.Value == "true" {
|
||||
dirty = true
|
||||
}
|
||||
}
|
||||
}
|
||||
defaultUserAgent = fmt.Sprintf("%s@%s", bi.Main.Path, revision)
|
||||
if dirty {
|
||||
defaultUserAgent += "-dirty"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user