From d0e7d1ac6a5308b32142434616b31552267e51e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 17 Sep 2018 19:53:15 +0200 Subject: [PATCH] coreapi swarm: rewire address listing cmds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Ɓukasz Magiera --- core/commands/swarm.go | 93 ++++++++++++++++----------------- core/coreapi/interface/key.go | 3 ++ core/coreapi/interface/swarm.go | 10 +++- core/coreapi/key.go | 4 ++ core/coreapi/swarm.go | 34 +++++++++++- 5 files changed, 94 insertions(+), 50 deletions(-) diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 459cbe5b376..217d1761f05 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -20,6 +20,7 @@ import ( "gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit" "gx/ipfs/QmYVqYJTVjetcf1guieEgWpK1PZtHPytP624vKzTF1P3r2/go-ipfs-config" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" + inet "gx/ipfs/QmZNJyx9GGCX4GeuHnLB8fxaxMLs4MjTjHokxfQcCd6Nve/go-libp2p-net" pstore "gx/ipfs/Qmda4cPRvSRyox3SqgJN6DfSZGU5TtHufPTp9uXjFj71X6/go-libp2p-peerstore" "gx/ipfs/QmeDpqUwwdye8ABKVMPXKuWwPVURFdqTqssbTUB39E2Nwd/go-libp2p-swarm" iaddr "gx/ipfs/QmePSRaGafvmURQwQkHPDBJsaGwKXC1WpBBHVCQxdr8FPn/go-ipfs-addr" @@ -65,47 +66,42 @@ var swarmPeersCmd = &cmds.Command{ cmdkit.BoolOption("direction", "Also list information about the direction of connection"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) { - n, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env) if err != nil { res.SetError(err, cmdkit.ErrNormal) return } - if n.PeerHost == nil { - res.SetError(ErrNotOnline, cmdkit.ErrClient) - return - } - verbose, _ := req.Options["verbose"].(bool) latency, _ := req.Options["latency"].(bool) streams, _ := req.Options["streams"].(bool) direction, _ := req.Options["direction"].(bool) - conns := n.PeerHost.Network().Conns() + conns, err := api.Swarm().Peers(req.Context) + if err != nil { + res.SetError(err, cmdkit.ErrNormal) + return + } + var out connInfos for _, c := range conns { - pid := c.RemotePeer() - addr := c.RemoteMultiaddr() ci := connInfo{ - Addr: addr.String(), - Peer: pid.Pretty(), + Addr: c.Address().String(), + Peer: c.ID().Pretty(), } - /* - // FIXME(steb): - swcon, ok := c.(*swarm.Conn) - if ok { - ci.Muxer = fmt.Sprintf("%T", swcon.StreamConn().Conn()) - } - */ - if verbose || direction { // set direction - ci.Direction = c.Stat().Direction + ci.Direction = c.Direction() } if verbose || latency { - lat := n.Peerstore.LatencyEWMA(pid) + lat, err := c.Latency(req.Context) + if err != nil { + res.SetError(err, cmdkit.ErrNormal) + return + } + if lat == 0 { ci.Latency = "n/a" } else { @@ -113,10 +109,14 @@ var swarmPeersCmd = &cmds.Command{ } } if verbose || streams { - strs := c.GetStreams() + strs, err := c.Streams(req.Context) + if err != nil { + res.SetError(err, cmdkit.ErrNormal) + return + } for _, s := range strs { - ci.Streams = append(ci.Streams, streamInfo{Protocol: string(s.Protocol())}) + ci.Streams = append(ci.Streams, streamInfo{Protocol: string(s)}) } } sort.Sort(&ci) @@ -230,28 +230,27 @@ var swarmAddrsCmd = &cmds.Command{ "listen": swarmAddrsListenCmd, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) { - n, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env) if err != nil { res.SetError(err, cmdkit.ErrNormal) return } - if n.PeerHost == nil { - res.SetError(ErrNotOnline, cmdkit.ErrClient) + addrs, err := api.Swarm().KnownAddrs(req.Context) + if err != nil { + res.SetError(err, cmdkit.ErrNormal) return } - addrs := make(map[string][]string) - ps := n.PeerHost.Network().Peerstore() - for _, p := range ps.Peers() { + out := make(map[string][]string) + for p, paddrs := range addrs { s := p.Pretty() - for _, a := range ps.Addrs(p) { - addrs[s] = append(addrs[s], a.String()) + for _, a := range paddrs { + out[s] = append(out[s], a.String()) } - sort.Sort(sort.StringSlice(addrs[s])) } - cmds.EmitOnce(res, &addrMap{Addrs: addrs}) + cmds.EmitOnce(res, &addrMap{Addrs: out}) }, Encoders: cmds.EncoderMap{ cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error { @@ -291,25 +290,30 @@ var swarmAddrsLocalCmd = &cmds.Command{ cmdkit.BoolOption("id", "Show peer ID in addresses."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) { - n, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env) if err != nil { res.SetError(err, cmdkit.ErrNormal) return } - if n.PeerHost == nil { - res.SetError(ErrNotOnline, cmdkit.ErrClient) + showid, _ := req.Options["id"].(bool) + self, err := api.Key().Self(req.Context) + if err != nil { + res.SetError(err, cmdkit.ErrNormal) return } - showid, _ := req.Options["id"].(bool) - id := n.Identity.Pretty() + maddrs, err := api.Swarm().LocalAddrs(req.Context) + if err != nil { + res.SetError(err, cmdkit.ErrNormal) + return + } var addrs []string - for _, addr := range n.PeerHost.Addrs() { + for _, addr := range maddrs { saddr := addr.String() if showid { - saddr = path.Join(saddr, "ipfs", id) + saddr = path.Join(saddr, "ipfs", self.ID().Pretty()) } addrs = append(addrs, saddr) } @@ -330,19 +334,14 @@ var swarmAddrsListenCmd = &cmds.Command{ `, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) { - n, err := cmdenv.GetNode(env) + api, err := cmdenv.GetApi(env) if err != nil { res.SetError(err, cmdkit.ErrNormal) return } - if n.PeerHost == nil { - res.SetError(ErrNotOnline, cmdkit.ErrClient) - return - } - var addrs []string - maddrs, err := n.PeerHost.Network().InterfaceListenAddresses() + maddrs, err := api.Swarm().ListenAddrs(req.Context) if err != nil { res.SetError(err, cmdkit.ErrNormal) return diff --git a/core/coreapi/interface/key.go b/core/coreapi/interface/key.go index cc7c409fd0e..23ba612d9bc 100644 --- a/core/coreapi/interface/key.go +++ b/core/coreapi/interface/key.go @@ -33,6 +33,9 @@ type KeyAPI interface { // List lists keys stored in keystore List(ctx context.Context) ([]Key, error) + // Self returns the 'main' node key + Self(ctx context.Context) (Key, error) + // Remove removes keys from keystore. Returns ipns path of the removed key Remove(ctx context.Context, name string) (Key, error) } diff --git a/core/coreapi/interface/swarm.go b/core/coreapi/interface/swarm.go index d9aadbffa23..484b3958c3a 100644 --- a/core/coreapi/interface/swarm.go +++ b/core/coreapi/interface/swarm.go @@ -7,6 +7,7 @@ import ( "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" + net "gx/ipfs/QmZNJyx9GGCX4GeuHnLB8fxaxMLs4MjTjHokxfQcCd6Nve/go-libp2p-net" "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" pstore "gx/ipfs/Qmda4cPRvSRyox3SqgJN6DfSZGU5TtHufPTp9uXjFj71X6/go-libp2p-peerstore" ) @@ -14,7 +15,7 @@ import ( var ( ErrNotConnected = errors.New("not connected") ErrConnNotFound = errors.New("conn not found") - ) +) // ConnectionInfo contains information about a peer type ConnectionInfo interface { @@ -24,6 +25,9 @@ type ConnectionInfo interface { // Address returns the multiaddress via which we are connected with the peer Address() ma.Multiaddr + // Direction returns which way the connection was established + Direction() net.Direction + // Latency returns last known round trip time to the peer Latency(context.Context) (time.Duration, error) @@ -41,4 +45,8 @@ type SwarmAPI interface { // Peers returns the list of peers we are connected to Peers(context.Context) ([]ConnectionInfo, error) + + KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) + LocalAddrs(context.Context) ([]ma.Multiaddr, error) + ListenAddrs(context.Context) ([]ma.Multiaddr, error) } diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 46b7523c8c2..f3aea9243cd 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -216,3 +216,7 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, erro return &key{"", pid}, nil } + +func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { + return &key{"self", api.node.Identity}, nil +} diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index 09a0a33f191..23916d1e696 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -3,18 +3,19 @@ package coreapi import ( "context" "fmt" + "sort" "time" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer" ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr" + inet "gx/ipfs/QmZNJyx9GGCX4GeuHnLB8fxaxMLs4MjTjHokxfQcCd6Nve/go-libp2p-net" net "gx/ipfs/QmZNJyx9GGCX4GeuHnLB8fxaxMLs4MjTjHokxfQcCd6Nve/go-libp2p-net" + protocol "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" pstore "gx/ipfs/Qmda4cPRvSRyox3SqgJN6DfSZGU5TtHufPTp9uXjFj71X6/go-libp2p-peerstore" swarm "gx/ipfs/QmeDpqUwwdye8ABKVMPXKuWwPVURFdqTqssbTUB39E2Nwd/go-libp2p-swarm" iaddr "gx/ipfs/QmePSRaGafvmURQwQkHPDBJsaGwKXC1WpBBHVCQxdr8FPn/go-ipfs-addr" - inet "gx/ipfs/QmZNJyx9GGCX4GeuHnLB8fxaxMLs4MjTjHokxfQcCd6Nve/go-libp2p-net" - protocol "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol" ) type SwarmAPI struct { @@ -24,6 +25,7 @@ type SwarmAPI struct { type connInfo struct { api *CoreAPI conn net.Conn + dir net.Direction addr ma.Multiaddr peer peer.ID @@ -80,6 +82,29 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { return nil } +func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) { + addrs := make(map[peer.ID][]ma.Multiaddr) + ps := api.node.PeerHost.Network().Peerstore() + for _, p := range ps.Peers() { + for _, a := range ps.Addrs(p) { + addrs[p] = append(addrs[p], a) + } + sort.Slice(addrs[p], func(i, j int) bool { + return addrs[p][i].String() < addrs[p][j].String() + }) + } + + return addrs, nil +} + +func (api *SwarmAPI) LocalAddrs(context.Context) ([]ma.Multiaddr, error) { + return api.node.PeerHost.Addrs(), nil +} + +func (api *SwarmAPI) ListenAddrs(context.Context) ([]ma.Multiaddr, error) { + return api.node.PeerHost.Network().InterfaceListenAddresses() +} + func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) { if api.node.PeerHost == nil { return nil, coreiface.ErrOffline @@ -95,6 +120,7 @@ func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) ci := &connInfo{ api: api.CoreAPI, conn: c, + dir: c.Stat().Direction, addr: addr, peer: pid, @@ -122,6 +148,10 @@ func (ci *connInfo) Address() ma.Multiaddr { return ci.addr } +func (ci *connInfo) Direction() net.Direction { + return ci.dir +} + func (ci *connInfo) Latency(context.Context) (time.Duration, error) { return ci.api.node.Peerstore.LatencyEWMA(peer.ID(ci.ID())), nil }