mirror of
https://github.com/ipfs/kubo.git
synced 2025-08-06 19:44:01 +08:00
174 lines
3.8 KiB
Go
174 lines
3.8 KiB
Go
package coreapi
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"time"
|
|
|
|
ma "gx/ipfs/QmTZBfrPJmjWsCvHEtX5FE6KimVJhsJg5sBbqEFYf4UZtL/go-multiaddr"
|
|
coreiface "gx/ipfs/QmVzvYWRABgGEv4iu3M9wivWbZKTW29qsU4VTZ2iZEoExX/interface-go-ipfs-core"
|
|
swarm "gx/ipfs/QmX9A6whepz59nU5jU9fbVQGkZQspdWkvcpP7gCihoKnGS/go-libp2p-swarm"
|
|
inet "gx/ipfs/QmY3ArotKMKaL7YGfbQfyDrib6RVraLqZYWXZvVgZktBxp/go-libp2p-net"
|
|
net "gx/ipfs/QmY3ArotKMKaL7YGfbQfyDrib6RVraLqZYWXZvVgZktBxp/go-libp2p-net"
|
|
peer "gx/ipfs/QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h/go-libp2p-peer"
|
|
protocol "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"
|
|
pstore "gx/ipfs/QmaCTz9RkrU13bm9kMB54f7atgqM4qkjDZpRwRoJiWXEqs/go-libp2p-peerstore"
|
|
iaddr "gx/ipfs/Qmdf1djucJ1jX5RMF1bDbFg5ybZnupmSAeETQQ3ZV7z6dU/go-ipfs-addr"
|
|
)
|
|
|
|
type SwarmAPI CoreAPI
|
|
|
|
type connInfo struct {
|
|
peerstore pstore.Peerstore
|
|
conn net.Conn
|
|
dir net.Direction
|
|
|
|
addr ma.Multiaddr
|
|
peer peer.ID
|
|
muxer string
|
|
}
|
|
|
|
func (api *SwarmAPI) Connect(ctx context.Context, pi pstore.PeerInfo) error {
|
|
if api.peerHost == nil {
|
|
return coreiface.ErrOffline
|
|
}
|
|
|
|
if swrm, ok := api.peerHost.Network().(*swarm.Swarm); ok {
|
|
swrm.Backoff().Clear(pi.ID)
|
|
}
|
|
|
|
return api.peerHost.Connect(ctx, pi)
|
|
}
|
|
|
|
func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error {
|
|
if api.peerHost == nil {
|
|
return coreiface.ErrOffline
|
|
}
|
|
|
|
ia, err := iaddr.ParseMultiaddr(ma.Multiaddr(addr))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
taddr := ia.Transport()
|
|
id := ia.ID()
|
|
net := api.peerHost.Network()
|
|
|
|
if taddr == nil {
|
|
if net.Connectedness(id) != inet.Connected {
|
|
return coreiface.ErrNotConnected
|
|
} else if err := net.ClosePeer(id); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
for _, conn := range net.ConnsToPeer(id) {
|
|
if !conn.RemoteMultiaddr().Equal(taddr) {
|
|
continue
|
|
}
|
|
|
|
return conn.Close()
|
|
}
|
|
|
|
return coreiface.ErrConnNotFound
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) {
|
|
if api.peerHost == nil {
|
|
return nil, coreiface.ErrOffline
|
|
}
|
|
|
|
addrs := make(map[peer.ID][]ma.Multiaddr)
|
|
ps := api.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) {
|
|
if api.peerHost == nil {
|
|
return nil, coreiface.ErrOffline
|
|
}
|
|
|
|
return api.peerHost.Addrs(), nil
|
|
}
|
|
|
|
func (api *SwarmAPI) ListenAddrs(context.Context) ([]ma.Multiaddr, error) {
|
|
if api.peerHost == nil {
|
|
return nil, coreiface.ErrOffline
|
|
}
|
|
|
|
return api.peerHost.Network().InterfaceListenAddresses()
|
|
}
|
|
|
|
func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) {
|
|
if api.peerHost == nil {
|
|
return nil, coreiface.ErrOffline
|
|
}
|
|
|
|
conns := api.peerHost.Network().Conns()
|
|
|
|
var out []coreiface.ConnectionInfo
|
|
for _, c := range conns {
|
|
pid := c.RemotePeer()
|
|
addr := c.RemoteMultiaddr()
|
|
|
|
ci := &connInfo{
|
|
peerstore: api.peerstore,
|
|
conn: c,
|
|
dir: c.Stat().Direction,
|
|
|
|
addr: addr,
|
|
peer: pid,
|
|
}
|
|
|
|
/*
|
|
// FIXME(steb):
|
|
swcon, ok := c.(*swarm.Conn)
|
|
if ok {
|
|
ci.muxer = fmt.Sprintf("%T", swcon.StreamConn().Conn())
|
|
}
|
|
*/
|
|
|
|
out = append(out, ci)
|
|
}
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func (ci *connInfo) ID() peer.ID {
|
|
return ci.peer
|
|
}
|
|
|
|
func (ci *connInfo) Address() ma.Multiaddr {
|
|
return ci.addr
|
|
}
|
|
|
|
func (ci *connInfo) Direction() net.Direction {
|
|
return ci.dir
|
|
}
|
|
|
|
func (ci *connInfo) Latency() (time.Duration, error) {
|
|
return ci.peerstore.LatencyEWMA(peer.ID(ci.ID())), nil
|
|
}
|
|
|
|
func (ci *connInfo) Streams() ([]protocol.ID, error) {
|
|
streams := ci.conn.GetStreams()
|
|
|
|
out := make([]protocol.ID, len(streams))
|
|
for i, s := range streams {
|
|
out[i] = s.Protocol()
|
|
}
|
|
|
|
return out, nil
|
|
}
|