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:
450
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/autonat.go
generated
vendored
Normal file
450
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/autonat.go
generated
vendored
Normal file
@@ -0,0 +1,450 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"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"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
var log = logging.Logger("autonat")
|
||||
|
||||
const maxConfidence = 3
|
||||
|
||||
// AmbientAutoNAT is the implementation of ambient NAT autodiscovery
|
||||
type AmbientAutoNAT struct {
|
||||
host host.Host
|
||||
|
||||
*config
|
||||
|
||||
ctx context.Context
|
||||
ctxCancel context.CancelFunc // is closed when Close is called
|
||||
backgroundRunning chan struct{} // is closed when the background go routine exits
|
||||
|
||||
inboundConn chan network.Conn
|
||||
dialResponses chan error
|
||||
// status is an autoNATResult reflecting current status.
|
||||
status atomic.Pointer[network.Reachability]
|
||||
// Reflects the confidence on of the NATStatus being private, as a single
|
||||
// dialback may fail for reasons unrelated to NAT.
|
||||
// If it is <3, then multiple autoNAT peers may be contacted for dialback
|
||||
// If only a single autoNAT peer is known, then the confidence increases
|
||||
// for each failure until it reaches 3.
|
||||
confidence int
|
||||
lastInbound time.Time
|
||||
lastProbeTry time.Time
|
||||
lastProbe time.Time
|
||||
recentProbes map[peer.ID]time.Time
|
||||
|
||||
service *autoNATService
|
||||
|
||||
emitReachabilityChanged event.Emitter
|
||||
subscriber event.Subscription
|
||||
}
|
||||
|
||||
// StaticAutoNAT is a simple AutoNAT implementation when a single NAT status is desired.
|
||||
type StaticAutoNAT struct {
|
||||
host host.Host
|
||||
reachability network.Reachability
|
||||
service *autoNATService
|
||||
}
|
||||
|
||||
// New creates a new NAT autodiscovery system attached to a host
|
||||
func New(h host.Host, options ...Option) (AutoNAT, error) {
|
||||
var err error
|
||||
conf := new(config)
|
||||
conf.host = h
|
||||
conf.dialPolicy.host = h
|
||||
|
||||
if err = defaults(conf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if conf.addressFunc == nil {
|
||||
conf.addressFunc = h.Addrs
|
||||
}
|
||||
|
||||
for _, o := range options {
|
||||
if err = o(conf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
emitReachabilityChanged, _ := h.EventBus().Emitter(new(event.EvtLocalReachabilityChanged), eventbus.Stateful)
|
||||
|
||||
var service *autoNATService
|
||||
if (!conf.forceReachability || conf.reachability == network.ReachabilityPublic) && conf.dialer != nil {
|
||||
service, err = newAutoNATService(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
service.Enable()
|
||||
}
|
||||
|
||||
if conf.forceReachability {
|
||||
emitReachabilityChanged.Emit(event.EvtLocalReachabilityChanged{Reachability: conf.reachability})
|
||||
|
||||
return &StaticAutoNAT{
|
||||
host: h,
|
||||
reachability: conf.reachability,
|
||||
service: service,
|
||||
}, nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
as := &AmbientAutoNAT{
|
||||
ctx: ctx,
|
||||
ctxCancel: cancel,
|
||||
backgroundRunning: make(chan struct{}),
|
||||
host: h,
|
||||
config: conf,
|
||||
inboundConn: make(chan network.Conn, 5),
|
||||
dialResponses: make(chan error, 1),
|
||||
|
||||
emitReachabilityChanged: emitReachabilityChanged,
|
||||
service: service,
|
||||
recentProbes: make(map[peer.ID]time.Time),
|
||||
}
|
||||
reachability := network.ReachabilityUnknown
|
||||
as.status.Store(&reachability)
|
||||
|
||||
subscriber, err := as.host.EventBus().Subscribe(
|
||||
[]any{new(event.EvtLocalAddressesUpdated), new(event.EvtPeerIdentificationCompleted)},
|
||||
eventbus.Name("autonat"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
as.subscriber = subscriber
|
||||
|
||||
h.Network().Notify(as)
|
||||
go as.background()
|
||||
|
||||
return as, nil
|
||||
}
|
||||
|
||||
// Status returns the AutoNAT observed reachability status.
|
||||
func (as *AmbientAutoNAT) Status() network.Reachability {
|
||||
s := as.status.Load()
|
||||
return *s
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) emitStatus() {
|
||||
status := *as.status.Load()
|
||||
as.emitReachabilityChanged.Emit(event.EvtLocalReachabilityChanged{Reachability: status})
|
||||
if as.metricsTracer != nil {
|
||||
as.metricsTracer.ReachabilityStatus(status)
|
||||
}
|
||||
}
|
||||
|
||||
func ipInList(candidate ma.Multiaddr, list []ma.Multiaddr) bool {
|
||||
candidateIP, _ := manet.ToIP(candidate)
|
||||
for _, i := range list {
|
||||
if ip, err := manet.ToIP(i); err == nil && ip.Equal(candidateIP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) background() {
|
||||
defer close(as.backgroundRunning)
|
||||
// wait a bit for the node to come online and establish some connections
|
||||
// before starting autodetection
|
||||
delay := as.config.bootDelay
|
||||
|
||||
subChan := as.subscriber.Out()
|
||||
defer as.subscriber.Close()
|
||||
defer as.emitReachabilityChanged.Close()
|
||||
|
||||
timer := time.NewTimer(delay)
|
||||
defer timer.Stop()
|
||||
timerRunning := true
|
||||
retryProbe := false
|
||||
for {
|
||||
select {
|
||||
// new inbound connection.
|
||||
case conn := <-as.inboundConn:
|
||||
localAddrs := as.host.Addrs()
|
||||
if manet.IsPublicAddr(conn.RemoteMultiaddr()) &&
|
||||
!ipInList(conn.RemoteMultiaddr(), localAddrs) {
|
||||
as.lastInbound = time.Now()
|
||||
}
|
||||
|
||||
case e := <-subChan:
|
||||
switch e := e.(type) {
|
||||
case event.EvtLocalAddressesUpdated:
|
||||
// On local address update, reduce confidence from maximum so that we schedule
|
||||
// the next probe sooner
|
||||
if as.confidence == maxConfidence {
|
||||
as.confidence--
|
||||
}
|
||||
case event.EvtPeerIdentificationCompleted:
|
||||
if s, err := as.host.Peerstore().SupportsProtocols(e.Peer, AutoNATProto); err == nil && len(s) > 0 {
|
||||
currentStatus := *as.status.Load()
|
||||
if currentStatus == network.ReachabilityUnknown {
|
||||
as.tryProbe(e.Peer)
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Errorf("unknown event type: %T", e)
|
||||
}
|
||||
|
||||
// probe finished.
|
||||
case err, ok := <-as.dialResponses:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if IsDialRefused(err) {
|
||||
retryProbe = true
|
||||
} else {
|
||||
as.handleDialResponse(err)
|
||||
}
|
||||
case <-timer.C:
|
||||
peer := as.getPeerToProbe()
|
||||
as.tryProbe(peer)
|
||||
timerRunning = false
|
||||
retryProbe = false
|
||||
case <-as.ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
// Drain the timer channel if it hasn't fired in preparation for Resetting it.
|
||||
if timerRunning && !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
timer.Reset(as.scheduleProbe(retryProbe))
|
||||
timerRunning = true
|
||||
}
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) cleanupRecentProbes() {
|
||||
fixedNow := time.Now()
|
||||
for k, v := range as.recentProbes {
|
||||
if fixedNow.Sub(v) > as.throttlePeerPeriod {
|
||||
delete(as.recentProbes, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scheduleProbe calculates when the next probe should be scheduled for.
|
||||
func (as *AmbientAutoNAT) scheduleProbe(retryProbe bool) time.Duration {
|
||||
// Our baseline is a probe every 'AutoNATRefreshInterval'
|
||||
// This is modulated by:
|
||||
// * if we are in an unknown state, have low confidence, or we want to retry because a probe was refused that
|
||||
// should drop to 'AutoNATRetryInterval'
|
||||
// * recent inbound connections (implying continued connectivity) should decrease the retry when public
|
||||
// * recent inbound connections when not public mean we should try more actively to see if we're public.
|
||||
fixedNow := time.Now()
|
||||
currentStatus := *as.status.Load()
|
||||
|
||||
nextProbe := fixedNow
|
||||
// Don't look for peers in the peer store more than once per second.
|
||||
if !as.lastProbeTry.IsZero() {
|
||||
backoff := as.lastProbeTry.Add(time.Second)
|
||||
if backoff.After(nextProbe) {
|
||||
nextProbe = backoff
|
||||
}
|
||||
}
|
||||
if !as.lastProbe.IsZero() {
|
||||
untilNext := as.config.refreshInterval
|
||||
if retryProbe {
|
||||
untilNext = as.config.retryInterval
|
||||
} else if currentStatus == network.ReachabilityUnknown {
|
||||
untilNext = as.config.retryInterval
|
||||
} else if as.confidence < maxConfidence {
|
||||
untilNext = as.config.retryInterval
|
||||
} else if currentStatus == network.ReachabilityPublic && as.lastInbound.After(as.lastProbe) {
|
||||
untilNext *= 2
|
||||
} else if currentStatus != network.ReachabilityPublic && as.lastInbound.After(as.lastProbe) {
|
||||
untilNext /= 5
|
||||
}
|
||||
|
||||
if as.lastProbe.Add(untilNext).After(nextProbe) {
|
||||
nextProbe = as.lastProbe.Add(untilNext)
|
||||
}
|
||||
}
|
||||
if as.metricsTracer != nil {
|
||||
as.metricsTracer.NextProbeTime(nextProbe)
|
||||
}
|
||||
return nextProbe.Sub(fixedNow)
|
||||
}
|
||||
|
||||
// handleDialResponse updates the current status based on dial response.
|
||||
func (as *AmbientAutoNAT) handleDialResponse(dialErr error) {
|
||||
var observation network.Reachability
|
||||
switch {
|
||||
case dialErr == nil:
|
||||
observation = network.ReachabilityPublic
|
||||
case IsDialError(dialErr):
|
||||
observation = network.ReachabilityPrivate
|
||||
default:
|
||||
observation = network.ReachabilityUnknown
|
||||
}
|
||||
|
||||
as.recordObservation(observation)
|
||||
}
|
||||
|
||||
// recordObservation updates NAT status and confidence
|
||||
func (as *AmbientAutoNAT) recordObservation(observation network.Reachability) {
|
||||
|
||||
currentStatus := *as.status.Load()
|
||||
|
||||
if observation == network.ReachabilityPublic {
|
||||
changed := false
|
||||
if currentStatus != network.ReachabilityPublic {
|
||||
// Aggressively switch to public from other states ignoring confidence
|
||||
log.Debugf("NAT status is public")
|
||||
|
||||
// we are flipping our NATStatus, so confidence drops to 0
|
||||
as.confidence = 0
|
||||
if as.service != nil {
|
||||
as.service.Enable()
|
||||
}
|
||||
changed = true
|
||||
} else if as.confidence < maxConfidence {
|
||||
as.confidence++
|
||||
}
|
||||
as.status.Store(&observation)
|
||||
if changed {
|
||||
as.emitStatus()
|
||||
}
|
||||
} else if observation == network.ReachabilityPrivate {
|
||||
if currentStatus != network.ReachabilityPrivate {
|
||||
if as.confidence > 0 {
|
||||
as.confidence--
|
||||
} else {
|
||||
log.Debugf("NAT status is private")
|
||||
|
||||
// we are flipping our NATStatus, so confidence drops to 0
|
||||
as.confidence = 0
|
||||
as.status.Store(&observation)
|
||||
if as.service != nil {
|
||||
as.service.Disable()
|
||||
}
|
||||
as.emitStatus()
|
||||
}
|
||||
} else if as.confidence < maxConfidence {
|
||||
as.confidence++
|
||||
as.status.Store(&observation)
|
||||
}
|
||||
} else if as.confidence > 0 {
|
||||
// don't just flip to unknown, reduce confidence first
|
||||
as.confidence--
|
||||
} else {
|
||||
log.Debugf("NAT status is unknown")
|
||||
as.status.Store(&observation)
|
||||
if currentStatus != network.ReachabilityUnknown {
|
||||
if as.service != nil {
|
||||
as.service.Enable()
|
||||
}
|
||||
as.emitStatus()
|
||||
}
|
||||
}
|
||||
if as.metricsTracer != nil {
|
||||
as.metricsTracer.ReachabilityStatusConfidence(as.confidence)
|
||||
}
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) tryProbe(p peer.ID) bool {
|
||||
as.lastProbeTry = time.Now()
|
||||
if p.Validate() != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if lastTime, ok := as.recentProbes[p]; ok {
|
||||
if time.Since(lastTime) < as.throttlePeerPeriod {
|
||||
return false
|
||||
}
|
||||
}
|
||||
as.cleanupRecentProbes()
|
||||
|
||||
info := as.host.Peerstore().PeerInfo(p)
|
||||
|
||||
if !as.config.dialPolicy.skipPeer(info.Addrs) {
|
||||
as.recentProbes[p] = time.Now()
|
||||
as.lastProbe = time.Now()
|
||||
go as.probe(&info)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) probe(pi *peer.AddrInfo) {
|
||||
cli := NewAutoNATClient(as.host, as.config.addressFunc, as.metricsTracer)
|
||||
ctx, cancel := context.WithTimeout(as.ctx, as.config.requestTimeout)
|
||||
defer cancel()
|
||||
|
||||
err := cli.DialBack(ctx, pi.ID)
|
||||
log.Debugf("Dialback through peer %s completed: err: %s", pi.ID, err)
|
||||
|
||||
select {
|
||||
case as.dialResponses <- err:
|
||||
case <-as.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) getPeerToProbe() peer.ID {
|
||||
peers := as.host.Network().Peers()
|
||||
if len(peers) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
candidates := make([]peer.ID, 0, len(peers))
|
||||
|
||||
for _, p := range peers {
|
||||
info := as.host.Peerstore().PeerInfo(p)
|
||||
// Exclude peers which don't support the autonat protocol.
|
||||
if proto, err := as.host.Peerstore().SupportsProtocols(p, AutoNATProto); len(proto) == 0 || err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Exclude peers in backoff.
|
||||
if lastTime, ok := as.recentProbes[p]; ok {
|
||||
if time.Since(lastTime) < as.throttlePeerPeriod {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if as.config.dialPolicy.skipPeer(info.Addrs) {
|
||||
continue
|
||||
}
|
||||
candidates = append(candidates, p)
|
||||
}
|
||||
|
||||
if len(candidates) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
return candidates[rand.Intn(len(candidates))]
|
||||
}
|
||||
|
||||
func (as *AmbientAutoNAT) Close() error {
|
||||
as.ctxCancel()
|
||||
if as.service != nil {
|
||||
as.service.Disable()
|
||||
}
|
||||
<-as.backgroundRunning
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns the AutoNAT observed reachability status.
|
||||
func (s *StaticAutoNAT) Status() network.Reachability {
|
||||
return s.reachability
|
||||
}
|
||||
|
||||
func (s *StaticAutoNAT) Close() error {
|
||||
if s.service != nil {
|
||||
s.service.Disable()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
122
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/client.go
generated
vendored
Normal file
122
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/client.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"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/p2p/host/autonat/pb"
|
||||
|
||||
"github.com/libp2p/go-msgio/pbio"
|
||||
)
|
||||
|
||||
// NewAutoNATClient creates a fresh instance of an AutoNATClient
|
||||
// If addrFunc is nil, h.Addrs will be used
|
||||
func NewAutoNATClient(h host.Host, addrFunc AddrFunc, mt MetricsTracer) Client {
|
||||
if addrFunc == nil {
|
||||
addrFunc = h.Addrs
|
||||
}
|
||||
return &client{h: h, addrFunc: addrFunc, mt: mt}
|
||||
}
|
||||
|
||||
type client struct {
|
||||
h host.Host
|
||||
addrFunc AddrFunc
|
||||
mt MetricsTracer
|
||||
}
|
||||
|
||||
// DialBack asks peer p to dial us back on all addresses returned by the addrFunc.
|
||||
// It blocks until we've received a response from the peer.
|
||||
//
|
||||
// Note: A returned error Message_E_DIAL_ERROR does not imply that the server
|
||||
// actually performed a dial attempt. Servers that run a version < v0.20.0 also
|
||||
// return Message_E_DIAL_ERROR if the dial was skipped due to the dialPolicy.
|
||||
func (c *client) DialBack(ctx context.Context, p peer.ID) error {
|
||||
s, err := c.h.NewStream(ctx, p, AutoNATProto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Scope().SetService(ServiceName); err != nil {
|
||||
log.Debugf("error attaching stream to autonat service: %s", err)
|
||||
s.Reset()
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Scope().ReserveMemory(maxMsgSize, network.ReservationPriorityAlways); err != nil {
|
||||
log.Debugf("error reserving memory for autonat stream: %s", err)
|
||||
s.Reset()
|
||||
return err
|
||||
}
|
||||
defer s.Scope().ReleaseMemory(maxMsgSize)
|
||||
|
||||
s.SetDeadline(time.Now().Add(streamTimeout))
|
||||
// Might as well just reset the stream. Once we get to this point, we
|
||||
// don't care about being nice.
|
||||
defer s.Close()
|
||||
|
||||
r := pbio.NewDelimitedReader(s, maxMsgSize)
|
||||
w := pbio.NewDelimitedWriter(s)
|
||||
|
||||
req := newDialMessage(peer.AddrInfo{ID: c.h.ID(), Addrs: c.addrFunc()})
|
||||
if err := w.WriteMsg(req); err != nil {
|
||||
s.Reset()
|
||||
return err
|
||||
}
|
||||
|
||||
var res pb.Message
|
||||
if err := r.ReadMsg(&res); err != nil {
|
||||
s.Reset()
|
||||
return err
|
||||
}
|
||||
if res.GetType() != pb.Message_DIAL_RESPONSE {
|
||||
s.Reset()
|
||||
return fmt.Errorf("unexpected response: %s", res.GetType().String())
|
||||
}
|
||||
|
||||
status := res.GetDialResponse().GetStatus()
|
||||
if c.mt != nil {
|
||||
c.mt.ReceivedDialResponse(status)
|
||||
}
|
||||
switch status {
|
||||
case pb.Message_OK:
|
||||
return nil
|
||||
default:
|
||||
return Error{Status: status, Text: res.GetDialResponse().GetStatusText()}
|
||||
}
|
||||
}
|
||||
|
||||
// Error wraps errors signalled by AutoNAT services
|
||||
type Error struct {
|
||||
Status pb.Message_ResponseStatus
|
||||
Text string
|
||||
}
|
||||
|
||||
func (e Error) Error() string {
|
||||
return fmt.Sprintf("AutoNAT error: %s (%s)", e.Text, e.Status.String())
|
||||
}
|
||||
|
||||
// IsDialError returns true if the error was due to a dial back failure
|
||||
func (e Error) IsDialError() bool {
|
||||
return e.Status == pb.Message_E_DIAL_ERROR
|
||||
}
|
||||
|
||||
// IsDialRefused returns true if the error was due to a refusal to dial back
|
||||
func (e Error) IsDialRefused() bool {
|
||||
return e.Status == pb.Message_E_DIAL_REFUSED
|
||||
}
|
||||
|
||||
// IsDialError returns true if the AutoNAT peer signalled an error dialing back
|
||||
func IsDialError(e error) bool {
|
||||
ae, ok := e.(Error)
|
||||
return ok && ae.IsDialError()
|
||||
}
|
||||
|
||||
// IsDialRefused returns true if the AutoNAT peer signalled refusal to dial back
|
||||
func IsDialRefused(e error) bool {
|
||||
ae, ok := e.(Error)
|
||||
return ok && ae.IsDialRefused()
|
||||
}
|
||||
95
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/dialpolicy.go
generated
vendored
Normal file
95
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/dialpolicy.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
type dialPolicy struct {
|
||||
allowSelfDials bool
|
||||
host host.Host
|
||||
}
|
||||
|
||||
// skipDial indicates that a multiaddress isn't worth attempted dialing.
|
||||
// The same logic is used when the autonat client is considering if
|
||||
// a remote peer is worth using as a server, and when the server is
|
||||
// considering if a requested client is worth dialing back.
|
||||
func (d *dialPolicy) skipDial(addr ma.Multiaddr) bool {
|
||||
// skip relay addresses
|
||||
_, err := addr.ValueForProtocol(ma.P_CIRCUIT)
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if d.allowSelfDials {
|
||||
return false
|
||||
}
|
||||
|
||||
// skip private network (unroutable) addresses
|
||||
if !manet.IsPublicAddr(addr) {
|
||||
return true
|
||||
}
|
||||
candidateIP, err := manet.ToIP(addr)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
// Skip dialing addresses we believe are the local node's
|
||||
for _, localAddr := range d.host.Addrs() {
|
||||
localIP, err := manet.ToIP(localAddr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if localIP.Equal(candidateIP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// skipPeer indicates that the collection of multiaddresses representing a peer
|
||||
// isn't worth attempted dialing. If one of the addresses matches an address
|
||||
// we believe is ours, we exclude the peer, even if there are other valid
|
||||
// public addresses in the list.
|
||||
func (d *dialPolicy) skipPeer(addrs []ma.Multiaddr) bool {
|
||||
localAddrs := d.host.Addrs()
|
||||
localHosts := make([]net.IP, 0)
|
||||
for _, lAddr := range localAddrs {
|
||||
if _, err := lAddr.ValueForProtocol(ma.P_CIRCUIT); err != nil && manet.IsPublicAddr(lAddr) {
|
||||
lIP, err := manet.ToIP(lAddr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
localHosts = append(localHosts, lIP)
|
||||
}
|
||||
}
|
||||
|
||||
// if a public IP of the peer is one of ours: skip the peer.
|
||||
goodPublic := false
|
||||
for _, addr := range addrs {
|
||||
if _, err := addr.ValueForProtocol(ma.P_CIRCUIT); err != nil && manet.IsPublicAddr(addr) {
|
||||
aIP, err := manet.ToIP(addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, lIP := range localHosts {
|
||||
if lIP.Equal(aIP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
goodPublic = true
|
||||
}
|
||||
}
|
||||
|
||||
if d.allowSelfDials {
|
||||
return false
|
||||
}
|
||||
|
||||
return !goodPublic
|
||||
}
|
||||
31
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/interface.go
generated
vendored
Normal file
31
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/interface.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// AutoNAT is the interface for NAT autodiscovery
|
||||
type AutoNAT interface {
|
||||
// Status returns the current NAT status
|
||||
Status() network.Reachability
|
||||
io.Closer
|
||||
}
|
||||
|
||||
// Client is a stateless client interface to AutoNAT peers
|
||||
type Client interface {
|
||||
// DialBack requests from a peer providing AutoNAT services to test dial back
|
||||
// and report the address on a successful connection.
|
||||
DialBack(ctx context.Context, p peer.ID) error
|
||||
}
|
||||
|
||||
// AddrFunc is a function returning the candidate addresses for the local host.
|
||||
type AddrFunc func() []ma.Multiaddr
|
||||
|
||||
// Option is an Autonat option for configuration
|
||||
type Option func(*config) error
|
||||
162
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/metrics.go
generated
vendored
Normal file
162
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/metrics.go
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/autonat/pb"
|
||||
"github.com/libp2p/go-libp2p/p2p/metricshelper"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const metricNamespace = "libp2p_autonat"
|
||||
|
||||
var (
|
||||
reachabilityStatus = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "reachability_status",
|
||||
Help: "Current node reachability",
|
||||
},
|
||||
)
|
||||
reachabilityStatusConfidence = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "reachability_status_confidence",
|
||||
Help: "Node reachability status confidence",
|
||||
},
|
||||
)
|
||||
receivedDialResponseTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "received_dial_response_total",
|
||||
Help: "Count of dial responses for client",
|
||||
},
|
||||
[]string{"response_status"},
|
||||
)
|
||||
outgoingDialResponseTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "outgoing_dial_response_total",
|
||||
Help: "Count of dial responses for server",
|
||||
},
|
||||
[]string{"response_status"},
|
||||
)
|
||||
outgoingDialRefusedTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "outgoing_dial_refused_total",
|
||||
Help: "Count of dial requests refused by server",
|
||||
},
|
||||
[]string{"refusal_reason"},
|
||||
)
|
||||
nextProbeTimestamp = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "next_probe_timestamp",
|
||||
Help: "Time of next probe",
|
||||
},
|
||||
)
|
||||
collectors = []prometheus.Collector{
|
||||
reachabilityStatus,
|
||||
reachabilityStatusConfidence,
|
||||
receivedDialResponseTotal,
|
||||
outgoingDialResponseTotal,
|
||||
outgoingDialRefusedTotal,
|
||||
nextProbeTimestamp,
|
||||
}
|
||||
)
|
||||
|
||||
type MetricsTracer interface {
|
||||
ReachabilityStatus(status network.Reachability)
|
||||
ReachabilityStatusConfidence(confidence int)
|
||||
ReceivedDialResponse(status pb.Message_ResponseStatus)
|
||||
OutgoingDialResponse(status pb.Message_ResponseStatus)
|
||||
OutgoingDialRefused(reason string)
|
||||
NextProbeTime(t time.Time)
|
||||
}
|
||||
|
||||
func getResponseStatus(status pb.Message_ResponseStatus) string {
|
||||
var s string
|
||||
switch status {
|
||||
case pb.Message_OK:
|
||||
s = "ok"
|
||||
case pb.Message_E_DIAL_ERROR:
|
||||
s = "dial error"
|
||||
case pb.Message_E_DIAL_REFUSED:
|
||||
s = "dial refused"
|
||||
case pb.Message_E_BAD_REQUEST:
|
||||
s = "bad request"
|
||||
case pb.Message_E_INTERNAL_ERROR:
|
||||
s = "internal error"
|
||||
default:
|
||||
s = "unknown"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
const (
|
||||
rate_limited = "rate limited"
|
||||
dial_blocked = "dial blocked"
|
||||
no_valid_address = "no valid address"
|
||||
)
|
||||
|
||||
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 (mt *metricsTracer) ReachabilityStatus(status network.Reachability) {
|
||||
reachabilityStatus.Set(float64(status))
|
||||
}
|
||||
|
||||
func (mt *metricsTracer) ReachabilityStatusConfidence(confidence int) {
|
||||
reachabilityStatusConfidence.Set(float64(confidence))
|
||||
}
|
||||
|
||||
func (mt *metricsTracer) ReceivedDialResponse(status pb.Message_ResponseStatus) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
*tags = append(*tags, getResponseStatus(status))
|
||||
receivedDialResponseTotal.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (mt *metricsTracer) OutgoingDialResponse(status pb.Message_ResponseStatus) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
*tags = append(*tags, getResponseStatus(status))
|
||||
outgoingDialResponseTotal.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (mt *metricsTracer) OutgoingDialRefused(reason string) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
*tags = append(*tags, reason)
|
||||
outgoingDialRefusedTotal.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (mt *metricsTracer) NextProbeTime(t time.Time) {
|
||||
nextProbeTimestamp.Set(float64(t.Unix()))
|
||||
}
|
||||
30
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/notify.go
generated
vendored
Normal file
30
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/notify.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
)
|
||||
|
||||
var _ network.Notifiee = (*AmbientAutoNAT)(nil)
|
||||
|
||||
// Listen is part of the network.Notifiee interface
|
||||
func (as *AmbientAutoNAT) Listen(net network.Network, a ma.Multiaddr) {}
|
||||
|
||||
// ListenClose is part of the network.Notifiee interface
|
||||
func (as *AmbientAutoNAT) ListenClose(net network.Network, a ma.Multiaddr) {}
|
||||
|
||||
// Connected is part of the network.Notifiee interface
|
||||
func (as *AmbientAutoNAT) Connected(net network.Network, c network.Conn) {
|
||||
if c.Stat().Direction == network.DirInbound &&
|
||||
manet.IsPublicAddr(c.RemoteMultiaddr()) {
|
||||
select {
|
||||
case as.inboundConn <- c:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnected is part of the network.Notifiee interface
|
||||
func (as *AmbientAutoNAT) Disconnected(net network.Network, c network.Conn) {}
|
||||
153
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/options.go
generated
vendored
Normal file
153
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/options.go
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
)
|
||||
|
||||
// config holds configurable options for the autonat subsystem.
|
||||
type config struct {
|
||||
host host.Host
|
||||
|
||||
addressFunc AddrFunc
|
||||
dialPolicy dialPolicy
|
||||
dialer network.Network
|
||||
forceReachability bool
|
||||
reachability network.Reachability
|
||||
metricsTracer MetricsTracer
|
||||
|
||||
// client
|
||||
bootDelay time.Duration
|
||||
retryInterval time.Duration
|
||||
refreshInterval time.Duration
|
||||
requestTimeout time.Duration
|
||||
throttlePeerPeriod time.Duration
|
||||
|
||||
// server
|
||||
dialTimeout time.Duration
|
||||
maxPeerAddresses int
|
||||
throttleGlobalMax int
|
||||
throttlePeerMax int
|
||||
throttleResetPeriod time.Duration
|
||||
throttleResetJitter time.Duration
|
||||
}
|
||||
|
||||
var defaults = func(c *config) error {
|
||||
c.bootDelay = 15 * time.Second
|
||||
c.retryInterval = 90 * time.Second
|
||||
c.refreshInterval = 15 * time.Minute
|
||||
c.requestTimeout = 30 * time.Second
|
||||
c.throttlePeerPeriod = 90 * time.Second
|
||||
|
||||
c.dialTimeout = 15 * time.Second
|
||||
c.maxPeerAddresses = 16
|
||||
c.throttleGlobalMax = 30
|
||||
c.throttlePeerMax = 3
|
||||
c.throttleResetPeriod = 1 * time.Minute
|
||||
c.throttleResetJitter = 15 * time.Second
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableService specifies that AutoNAT should be allowed to run a NAT service to help
|
||||
// other peers determine their own NAT status. The provided Network should not be the
|
||||
// default network/dialer of the host passed to `New`, as the NAT system will need to
|
||||
// make parallel connections, and as such will modify both the associated peerstore
|
||||
// and terminate connections of this dialer. The dialer provided
|
||||
// should be compatible (TCP/UDP) however with the transports of the libp2p network.
|
||||
func EnableService(dialer network.Network) Option {
|
||||
return func(c *config) error {
|
||||
if dialer == c.host.Network() || dialer.Peerstore() == c.host.Peerstore() {
|
||||
return errors.New("dialer should not be that of the host")
|
||||
}
|
||||
c.dialer = dialer
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithReachability overrides autonat to simply report an over-ridden reachability
|
||||
// status.
|
||||
func WithReachability(reachability network.Reachability) Option {
|
||||
return func(c *config) error {
|
||||
c.forceReachability = true
|
||||
c.reachability = reachability
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// UsingAddresses allows overriding which Addresses the AutoNAT client believes
|
||||
// are "its own". Useful for testing, or for more exotic port-forwarding
|
||||
// scenarios where the host may be listening on different ports than it wants
|
||||
// to externally advertise or verify connectability on.
|
||||
func UsingAddresses(addrFunc AddrFunc) Option {
|
||||
return func(c *config) error {
|
||||
if addrFunc == nil {
|
||||
return errors.New("invalid address function supplied")
|
||||
}
|
||||
c.addressFunc = addrFunc
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSchedule configures how aggressively probes will be made to verify the
|
||||
// address of the host. retryInterval indicates how often probes should be made
|
||||
// when the host lacks confidence about its address, while refreshInterval
|
||||
// is the schedule of periodic probes when the host believes it knows its
|
||||
// steady-state reachability.
|
||||
func WithSchedule(retryInterval, refreshInterval time.Duration) Option {
|
||||
return func(c *config) error {
|
||||
c.retryInterval = retryInterval
|
||||
c.refreshInterval = refreshInterval
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithoutStartupDelay removes the initial delay the NAT subsystem typically
|
||||
// uses as a buffer for ensuring that connectivity and guesses as to the hosts
|
||||
// local interfaces have settled down during startup.
|
||||
func WithoutStartupDelay() Option {
|
||||
return func(c *config) error {
|
||||
c.bootDelay = 1
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithoutThrottling indicates that this autonat service should not place
|
||||
// restrictions on how many peers it is willing to help when acting as
|
||||
// a server.
|
||||
func WithoutThrottling() Option {
|
||||
return func(c *config) error {
|
||||
c.throttleGlobalMax = 0
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithThrottling specifies how many peers (`amount`) it is willing to help
|
||||
// ever `interval` amount of time when acting as a server.
|
||||
func WithThrottling(amount int, interval time.Duration) Option {
|
||||
return func(c *config) error {
|
||||
c.throttleGlobalMax = amount
|
||||
c.throttleResetPeriod = interval
|
||||
c.throttleResetJitter = interval / 4
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPeerThrottling specifies a limit for the maximum number of IP checks
|
||||
// this node will provide to an individual peer in each `interval`.
|
||||
func WithPeerThrottling(amount int) Option {
|
||||
return func(c *config) error {
|
||||
c.throttlePeerMax = amount
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithMetricsTracer uses mt to track autonat metrics
|
||||
func WithMetricsTracer(mt MetricsTracer) Option {
|
||||
return func(c *config) error {
|
||||
c.metricsTracer = mt
|
||||
return nil
|
||||
}
|
||||
}
|
||||
524
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/pb/autonat.pb.go
generated
vendored
Normal file
524
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/pb/autonat.pb.go
generated
vendored
Normal file
@@ -0,0 +1,524 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v3.21.12
|
||||
// source: pb/autonat.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 Message_MessageType int32
|
||||
|
||||
const (
|
||||
Message_DIAL Message_MessageType = 0
|
||||
Message_DIAL_RESPONSE Message_MessageType = 1
|
||||
)
|
||||
|
||||
// Enum value maps for Message_MessageType.
|
||||
var (
|
||||
Message_MessageType_name = map[int32]string{
|
||||
0: "DIAL",
|
||||
1: "DIAL_RESPONSE",
|
||||
}
|
||||
Message_MessageType_value = map[string]int32{
|
||||
"DIAL": 0,
|
||||
"DIAL_RESPONSE": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Message_MessageType) Enum() *Message_MessageType {
|
||||
p := new(Message_MessageType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Message_MessageType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Message_MessageType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_pb_autonat_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Message_MessageType) Type() protoreflect.EnumType {
|
||||
return &file_pb_autonat_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Message_MessageType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (x *Message_MessageType) UnmarshalJSON(b []byte) error {
|
||||
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Message_MessageType(num)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprecated: Use Message_MessageType.Descriptor instead.
|
||||
func (Message_MessageType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_pb_autonat_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
type Message_ResponseStatus int32
|
||||
|
||||
const (
|
||||
Message_OK Message_ResponseStatus = 0
|
||||
Message_E_DIAL_ERROR Message_ResponseStatus = 100
|
||||
Message_E_DIAL_REFUSED Message_ResponseStatus = 101
|
||||
Message_E_BAD_REQUEST Message_ResponseStatus = 200
|
||||
Message_E_INTERNAL_ERROR Message_ResponseStatus = 300
|
||||
)
|
||||
|
||||
// Enum value maps for Message_ResponseStatus.
|
||||
var (
|
||||
Message_ResponseStatus_name = map[int32]string{
|
||||
0: "OK",
|
||||
100: "E_DIAL_ERROR",
|
||||
101: "E_DIAL_REFUSED",
|
||||
200: "E_BAD_REQUEST",
|
||||
300: "E_INTERNAL_ERROR",
|
||||
}
|
||||
Message_ResponseStatus_value = map[string]int32{
|
||||
"OK": 0,
|
||||
"E_DIAL_ERROR": 100,
|
||||
"E_DIAL_REFUSED": 101,
|
||||
"E_BAD_REQUEST": 200,
|
||||
"E_INTERNAL_ERROR": 300,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Message_ResponseStatus) Enum() *Message_ResponseStatus {
|
||||
p := new(Message_ResponseStatus)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Message_ResponseStatus) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Message_ResponseStatus) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_pb_autonat_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (Message_ResponseStatus) Type() protoreflect.EnumType {
|
||||
return &file_pb_autonat_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x Message_ResponseStatus) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (x *Message_ResponseStatus) UnmarshalJSON(b []byte) error {
|
||||
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = Message_ResponseStatus(num)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprecated: Use Message_ResponseStatus.Descriptor instead.
|
||||
func (Message_ResponseStatus) EnumDescriptor() ([]byte, []int) {
|
||||
return file_pb_autonat_proto_rawDescGZIP(), []int{0, 1}
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Type *Message_MessageType `protobuf:"varint,1,opt,name=type,enum=autonat.pb.Message_MessageType" json:"type,omitempty"`
|
||||
Dial *Message_Dial `protobuf:"bytes,2,opt,name=dial" json:"dial,omitempty"`
|
||||
DialResponse *Message_DialResponse `protobuf:"bytes,3,opt,name=dialResponse" json:"dialResponse,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Message) Reset() {
|
||||
*x = Message{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_autonat_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Message) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Message) ProtoMessage() {}
|
||||
|
||||
func (x *Message) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_autonat_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 Message.ProtoReflect.Descriptor instead.
|
||||
func (*Message) Descriptor() ([]byte, []int) {
|
||||
return file_pb_autonat_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Message) GetType() Message_MessageType {
|
||||
if x != nil && x.Type != nil {
|
||||
return *x.Type
|
||||
}
|
||||
return Message_DIAL
|
||||
}
|
||||
|
||||
func (x *Message) GetDial() *Message_Dial {
|
||||
if x != nil {
|
||||
return x.Dial
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Message) GetDialResponse() *Message_DialResponse {
|
||||
if x != nil {
|
||||
return x.DialResponse
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Message_PeerInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
|
||||
Addrs [][]byte `protobuf:"bytes,2,rep,name=addrs" json:"addrs,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Message_PeerInfo) Reset() {
|
||||
*x = Message_PeerInfo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_autonat_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Message_PeerInfo) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Message_PeerInfo) ProtoMessage() {}
|
||||
|
||||
func (x *Message_PeerInfo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_autonat_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Message_PeerInfo.ProtoReflect.Descriptor instead.
|
||||
func (*Message_PeerInfo) Descriptor() ([]byte, []int) {
|
||||
return file_pb_autonat_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
func (x *Message_PeerInfo) GetId() []byte {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Message_PeerInfo) GetAddrs() [][]byte {
|
||||
if x != nil {
|
||||
return x.Addrs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Message_Dial struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Peer *Message_PeerInfo `protobuf:"bytes,1,opt,name=peer" json:"peer,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Message_Dial) Reset() {
|
||||
*x = Message_Dial{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_autonat_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Message_Dial) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Message_Dial) ProtoMessage() {}
|
||||
|
||||
func (x *Message_Dial) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_autonat_proto_msgTypes[2]
|
||||
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 Message_Dial.ProtoReflect.Descriptor instead.
|
||||
func (*Message_Dial) Descriptor() ([]byte, []int) {
|
||||
return file_pb_autonat_proto_rawDescGZIP(), []int{0, 1}
|
||||
}
|
||||
|
||||
func (x *Message_Dial) GetPeer() *Message_PeerInfo {
|
||||
if x != nil {
|
||||
return x.Peer
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Message_DialResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Status *Message_ResponseStatus `protobuf:"varint,1,opt,name=status,enum=autonat.pb.Message_ResponseStatus" json:"status,omitempty"`
|
||||
StatusText *string `protobuf:"bytes,2,opt,name=statusText" json:"statusText,omitempty"`
|
||||
Addr []byte `protobuf:"bytes,3,opt,name=addr" json:"addr,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Message_DialResponse) Reset() {
|
||||
*x = Message_DialResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_pb_autonat_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Message_DialResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Message_DialResponse) ProtoMessage() {}
|
||||
|
||||
func (x *Message_DialResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_pb_autonat_proto_msgTypes[3]
|
||||
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 Message_DialResponse.ProtoReflect.Descriptor instead.
|
||||
func (*Message_DialResponse) Descriptor() ([]byte, []int) {
|
||||
return file_pb_autonat_proto_rawDescGZIP(), []int{0, 2}
|
||||
}
|
||||
|
||||
func (x *Message_DialResponse) GetStatus() Message_ResponseStatus {
|
||||
if x != nil && x.Status != nil {
|
||||
return *x.Status
|
||||
}
|
||||
return Message_OK
|
||||
}
|
||||
|
||||
func (x *Message_DialResponse) GetStatusText() string {
|
||||
if x != nil && x.StatusText != nil {
|
||||
return *x.StatusText
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Message_DialResponse) GetAddr() []byte {
|
||||
if x != nil {
|
||||
return x.Addr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_pb_autonat_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_pb_autonat_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x70, 0x62, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x22, 0xb5,
|
||||
0x04, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e,
|
||||
0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
|
||||
0x2c, 0x0a, 0x04, 0x64, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e,
|
||||
0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x04, 0x64, 0x69, 0x61, 0x6c, 0x12, 0x44, 0x0a,
|
||||
0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x1a, 0x30, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05,
|
||||
0x61, 0x64, 0x64, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x04, 0x44, 0x69, 0x61, 0x6c, 0x12, 0x30, 0x0a,
|
||||
0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x75,
|
||||
0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x2e, 0x50, 0x65, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x1a,
|
||||
0x7e, 0x0a, 0x0c, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x22, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x6e, 0x61, 0x74, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61,
|
||||
0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x22,
|
||||
0x2a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08,
|
||||
0x0a, 0x04, 0x44, 0x49, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x49, 0x41, 0x4c,
|
||||
0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x01, 0x22, 0x69, 0x0a, 0x0e, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x06, 0x0a,
|
||||
0x02, 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x5f, 0x44, 0x49, 0x41, 0x4c, 0x5f,
|
||||
0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x64, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x5f, 0x44, 0x49, 0x41,
|
||||
0x4c, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x53, 0x45, 0x44, 0x10, 0x65, 0x12, 0x12, 0x0a, 0x0d, 0x45,
|
||||
0x5f, 0x42, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0xc8, 0x01, 0x12,
|
||||
0x15, 0x0a, 0x10, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x45, 0x52,
|
||||
0x52, 0x4f, 0x52, 0x10, 0xac, 0x02,
|
||||
}
|
||||
|
||||
var (
|
||||
file_pb_autonat_proto_rawDescOnce sync.Once
|
||||
file_pb_autonat_proto_rawDescData = file_pb_autonat_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_pb_autonat_proto_rawDescGZIP() []byte {
|
||||
file_pb_autonat_proto_rawDescOnce.Do(func() {
|
||||
file_pb_autonat_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_autonat_proto_rawDescData)
|
||||
})
|
||||
return file_pb_autonat_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_pb_autonat_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_pb_autonat_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_pb_autonat_proto_goTypes = []interface{}{
|
||||
(Message_MessageType)(0), // 0: autonat.pb.Message.MessageType
|
||||
(Message_ResponseStatus)(0), // 1: autonat.pb.Message.ResponseStatus
|
||||
(*Message)(nil), // 2: autonat.pb.Message
|
||||
(*Message_PeerInfo)(nil), // 3: autonat.pb.Message.PeerInfo
|
||||
(*Message_Dial)(nil), // 4: autonat.pb.Message.Dial
|
||||
(*Message_DialResponse)(nil), // 5: autonat.pb.Message.DialResponse
|
||||
}
|
||||
var file_pb_autonat_proto_depIdxs = []int32{
|
||||
0, // 0: autonat.pb.Message.type:type_name -> autonat.pb.Message.MessageType
|
||||
4, // 1: autonat.pb.Message.dial:type_name -> autonat.pb.Message.Dial
|
||||
5, // 2: autonat.pb.Message.dialResponse:type_name -> autonat.pb.Message.DialResponse
|
||||
3, // 3: autonat.pb.Message.Dial.peer:type_name -> autonat.pb.Message.PeerInfo
|
||||
1, // 4: autonat.pb.Message.DialResponse.status:type_name -> autonat.pb.Message.ResponseStatus
|
||||
5, // [5:5] is the sub-list for method output_type
|
||||
5, // [5:5] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pb_autonat_proto_init() }
|
||||
func file_pb_autonat_proto_init() {
|
||||
if File_pb_autonat_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_pb_autonat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Message); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pb_autonat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Message_PeerInfo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pb_autonat_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Message_Dial); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_pb_autonat_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Message_DialResponse); 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_autonat_proto_rawDesc,
|
||||
NumEnums: 2,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_pb_autonat_proto_goTypes,
|
||||
DependencyIndexes: file_pb_autonat_proto_depIdxs,
|
||||
EnumInfos: file_pb_autonat_proto_enumTypes,
|
||||
MessageInfos: file_pb_autonat_proto_msgTypes,
|
||||
}.Build()
|
||||
File_pb_autonat_proto = out.File
|
||||
file_pb_autonat_proto_rawDesc = nil
|
||||
file_pb_autonat_proto_goTypes = nil
|
||||
file_pb_autonat_proto_depIdxs = nil
|
||||
}
|
||||
37
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/pb/autonat.proto
generated
vendored
Normal file
37
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/pb/autonat.proto
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package autonat.pb;
|
||||
|
||||
message Message {
|
||||
enum MessageType {
|
||||
DIAL = 0;
|
||||
DIAL_RESPONSE = 1;
|
||||
}
|
||||
|
||||
enum ResponseStatus {
|
||||
OK = 0;
|
||||
E_DIAL_ERROR = 100;
|
||||
E_DIAL_REFUSED = 101;
|
||||
E_BAD_REQUEST = 200;
|
||||
E_INTERNAL_ERROR = 300;
|
||||
}
|
||||
|
||||
message PeerInfo {
|
||||
optional bytes id = 1;
|
||||
repeated bytes addrs = 2;
|
||||
}
|
||||
|
||||
message Dial {
|
||||
optional PeerInfo peer = 1;
|
||||
}
|
||||
|
||||
message DialResponse {
|
||||
optional ResponseStatus status = 1;
|
||||
optional string statusText = 2;
|
||||
optional bytes addr = 3;
|
||||
}
|
||||
|
||||
optional MessageType type = 1;
|
||||
optional Dial dial = 2;
|
||||
optional DialResponse dialResponse = 3;
|
||||
}
|
||||
41
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/proto.go
generated
vendored
Normal file
41
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/proto.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/autonat/pb"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
//go:generate protoc --proto_path=$PWD:$PWD/../../.. --go_out=. --go_opt=Mpb/autonat.proto=./pb pb/autonat.proto
|
||||
|
||||
// AutoNATProto identifies the autonat service protocol
|
||||
const AutoNATProto = "/libp2p/autonat/1.0.0"
|
||||
|
||||
func newDialMessage(pi peer.AddrInfo) *pb.Message {
|
||||
msg := new(pb.Message)
|
||||
msg.Type = pb.Message_DIAL.Enum()
|
||||
msg.Dial = new(pb.Message_Dial)
|
||||
msg.Dial.Peer = new(pb.Message_PeerInfo)
|
||||
msg.Dial.Peer.Id = []byte(pi.ID)
|
||||
msg.Dial.Peer.Addrs = make([][]byte, len(pi.Addrs))
|
||||
for i, addr := range pi.Addrs {
|
||||
msg.Dial.Peer.Addrs[i] = addr.Bytes()
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
func newDialResponseOK(addr ma.Multiaddr) *pb.Message_DialResponse {
|
||||
dr := new(pb.Message_DialResponse)
|
||||
dr.Status = pb.Message_OK.Enum()
|
||||
dr.Addr = addr.Bytes()
|
||||
return dr
|
||||
}
|
||||
|
||||
func newDialResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DialResponse {
|
||||
dr := new(pb.Message_DialResponse)
|
||||
dr.Status = status.Enum()
|
||||
dr.StatusText = &text
|
||||
return dr
|
||||
}
|
||||
295
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/svc.go
generated
vendored
Normal file
295
vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/svc.go
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
package autonat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"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/autonat/pb"
|
||||
|
||||
"github.com/libp2p/go-msgio/pbio"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
var streamTimeout = 60 * time.Second
|
||||
|
||||
const (
|
||||
ServiceName = "libp2p.autonat"
|
||||
|
||||
maxMsgSize = 4096
|
||||
)
|
||||
|
||||
// AutoNATService provides NAT autodetection services to other peers
|
||||
type autoNATService struct {
|
||||
instanceLock sync.Mutex
|
||||
instance context.CancelFunc
|
||||
backgroundRunning chan struct{} // closed when background exits
|
||||
|
||||
config *config
|
||||
|
||||
// rate limiter
|
||||
mx sync.Mutex
|
||||
reqs map[peer.ID]int
|
||||
globalReqs int
|
||||
}
|
||||
|
||||
// NewAutoNATService creates a new AutoNATService instance attached to a host
|
||||
func newAutoNATService(c *config) (*autoNATService, error) {
|
||||
if c.dialer == nil {
|
||||
return nil, errors.New("cannot create NAT service without a network")
|
||||
}
|
||||
return &autoNATService{
|
||||
config: c,
|
||||
reqs: make(map[peer.ID]int),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (as *autoNATService) handleStream(s network.Stream) {
|
||||
if err := s.Scope().SetService(ServiceName); err != nil {
|
||||
log.Debugf("error attaching stream to autonat service: %s", err)
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Scope().ReserveMemory(maxMsgSize, network.ReservationPriorityAlways); err != nil {
|
||||
log.Debugf("error reserving memory for autonat stream: %s", err)
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
defer s.Scope().ReleaseMemory(maxMsgSize)
|
||||
|
||||
s.SetDeadline(time.Now().Add(streamTimeout))
|
||||
defer s.Close()
|
||||
|
||||
pid := s.Conn().RemotePeer()
|
||||
log.Debugf("New stream from %s", pid)
|
||||
|
||||
r := pbio.NewDelimitedReader(s, maxMsgSize)
|
||||
w := pbio.NewDelimitedWriter(s)
|
||||
|
||||
var req pb.Message
|
||||
var res pb.Message
|
||||
|
||||
err := r.ReadMsg(&req)
|
||||
if err != nil {
|
||||
log.Debugf("Error reading message from %s: %s", pid, err.Error())
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
|
||||
t := req.GetType()
|
||||
if t != pb.Message_DIAL {
|
||||
log.Debugf("Unexpected message from %s: %s (%d)", pid, t.String(), t)
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
|
||||
dr := as.handleDial(pid, s.Conn().RemoteMultiaddr(), req.GetDial().GetPeer())
|
||||
res.Type = pb.Message_DIAL_RESPONSE.Enum()
|
||||
res.DialResponse = dr
|
||||
|
||||
err = w.WriteMsg(&res)
|
||||
if err != nil {
|
||||
log.Debugf("Error writing response to %s: %s", pid, err.Error())
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
if as.config.metricsTracer != nil {
|
||||
as.config.metricsTracer.OutgoingDialResponse(res.GetDialResponse().GetStatus())
|
||||
}
|
||||
}
|
||||
|
||||
func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Message_PeerInfo) *pb.Message_DialResponse {
|
||||
if mpi == nil {
|
||||
return newDialResponseError(pb.Message_E_BAD_REQUEST, "missing peer info")
|
||||
}
|
||||
|
||||
mpid := mpi.GetId()
|
||||
if mpid != nil {
|
||||
mp, err := peer.IDFromBytes(mpid)
|
||||
if err != nil {
|
||||
return newDialResponseError(pb.Message_E_BAD_REQUEST, "bad peer id")
|
||||
}
|
||||
|
||||
if mp != p {
|
||||
return newDialResponseError(pb.Message_E_BAD_REQUEST, "peer id mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
addrs := make([]ma.Multiaddr, 0, as.config.maxPeerAddresses)
|
||||
seen := make(map[string]struct{})
|
||||
|
||||
// Don't even try to dial peers with blocked remote addresses. In order to dial a peer, we
|
||||
// need to know their public IP address, and it needs to be different from our public IP
|
||||
// address.
|
||||
if as.config.dialPolicy.skipDial(obsaddr) {
|
||||
if as.config.metricsTracer != nil {
|
||||
as.config.metricsTracer.OutgoingDialRefused(dial_blocked)
|
||||
}
|
||||
// Note: versions < v0.20.0 return Message_E_DIAL_ERROR here, thus we can not rely on this error code.
|
||||
return newDialResponseError(pb.Message_E_DIAL_REFUSED, "refusing to dial peer with blocked observed address")
|
||||
}
|
||||
|
||||
// Determine the peer's IP address.
|
||||
hostIP, _ := ma.SplitFirst(obsaddr)
|
||||
switch hostIP.Protocol().Code {
|
||||
case ma.P_IP4, ma.P_IP6:
|
||||
default:
|
||||
// This shouldn't be possible as we should skip all addresses that don't include
|
||||
// public IP addresses.
|
||||
return newDialResponseError(pb.Message_E_INTERNAL_ERROR, "expected an IP address")
|
||||
}
|
||||
|
||||
// add observed addr to the list of addresses to dial
|
||||
addrs = append(addrs, obsaddr)
|
||||
seen[obsaddr.String()] = struct{}{}
|
||||
|
||||
for _, maddr := range mpi.GetAddrs() {
|
||||
addr, err := ma.NewMultiaddrBytes(maddr)
|
||||
if err != nil {
|
||||
log.Debugf("Error parsing multiaddr: %s", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
// For security reasons, we _only_ dial the observed IP address.
|
||||
// Replace other IP addresses with the observed one so we can still try the
|
||||
// requested ports/transports.
|
||||
if ip, rest := ma.SplitFirst(addr); !ip.Equal(hostIP) {
|
||||
// Make sure it's an IP address
|
||||
switch ip.Protocol().Code {
|
||||
case ma.P_IP4, ma.P_IP6:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
addr = hostIP
|
||||
if rest != nil {
|
||||
addr = addr.Encapsulate(rest)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we're willing to dial the rest of the address (e.g., not a circuit
|
||||
// address).
|
||||
if as.config.dialPolicy.skipDial(addr) {
|
||||
continue
|
||||
}
|
||||
|
||||
str := addr.String()
|
||||
_, ok := seen[str]
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs = append(addrs, addr)
|
||||
seen[str] = struct{}{}
|
||||
|
||||
if len(addrs) >= as.config.maxPeerAddresses {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(addrs) == 0 {
|
||||
if as.config.metricsTracer != nil {
|
||||
as.config.metricsTracer.OutgoingDialRefused(no_valid_address)
|
||||
}
|
||||
// Note: versions < v0.20.0 return Message_E_DIAL_ERROR here, thus we can not rely on this error code.
|
||||
return newDialResponseError(pb.Message_E_DIAL_REFUSED, "no dialable addresses")
|
||||
}
|
||||
|
||||
return as.doDial(peer.AddrInfo{ID: p, Addrs: addrs})
|
||||
}
|
||||
|
||||
func (as *autoNATService) doDial(pi peer.AddrInfo) *pb.Message_DialResponse {
|
||||
// rate limit check
|
||||
as.mx.Lock()
|
||||
count := as.reqs[pi.ID]
|
||||
if count >= as.config.throttlePeerMax || (as.config.throttleGlobalMax > 0 &&
|
||||
as.globalReqs >= as.config.throttleGlobalMax) {
|
||||
as.mx.Unlock()
|
||||
if as.config.metricsTracer != nil {
|
||||
as.config.metricsTracer.OutgoingDialRefused(rate_limited)
|
||||
}
|
||||
return newDialResponseError(pb.Message_E_DIAL_REFUSED, "too many dials")
|
||||
}
|
||||
as.reqs[pi.ID] = count + 1
|
||||
as.globalReqs++
|
||||
as.mx.Unlock()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), as.config.dialTimeout)
|
||||
defer cancel()
|
||||
|
||||
as.config.dialer.Peerstore().ClearAddrs(pi.ID)
|
||||
|
||||
as.config.dialer.Peerstore().AddAddrs(pi.ID, pi.Addrs, peerstore.TempAddrTTL)
|
||||
|
||||
defer func() {
|
||||
as.config.dialer.Peerstore().ClearAddrs(pi.ID)
|
||||
as.config.dialer.Peerstore().RemovePeer(pi.ID)
|
||||
}()
|
||||
|
||||
conn, err := as.config.dialer.DialPeer(ctx, pi.ID)
|
||||
if err != nil {
|
||||
log.Debugf("error dialing %s: %s", pi.ID, err.Error())
|
||||
// wait for the context to timeout to avoid leaking timing information
|
||||
// this renders the service ineffective as a port scanner
|
||||
<-ctx.Done()
|
||||
return newDialResponseError(pb.Message_E_DIAL_ERROR, "dial failed")
|
||||
}
|
||||
|
||||
ra := conn.RemoteMultiaddr()
|
||||
as.config.dialer.ClosePeer(pi.ID)
|
||||
return newDialResponseOK(ra)
|
||||
}
|
||||
|
||||
// Enable the autoNAT service if it is not running.
|
||||
func (as *autoNATService) Enable() {
|
||||
as.instanceLock.Lock()
|
||||
defer as.instanceLock.Unlock()
|
||||
if as.instance != nil {
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
as.instance = cancel
|
||||
as.backgroundRunning = make(chan struct{})
|
||||
as.config.host.SetStreamHandler(AutoNATProto, as.handleStream)
|
||||
|
||||
go as.background(ctx)
|
||||
}
|
||||
|
||||
// Disable the autoNAT service if it is running.
|
||||
func (as *autoNATService) Disable() {
|
||||
as.instanceLock.Lock()
|
||||
defer as.instanceLock.Unlock()
|
||||
if as.instance != nil {
|
||||
as.config.host.RemoveStreamHandler(AutoNATProto)
|
||||
as.instance()
|
||||
as.instance = nil
|
||||
<-as.backgroundRunning
|
||||
}
|
||||
}
|
||||
|
||||
func (as *autoNATService) background(ctx context.Context) {
|
||||
defer close(as.backgroundRunning)
|
||||
|
||||
timer := time.NewTimer(as.config.throttleResetPeriod)
|
||||
defer timer.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
as.mx.Lock()
|
||||
as.reqs = make(map[peer.ID]int)
|
||||
as.globalReqs = 0
|
||||
as.mx.Unlock()
|
||||
jitter := rand.Float32() * float32(as.config.throttleResetJitter)
|
||||
timer.Reset(as.config.throttleResetPeriod + time.Duration(int64(jitter)))
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user