Skip to content

Commit f654b4b

Browse files
Add Resolver interface to transport (#1719)
* Add Resolver interface to transport * Move resolve test to swarm_dial_test * Use proper peer id in test * Only import go-multiaddr once * Cleanup * Use SNI in websocket * Update go-multiaddr * Update p2p/net/swarm/swarm.go Co-authored-by: Marten Seemann <martenseemann@gmail.com> * PR comments on websocket.go * Use unresolved/resolved map * Set sni * Refactor websocket multiaddr parsing code, add server test * Delete superflous helpers * Update callsites * Fix typo in p2p/transport/websocket/websocket.go Co-authored-by: Marten Seemann <martenseemann@gmail.com>
1 parent aa6d051 commit f654b4b

File tree

16 files changed

+698
-285
lines changed

16 files changed

+698
-285
lines changed

config/config.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ func (cfg *Config) makeSwarm() (*swarm.Swarm, error) {
155155
if cfg.ResourceManager != nil {
156156
opts = append(opts, swarm.WithResourceManager(cfg.ResourceManager))
157157
}
158+
if cfg.MultiaddrResolver != nil {
159+
opts = append(opts, swarm.WithMultiaddrResolver(cfg.MultiaddrResolver))
160+
}
158161
// TODO: Make the swarm implementation configurable.
159162
return swarm.NewSwarm(pid, cfg.Peerstore, opts...)
160163
}
@@ -229,7 +232,6 @@ func (cfg *Config) NewNode() (host.Host, error) {
229232
EnablePing: !cfg.DisablePing,
230233
UserAgent: cfg.UserAgent,
231234
ProtocolVersion: cfg.ProtocolVersion,
232-
MultiaddrResolver: cfg.MultiaddrResolver,
233235
EnableHolePunching: cfg.EnableHolePunching,
234236
HolePunchingOptions: cfg.HolePunchingOptions,
235237
EnableRelayService: cfg.EnableRelayService,

core/transport/transport.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ type Transport interface {
7777
Proxy() bool
7878
}
7979

80+
// Resolver can be optionally implemented by transports that want to resolve or transform the
81+
// multiaddr.
82+
type Resolver interface {
83+
Resolve(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error)
84+
}
85+
8086
// Listener is an interface closely resembling the net.Listener interface. The
8187
// only real difference is that Accept() returns Conn's of the type in this
8288
// package, and also exposes a Multiaddr method as opposed to a regular Addr

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ require (
3838
github.com/minio/sha256-simd v1.0.0
3939
github.com/mr-tron/base58 v1.2.0
4040
github.com/multiformats/go-base32 v0.0.4
41-
github.com/multiformats/go-multiaddr v0.6.0
41+
github.com/multiformats/go-multiaddr v0.7.0
4242
github.com/multiformats/go-multiaddr-dns v0.3.1
4343
github.com/multiformats/go-multiaddr-fmt v0.1.0
4444
github.com/multiformats/go-multibase v0.1.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,8 @@ github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ8
369369
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
370370
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
371371
github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4=
372-
github.com/multiformats/go-multiaddr v0.6.0 h1:qMnoOPj2s8xxPU5kZ57Cqdr0hHhARz7mFsPMIiYNqzg=
373-
github.com/multiformats/go-multiaddr v0.6.0/go.mod h1:F4IpaKZuPP360tOMn2Tpyu0At8w23aRyVqeK0DbFeGM=
372+
github.com/multiformats/go-multiaddr v0.7.0 h1:gskHcdaCyPtp9XskVwtvEeQOG465sCohbQIirSyqxrc=
373+
github.com/multiformats/go-multiaddr v0.7.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs=
374374
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
375375
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
376376
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=

p2p/host/basic/basic_host.go

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ import (
3838
msmux "github.com/multiformats/go-multistream"
3939
)
4040

41-
// The maximum number of address resolution steps we'll perform for a single
42-
// peer (for all addresses).
43-
const maxAddressResolution = 32
44-
4541
// addrChangeTickrInterval is the interval between two address change ticks.
4642
var addrChangeTickrInterval = 5 * time.Second
4743

@@ -713,77 +709,9 @@ func (h *BasicHost) Connect(ctx context.Context, pi peer.AddrInfo) error {
713709
}
714710
}
715711

716-
resolved, err := h.resolveAddrs(ctx, h.Peerstore().PeerInfo(pi.ID))
717-
if err != nil {
718-
return err
719-
}
720-
h.Peerstore().AddAddrs(pi.ID, resolved, peerstore.TempAddrTTL)
721-
722712
return h.dialPeer(ctx, pi.ID)
723713
}
724714

725-
func (h *BasicHost) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multiaddr, error) {
726-
proto := ma.ProtocolWithCode(ma.P_P2P).Name
727-
p2paddr, err := ma.NewMultiaddr("/" + proto + "/" + pi.ID.Pretty())
728-
if err != nil {
729-
return nil, err
730-
}
731-
732-
resolveSteps := 0
733-
734-
// Recursively resolve all addrs.
735-
//
736-
// While the toResolve list is non-empty:
737-
// * Pop an address off.
738-
// * If the address is fully resolved, add it to the resolved list.
739-
// * Otherwise, resolve it and add the results to the "to resolve" list.
740-
toResolve := append(([]ma.Multiaddr)(nil), pi.Addrs...)
741-
resolved := make([]ma.Multiaddr, 0, len(pi.Addrs))
742-
for len(toResolve) > 0 {
743-
// pop the last addr off.
744-
addr := toResolve[len(toResolve)-1]
745-
toResolve = toResolve[:len(toResolve)-1]
746-
747-
// if it's resolved, add it to the resolved list.
748-
if !madns.Matches(addr) {
749-
resolved = append(resolved, addr)
750-
continue
751-
}
752-
753-
resolveSteps++
754-
755-
// We've resolved too many addresses. We can keep all the fully
756-
// resolved addresses but we'll need to skip the rest.
757-
if resolveSteps >= maxAddressResolution {
758-
log.Warnf(
759-
"peer %s asked us to resolve too many addresses: %s/%s",
760-
pi.ID,
761-
resolveSteps,
762-
maxAddressResolution,
763-
)
764-
continue
765-
}
766-
767-
// otherwise, resolve it
768-
reqaddr := addr.Encapsulate(p2paddr)
769-
resaddrs, err := h.maResolver.Resolve(ctx, reqaddr)
770-
if err != nil {
771-
log.Infof("error resolving %s: %s", reqaddr, err)
772-
}
773-
774-
// add the results to the toResolve list.
775-
for _, res := range resaddrs {
776-
pi, err := peer.AddrInfoFromP2pAddr(res)
777-
if err != nil {
778-
log.Infof("error parsing %s: %s", res, err)
779-
}
780-
toResolve = append(toResolve, pi.Addrs...)
781-
}
782-
}
783-
784-
return resolved, nil
785-
}
786-
787715
// dialPeer opens a connection to peer, and makes sure to identify
788716
// the connection once it has been opened.
789717
func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error {

p2p/host/basic/basic_host_test.go

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ import (
1717
"github.com/libp2p/go-libp2p/core/peerstore"
1818
"github.com/libp2p/go-libp2p/core/protocol"
1919
"github.com/libp2p/go-libp2p/core/record"
20-
"github.com/libp2p/go-libp2p/core/test"
2120
"github.com/libp2p/go-libp2p/p2p/host/autonat"
2221
"github.com/libp2p/go-libp2p/p2p/host/eventbus"
2322
swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing"
2423
"github.com/libp2p/go-libp2p/p2p/protocol/identify"
2524

2625
ma "github.com/multiformats/go-multiaddr"
27-
madns "github.com/multiformats/go-multiaddr-dns"
2826

2927
"github.com/stretchr/testify/assert"
3028
"github.com/stretchr/testify/require"
@@ -526,111 +524,6 @@ func TestProtoDowngrade(t *testing.T) {
526524
assertWait(t, connectedOn, "/testing")
527525
}
528526

529-
func TestAddrResolution(t *testing.T) {
530-
ctx := context.Background()
531-
532-
p1 := test.RandPeerIDFatal(t)
533-
p2 := test.RandPeerIDFatal(t)
534-
addr1 := ma.StringCast("/dnsaddr/example.com")
535-
addr2 := ma.StringCast("/ip4/192.0.2.1/tcp/123")
536-
p2paddr1 := ma.StringCast("/dnsaddr/example.com/p2p/" + p1.Pretty())
537-
p2paddr2 := ma.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p1.Pretty())
538-
p2paddr3 := ma.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p2.Pretty())
539-
540-
backend := &madns.MockResolver{
541-
TXT: map[string][]string{"_dnsaddr.example.com": {
542-
"dnsaddr=" + p2paddr2.String(), "dnsaddr=" + p2paddr3.String(),
543-
}},
544-
}
545-
resolver, err := madns.NewResolver(madns.WithDefaultResolver(backend))
546-
require.NoError(t, err)
547-
548-
h, err := NewHost(swarmt.GenSwarm(t), &HostOpts{MultiaddrResolver: resolver})
549-
require.NoError(t, err)
550-
defer h.Close()
551-
552-
pi, err := peer.AddrInfoFromP2pAddr(p2paddr1)
553-
require.NoError(t, err)
554-
555-
tctx, cancel := context.WithTimeout(ctx, time.Millisecond*100)
556-
defer cancel()
557-
_ = h.Connect(tctx, *pi)
558-
559-
addrs := h.Peerstore().Addrs(pi.ID)
560-
561-
require.Len(t, addrs, 2)
562-
require.Contains(t, addrs, addr1)
563-
require.Contains(t, addrs, addr2)
564-
}
565-
566-
func TestAddrResolutionRecursive(t *testing.T) {
567-
ctx := context.Background()
568-
569-
p1, err := test.RandPeerID()
570-
if err != nil {
571-
t.Error(err)
572-
}
573-
p2, err := test.RandPeerID()
574-
if err != nil {
575-
t.Error(err)
576-
}
577-
addr1 := ma.StringCast("/dnsaddr/example.com")
578-
addr2 := ma.StringCast("/ip4/192.0.2.1/tcp/123")
579-
p2paddr1 := ma.StringCast("/dnsaddr/example.com/p2p/" + p1.Pretty())
580-
p2paddr2 := ma.StringCast("/dnsaddr/example.com/p2p/" + p2.Pretty())
581-
p2paddr1i := ma.StringCast("/dnsaddr/foo.example.com/p2p/" + p1.Pretty())
582-
p2paddr2i := ma.StringCast("/dnsaddr/bar.example.com/p2p/" + p2.Pretty())
583-
p2paddr1f := ma.StringCast("/ip4/192.0.2.1/tcp/123/p2p/" + p1.Pretty())
584-
585-
backend := &madns.MockResolver{
586-
TXT: map[string][]string{
587-
"_dnsaddr.example.com": {
588-
"dnsaddr=" + p2paddr1i.String(),
589-
"dnsaddr=" + p2paddr2i.String(),
590-
},
591-
"_dnsaddr.foo.example.com": {
592-
"dnsaddr=" + p2paddr1f.String(),
593-
},
594-
"_dnsaddr.bar.example.com": {
595-
"dnsaddr=" + p2paddr2i.String(),
596-
},
597-
},
598-
}
599-
resolver, err := madns.NewResolver(madns.WithDefaultResolver(backend))
600-
if err != nil {
601-
t.Fatal(err)
602-
}
603-
604-
h, err := NewHost(swarmt.GenSwarm(t), &HostOpts{MultiaddrResolver: resolver})
605-
require.NoError(t, err)
606-
defer h.Close()
607-
608-
pi1, err := peer.AddrInfoFromP2pAddr(p2paddr1)
609-
if err != nil {
610-
t.Error(err)
611-
}
612-
613-
tctx, cancel := context.WithTimeout(ctx, time.Millisecond*100)
614-
defer cancel()
615-
_ = h.Connect(tctx, *pi1)
616-
617-
addrs1 := h.Peerstore().Addrs(pi1.ID)
618-
require.Len(t, addrs1, 2)
619-
require.Contains(t, addrs1, addr1)
620-
require.Contains(t, addrs1, addr2)
621-
622-
pi2, err := peer.AddrInfoFromP2pAddr(p2paddr2)
623-
if err != nil {
624-
t.Error(err)
625-
}
626-
627-
_ = h.Connect(tctx, *pi2)
628-
629-
addrs2 := h.Peerstore().Addrs(pi2.ID)
630-
require.Len(t, addrs2, 1)
631-
require.Contains(t, addrs2, addr1)
632-
}
633-
634527
func TestAddrChangeImmediatelyIfAddressNonEmpty(t *testing.T) {
635528
ctx := context.Background()
636529
taddrs := []ma.Multiaddr{ma.StringCast("/ip4/1.2.3.4/tcp/1234")}

0 commit comments

Comments
 (0)