From 85651ee0f63edf8f7b52da35748039e5f5756aba Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 10 Mar 2022 17:22:40 +0100 Subject: [PATCH] only start the hole puncher if the node is behind a NAT / firewall --- p2p/protocol/holepunch/holepunch_test.go | 5 +++- p2p/protocol/holepunch/svc.go | 34 ++++++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/p2p/protocol/holepunch/holepunch_test.go b/p2p/protocol/holepunch/holepunch_test.go index da0db1ae..1b843111 100644 --- a/p2p/protocol/holepunch/holepunch_test.go +++ b/p2p/protocol/holepunch/holepunch_test.go @@ -414,7 +414,10 @@ func addHolePunchService(t *testing.T, h host.Host, opt holepunch.Option) *holep func mkHostWithHolePunchSvc(t *testing.T, opts ...holepunch.Option) (host.Host, *holepunch.Service) { t.Helper() - h, err := libp2p.New(libp2p.ListenAddrs(ma.StringCast("/ip4/127.0.0.1/tcp/0"), ma.StringCast("/ip6/::1/tcp/0"))) + h, err := libp2p.New( + libp2p.ListenAddrs(ma.StringCast("/ip4/127.0.0.1/tcp/0"), ma.StringCast("/ip6/::1/tcp/0")), + libp2p.ForceReachabilityPrivate(), + ) require.NoError(t, err) hps, err := holepunch.NewService(h, newMockIDService(t, h), opts...) require.NoError(t, err) diff --git a/p2p/protocol/holepunch/svc.go b/p2p/protocol/holepunch/svc.go index fd944e53..8fc9158f 100644 --- a/p2p/protocol/holepunch/svc.go +++ b/p2p/protocol/holepunch/svc.go @@ -7,12 +7,14 @@ import ( "sync" "time" + pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" + "github.com/libp2p/go-libp2p/p2p/protocol/identify" + + "github.com/libp2p/go-libp2p-core/event" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/protocol" - pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" - "github.com/libp2p/go-libp2p/p2p/protocol/identify" logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-msgio/protoio" @@ -103,9 +105,7 @@ func (s *Service) watchForPublicAddr() { if containsPublicAddr(s.ids.OwnObservedAddrs()) { log.Debug("Host now has a public address. Starting holepunch protocol.") s.host.SetStreamHandler(Protocol, s.handleNewStream) - s.holePuncher = newHolePuncher(s.host, s.ids, s.tracer) - close(s.hasPublicAddrsChan) - return + break } select { @@ -119,6 +119,30 @@ func (s *Service) watchForPublicAddr() { t.Reset(duration) } } + + // Only start the holePuncher if we're behind a NAT / firewall. + sub, err := s.host.EventBus().Subscribe(&event.EvtLocalReachabilityChanged{}) + if err != nil { + log.Debugf("failed to subscripe to Reachability event: %s", err) + return + } + defer sub.Close() + for { + select { + case <-s.ctx.Done(): + return + case e, ok := <-sub.Out(): + if !ok { + return + } + if e.(event.EvtLocalReachabilityChanged).Reachability != network.ReachabilityPrivate { + continue + } + s.holePuncher = newHolePuncher(s.host, s.ids, s.tracer) + close(s.hasPublicAddrsChan) + return + } + } } // Close closes the Hole Punch Service.