diff --git a/p2p/protocol/holepunch/svc.go b/p2p/protocol/holepunch/svc.go index 9de0a11e0c..eb8ad9fd38 100644 --- a/p2p/protocol/holepunch/svc.go +++ b/p2p/protocol/holepunch/svc.go @@ -19,6 +19,7 @@ import ( "github.com/libp2p/go-msgio/pbio" ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" ) // Protocol is the libp2p protocol for Hole Punching. @@ -106,7 +107,7 @@ func (s *Service) watchForPublicAddr() { t := time.NewTimer(duration) defer t.Stop() for { - if containsPublicAddr(s.ids.OwnObservedAddrs()) { + if len(s.getPublicAddrs()) > 0 { log.Debug("Host now has a public address. Starting holepunch protocol.") s.host.SetStreamHandler(Protocol, s.handleNewStream) break @@ -171,7 +172,7 @@ func (s *Service) incomingHolePunch(str network.Stream) (rtt time.Duration, remo if !isRelayAddress(str.Conn().RemoteMultiaddr()) { return 0, nil, nil, fmt.Errorf("received hole punch stream: %s", str.Conn().RemoteMultiaddr()) } - ownAddrs = removeRelayAddrs(s.ids.OwnObservedAddrs()) + ownAddrs = s.getPublicAddrs() if s.filter != nil { ownAddrs = s.filter.FilterLocal(str.Conn().RemotePeer(), ownAddrs) } @@ -274,6 +275,29 @@ func (s *Service) handleNewStream(str network.Stream) { s.tracer.HolePunchFinished("receiver", 1, addrs, ownAddrs, getDirectConnection(s.host, rp)) } +// getPublicAddrs returns public observed and interface addresses +func (s *Service) getPublicAddrs() []ma.Multiaddr { + addrs := removeRelayAddrs(s.ids.OwnObservedAddrs()) + + interfaceListenAddrs, err := s.host.Network().InterfaceListenAddresses() + if err != nil { + log.Debugf("failed to get to get InterfaceListenAddresses: %s", err) + } else { + addrs = append(addrs, interfaceListenAddrs...) + } + + addrs = ma.Unique(addrs) + + publicAddrs := make([]ma.Multiaddr, 0, len(addrs)) + + for _, addr := range addrs { + if manet.IsPublicAddr(addr) { + publicAddrs = append(publicAddrs, addr) + } + } + return publicAddrs +} + // DirectConnect is only exposed for testing purposes. // TODO: find a solution for this. func (s *Service) DirectConnect(p peer.ID) error { diff --git a/p2p/protocol/holepunch/util.go b/p2p/protocol/holepunch/util.go index 13013568fe..947b1ffd82 100644 --- a/p2p/protocol/holepunch/util.go +++ b/p2p/protocol/holepunch/util.go @@ -8,19 +8,8 @@ import ( "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr/net" ) -func containsPublicAddr(addrs []ma.Multiaddr) bool { - for _, addr := range addrs { - if isRelayAddress(addr) || !manet.IsPublicAddr(addr) { - continue - } - return true - } - return false -} - func removeRelayAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { result := make([]ma.Multiaddr, 0, len(addrs)) for _, addr := range addrs {