diff --git a/p2p/protocol/identify/id.go b/p2p/protocol/identify/id.go index f44716b25f..483cfa0111 100644 --- a/p2p/protocol/identify/id.go +++ b/p2p/protocol/identify/id.go @@ -21,6 +21,7 @@ import ( logging "github.com/ipfs/go-log" ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr-net" msmux "github.com/multiformats/go-multistream" ) @@ -277,9 +278,13 @@ func (ids *IDService) populateMessage(mes *pb.Identify, c network.Conn) { // set listen addrs, get our latest addrs from Host. laddrs := ids.Host.Addrs() - mes.ListenAddrs = make([][]byte, len(laddrs)) - for i, addr := range laddrs { - mes.ListenAddrs[i] = addr.Bytes() + viaLoopback := manet.IsIPLoopback(c.LocalMultiaddr()) + mes.ListenAddrs = make([][]byte, 0, len(laddrs)) + for _, addr := range laddrs { + if !viaLoopback && manet.IsIPLoopback(addr) { + continue + } + mes.ListenAddrs = append(mes.ListenAddrs, addr.Bytes()) } log.Debugf("%s sent listen addrs to %s: %s", c.LocalPeer(), c.RemotePeer(), laddrs) diff --git a/p2p/protocol/identify/id_test.go b/p2p/protocol/identify/id_test.go index 4bbf91b959..74aae94a81 100644 --- a/p2p/protocol/identify/id_test.go +++ b/p2p/protocol/identify/id_test.go @@ -16,11 +16,14 @@ import ( "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" "github.com/libp2p/go-libp2p-core/protocol" + coretest "github.com/libp2p/go-libp2p-core/test" blhost "github.com/libp2p/go-libp2p-blankhost" swarmt "github.com/libp2p/go-libp2p-swarm/testing" "github.com/libp2p/go-libp2p/p2p/protocol/identify" + "github.com/libp2p/go-libp2p-peerstore/pstoremem" + mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" ma "github.com/multiformats/go-multiaddr" ) @@ -190,6 +193,80 @@ func TestProtoMatching(t *testing.T) { } } +func TestLocalhostAddrFiltering(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + mn := mocknet.New(ctx) + id1 := coretest.RandPeerIDFatal(t) + ps1 := pstoremem.NewPeerstore() + p1addr1, _ := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/1234") + p1addr2, _ := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/2345") + ps1.AddAddrs(id1, []ma.Multiaddr{p1addr1, p1addr2}, peerstore.PermanentAddrTTL) + p1, err := mn.AddPeerWithPeerstore(id1, ps1) + if err != nil { + t.Fatal(err) + } + + id2 := coretest.RandPeerIDFatal(t) + ps2 := pstoremem.NewPeerstore() + p2addr1, _ := ma.NewMultiaddr("/ip4/1.2.3.5/tcp/1234") + p2addr2, _ := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/3456") + p2addrs := []ma.Multiaddr{p2addr1, p2addr2} + ps2.AddAddrs(id2, p2addrs, peerstore.PermanentAddrTTL) + p2, err := mn.AddPeerWithPeerstore(id2, ps2) + if err != nil { + t.Fatal(err) + } + + id3 := coretest.RandPeerIDFatal(t) + ps3 := pstoremem.NewPeerstore() + p3addr1, _ := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4567") + ps3.AddAddrs(id3, []ma.Multiaddr{p3addr1}, peerstore.PermanentAddrTTL) + p3, err := mn.AddPeerWithPeerstore(id3, ps3) + if err != nil { + t.Fatal(err) + } + + err = mn.LinkAll() + if err != nil { + t.Fatal(err) + } + p1.Connect(ctx, peer.AddrInfo{ + ID: id2, + Addrs: p2addrs[0:1], + }) + p3.Connect(ctx, peer.AddrInfo{ + ID: id2, + Addrs: p2addrs[1:], + }) + + _ = identify.NewIDService(ctx, p1) + ids2 := identify.NewIDService(ctx, p2) + ids3 := identify.NewIDService(ctx, p3) + + conns := p2.Network().ConnsToPeer(id1) + if len(conns) == 0 { + t.Fatal("no conns") + } + conn := conns[0] + ids2.IdentifyConn(conn) + addrs := p2.Peerstore().Addrs(id1) + if len(addrs) != 1 { + t.Fatalf("expected one addr, found %s", addrs) + } + + conns = p3.Network().ConnsToPeer(id2) + if len(conns) == 0 { + t.Fatal("no conns") + } + conn = conns[0] + ids3.IdentifyConn(conn) + addrs = p3.Peerstore().Addrs(id2) + if len(addrs) != 2 { + t.Fatalf("expected 2 addrs for %s, found %d: %s", id2, len(addrs), addrs) + } +} + func TestIdentifyDeltaOnProtocolChange(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel()