Skip to content

Commit

Permalink
fix: enable dctur when interface address is public (#2931)
Browse files Browse the repository at this point in the history
* fix: allow punching undialable host public ip

fixes #2913

* chore: use interface listen addrs to enable dctur

* fix: filter public addresses

* chore: remove unused function

* chore: formatting

---------

Co-authored-by: Daniel N <2color@users.noreply.github.com>
  • Loading branch information
2color and 2color authored Aug 28, 2024
1 parent 65bc28b commit 3deee92
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
28 changes: 26 additions & 2 deletions p2p/protocol/holepunch/svc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand Down
11 changes: 0 additions & 11 deletions p2p/protocol/holepunch/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 3deee92

Please sign in to comment.