1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-01 07:47:07 +08:00
Files
kubo/core/commands/swarm.go
Juan Batiz-Benet c84a714b16 peer change: peer.Peer -> peer.ID
this is a major refactor of the entire codebase
it changes the monolithic peer.Peer into using
a peer.ID and a peer.Peerstore.

Other changes:
- removed handshake3.
-	testutil vastly simplified peer
-	secio bugfix + debugging logs
-	testutil: RandKeyPair
-	backpressure bugfix: w.o.w.
-	peer: added hex enc/dec
-	peer: added a PeerInfo struct
  PeerInfo is a small struct used to pass around a peer with
 	a set of addresses and keys. This is not meant to be a
 	complete view of the system, but rather to model updates to
 	the peerstore. It is used by things like the routing system.
-	updated peer/queue + peerset
-	latency metrics
-	testutil: use crand for PeerID gen
 	RandPeerID generates random "valid" peer IDs. it does not
 	NEED to generate keys because it is as if we lost the key
 	right away. fine to read some randomness and hash it. to
 	generate proper keys and an ID, use:
 	  sk, pk, _ := testutil.RandKeyPair()
 	  id, _ := peer.IDFromPublicKey(pk)
 	Also added RandPeerIDFatal helper
- removed old spipe
- updated seccat
- core: cleanup initIdentity
- removed old getFromPeerList
2014-12-23 08:33:32 -08:00

175 lines
4.1 KiB
Go

package commands
import (
"bytes"
"fmt"
"path"
cmds "github.com/jbenet/go-ipfs/commands"
peer "github.com/jbenet/go-ipfs/peer"
errors "github.com/jbenet/go-ipfs/util/debugerror"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)
type stringList struct {
Strings []string
}
var SwarmCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "swarm inspection tool",
Synopsis: `
ipfs swarm peers - List peers with open connections
ipfs swarm connect <address> - Open connection to a given peer
`,
ShortDescription: `
ipfs swarm is a tool to manipulate the network swarm. The swarm is the
component that opens, listens for, and maintains connections to other
ipfs peers in the internet.
`,
},
Subcommands: map[string]*cmds.Command{
"peers": swarmPeersCmd,
"connect": swarmConnectCmd,
},
}
var swarmPeersCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "List peers with open connections",
ShortDescription: `
ipfs swarm peers lists the set of peers this node is connected to.
`,
},
Run: func(req cmds.Request) (interface{}, error) {
log.Debug("ipfs swarm peers")
n, err := req.Context().GetNode()
if err != nil {
return nil, err
}
if n.Network == nil {
return nil, errNotOnline
}
conns := n.Network.Conns()
addrs := make([]string, len(conns))
for i, c := range conns {
pid := c.RemotePeer()
addr := c.RemoteMultiaddr()
addrs[i] = fmt.Sprintf("%s/%s", addr, pid)
}
return &stringList{addrs}, nil
},
Marshalers: cmds.MarshalerMap{
cmds.Text: stringListMarshaler,
},
Type: &stringList{},
}
var swarmConnectCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Open connection to a given peer",
ShortDescription: `
'ipfs swarm connect' opens a connection to a peer address. The address format
is an ipfs multiaddr:
ipfs swarm connect /ip4/104.131.131.82/tcp/4001/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
`,
},
Arguments: []cmds.Argument{
cmds.StringArg("address", true, true, "address of peer to connect to"),
},
Run: func(req cmds.Request) (interface{}, error) {
ctx := context.TODO()
log.Debug("ipfs swarm connect")
n, err := req.Context().GetNode()
if err != nil {
return nil, err
}
addrs := req.Arguments()
if n.Network == nil {
return nil, errNotOnline
}
peers, err := peersWithAddresses(n.Peerstore, addrs)
if err != nil {
return nil, err
}
output := make([]string, len(peers))
for i, p := range peers {
output[i] = "connect " + p.Pretty()
err := n.Network.DialPeer(ctx, p)
if err != nil {
output[i] += " failure: " + err.Error()
} else {
output[i] += " success"
}
}
return &stringList{output}, nil
},
Marshalers: cmds.MarshalerMap{
cmds.Text: stringListMarshaler,
},
Type: &stringList{},
}
func stringListMarshaler(res cmds.Response) ([]byte, error) {
list, ok := res.Output().(*stringList)
if !ok {
return nil, errors.New("failed to cast []string")
}
var buf bytes.Buffer
for _, s := range list.Strings {
buf.Write([]byte(s))
buf.Write([]byte("\n"))
}
return buf.Bytes(), nil
}
// splitAddresses is a function that takes in a slice of string peer addresses
// (multiaddr + peerid) and returns slices of multiaddrs and peerids.
func splitAddresses(addrs []string) (maddrs []ma.Multiaddr, pids []peer.ID, err error) {
maddrs = make([]ma.Multiaddr, len(addrs))
pids = make([]peer.ID, len(addrs))
for i, addr := range addrs {
a, err := ma.NewMultiaddr(path.Dir(addr))
if err != nil {
return nil, nil, cmds.ClientError("invalid peer address: " + err.Error())
}
id, err := peer.IDB58Decode(path.Base(addr))
if err != nil {
return nil, nil, err
}
pids[i] = id
maddrs[i] = a
}
return
}
// peersWithAddresses is a function that takes in a slice of string peer addresses
// (multiaddr + peerid) and returns a slice of properly constructed peers
func peersWithAddresses(ps peer.Peerstore, addrs []string) ([]peer.ID, error) {
maddrs, pids, err := splitAddresses(addrs)
if err != nil {
return nil, err
}
for i, p := range pids {
ps.AddAddress(p, maddrs[i])
}
return pids, nil
}