diff --git a/core/commands/peers.go b/core/commands/peers.go new file mode 100644 index 00000000000..0ca4e758053 --- /dev/null +++ b/core/commands/peers.go @@ -0,0 +1,50 @@ +package commands + +import ( + "encoding/json" + "io" + + "github.com/jbenet/go-ipfs/core" + b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58" +) + +// peerInfo is a representation of a peer.Peer that is better suited for serialization +type peerInfo struct { + ID string + Addresses []string + PubKey string + Latency int64 +} + +func Peers(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error { + enc := json.NewEncoder(out) + peers := make([]peerInfo, len(*n.PeerMap)) + + for i, p := range *n.PeerMap { + addrs := make([]string, len(p.Addresses)) + for j, addr := range p.Addresses { + addrStr, err := addr.String() + if err != nil { + return err + } + addrs[j] = addrStr + } + + pubkeyBytes, err := p.PubKey.Bytes() + if err != nil { + return err + } + + peer := peerInfo{ + ID: p.ID.Pretty(), + Addresses: addrs, + PubKey: b58.Encode(pubkeyBytes), + Latency: p.GetLatency().Nanoseconds(), + } + peers[i] = peer + } + + enc.Encode(peers) + + return nil +} diff --git a/core/core.go b/core/core.go index 0a9db055a9e..3d1ba718795 100644 --- a/core/core.go +++ b/core/core.go @@ -76,6 +76,7 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) { var ( net *swarm.Swarm + peers *peer.Map // TODO: refactor so we can use IpfsRouting interface instead of being DHT-specific route* dht.IpfsDHT swap *bitswap.BitSwap @@ -88,13 +89,15 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) { return nil, err } + peers = &peer.Map{} + route = dht.NewDHT(local, net, d) route.Start() swap = bitswap.NewBitSwap(local, net, d, route) swap.SetStrategy(bitswap.YesManStrategy) - go initConnections(cfg, route) + go initConnections(cfg, peers, route) } bs, err := bserv.NewBlockService(d, swap) @@ -106,7 +109,7 @@ func NewIpfsNode(cfg *config.Config, online bool) (*IpfsNode, error) { return &IpfsNode{ Config: cfg, - PeerMap: &peer.Map{}, + PeerMap: peers, Datastore: d, Blocks: bs, DAG: dag, @@ -155,18 +158,20 @@ func initIdentity(cfg *config.Config) (*peer.Peer, error) { }, nil } -func initConnections(cfg *config.Config, route *dht.IpfsDHT) { - for _, p := range cfg.Peers { - maddr, err := ma.NewMultiaddr(p.Address) +func initConnections(cfg *config.Config, peers *peer.Map, route *dht.IpfsDHT) { + for _, sp := range cfg.Peers { + maddr, err := ma.NewMultiaddr(sp.Address) if err != nil { u.PErr("error: %v\n", err) continue } - _, err = route.Connect(maddr) + p, err := route.Connect(maddr) if err != nil { u.PErr("Bootstrapping error: %v\n", err) } + + (*peers)[p.Key()] = p } } diff --git a/daemon/daemon.go b/daemon/daemon.go index f1983e5027c..48b339a1fcc 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -81,6 +81,8 @@ func (dl *DaemonListener) handleConnection(conn net.Conn) { err = commands.Ls(dl.node, command.Args, command.Opts, conn) case "pin": err = commands.Pin(dl.node, command.Args, command.Opts, conn) + case "peers": + err = commands.Peers(dl.node, command.Args, command.Opts, conn) default: err = fmt.Errorf("Invalid Command: '%s'", command.Command) }