Skip to content

Commit

Permalink
webrtcprivate: advertise /webrtc addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
sukunrt committed Oct 23, 2023
1 parent 6249772 commit bc90626
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
2 changes: 1 addition & 1 deletion p2p/host/autorelay/relay_finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ func (rf *relayFinder) relayAddrs(addrs []ma.Multiaddr) []ma.Multiaddr {

// only keep private addrs from the original addr set
for _, addr := range addrs {
if manet.IsPrivateAddr(addr) {
if !manet.IsPublicAddr(addr) {
raddrs = append(raddrs, addr)
}
}
Expand Down
30 changes: 30 additions & 0 deletions p2p/host/basic/basic_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/libp2p/go-libp2p/p2p/protocol/holepunch"
"github.com/libp2p/go-libp2p/p2p/protocol/identify"
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
libp2pwebrtcprivate "github.com/libp2p/go-libp2p/p2p/transport/webrtcprivate"
libp2pwebtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
"github.com/prometheus/client_golang/prometheus"

Expand Down Expand Up @@ -801,9 +802,38 @@ func (h *BasicHost) Addrs() []ma.Multiaddr {
addrs[i] = addrWithCerthash
}
}

// Append webrtc addresses to circuit-v2 addresses
hasWebRTCPrivate := false
for _, addr := range addrs {
if addr.Equal(libp2pwebrtcprivate.WebRTCAddr) {
hasWebRTCPrivate = true
break
}
}
if hasWebRTCPrivate {
for _, addr := range addrs {
if _, err := addr.ValueForProtocol(ma.P_CIRCUIT); err == nil {
if isBrowserDialableAddr(addr) {
addrs = append(addrs, addr.Encapsulate(libp2pwebrtcprivate.WebRTCAddr))
}
}
}
}
return addrs
}

var browserProtocols = []int{ma.P_WEBTRANSPORT, ma.P_WEBRTC_DIRECT, ma.P_WSS}

func isBrowserDialableAddr(addr ma.Multiaddr) bool {
for _, p := range browserProtocols {
if _, err := addr.ValueForProtocol(p); err == nil {
return true
}
}
return false
}

// NormalizeMultiaddr returns a multiaddr suitable for equality checks.
// If the multiaddr is a webtransport component, it removes the certhashes.
func (h *BasicHost) NormalizeMultiaddr(addr ma.Multiaddr) ma.Multiaddr {
Expand Down
5 changes: 4 additions & 1 deletion p2p/protocol/holepunch/holepuncher.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@ func (hp *holePuncher) maybeDialWebRTC(p peer.ID) {
for _, a := range addrs {
if _, err := a.ValueForProtocol(ma.P_WEBRTC); err == nil {
ctx := network.WithForceDirectDial(hp.ctx, "webrtc holepunch")
hp.host.Connect(ctx, peer.AddrInfo{ID: p}) // address is already in peerstore
err := hp.host.Connect(ctx, peer.AddrInfo{ID: p}) // address is already in peerstore
if err != nil {
log.Debugf("holepunch attempt to %s over /webrtc failed: %s", p, err)
}
return
}
}
Expand Down
5 changes: 4 additions & 1 deletion p2p/protocol/holepunch/svc.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,10 @@ func (s *Service) Connected(_ network.Network, conn network.Conn) {
for _, addr := range s.host.Peerstore().Addrs(p) {
if _, err := addr.ValueForProtocol(ma.P_WEBRTC); err == nil {
ctx := network.WithForceDirectDial(s.ctx, "webrtc holepunch")
s.host.Connect(ctx, peer.AddrInfo{ID: p}) // address is already in peerstore
err := s.host.Connect(ctx, peer.AddrInfo{ID: p}) // address is already in peerstore
if err != nil {
log.Debugf("holepunch attempt to %s over /webrtc failed: %s", p, err)
}
return
}
}
Expand Down
41 changes: 41 additions & 0 deletions p2p/test/basichost/basic_host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"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/autorelay"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client"
"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay"
ma "github.com/multiformats/go-multiaddr"
Expand Down Expand Up @@ -158,3 +159,43 @@ func TestNewStreamTransientConnection(t *testing.T) {
<-done
<-done
}

func TestWebRTCPrivateAddressAdvertisement(t *testing.T) {
r, err := libp2p.New(
// We need a public address for the relay
libp2p.AddrsFactory(func(addrs []ma.Multiaddr) []ma.Multiaddr {
return append(addrs, ma.StringCast("/ip4/1.2.3.4/udp/1/quic-v1/webtransport"))
}),
libp2p.EnableRelayService(),
libp2p.ForceReachabilityPublic(),
)
require.NoError(t, err)

relay1info := peer.AddrInfo{
ID: r.ID(),
Addrs: r.Addrs(),
}

h, err := libp2p.New(
libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"),
libp2p.EnableRelay(),
libp2p.EnableWebRTCPrivate(nil),
libp2p.EnableAutoRelayWithStaticRelays(
[]peer.AddrInfo{relay1info},
autorelay.WithBootDelay(0),
),
libp2p.ForceReachabilityPrivate(),
)
require.NoError(t, err)

require.Eventually(t, func() bool {
for _, a := range h.Addrs() {
_, rerr := a.ValueForProtocol(ma.P_CIRCUIT)
_, werr := a.ValueForProtocol(ma.P_WEBRTC)
if rerr == nil && werr == nil {
return true
}
}
return false
}, 5*time.Second, 50*time.Millisecond)
}

0 comments on commit bc90626

Please sign in to comment.