master
go 187 lines 3.88 KB
Raw
1 package rpc
2
3 import (
4 "context"
5 "time"
6
7 iface "github.com/ipfs/kubo/core/coreiface"
8 "github.com/libp2p/go-libp2p/core/network"
9 "github.com/libp2p/go-libp2p/core/peer"
10 "github.com/libp2p/go-libp2p/core/protocol"
11 "github.com/multiformats/go-multiaddr"
12 )
13
14 type SwarmAPI HttpApi
15
16 func (api *SwarmAPI) Connect(ctx context.Context, pi peer.AddrInfo) error {
17 pidma, err := multiaddr.NewComponent("p2p", pi.ID.String())
18 if err != nil {
19 return err
20 }
21
22 saddrs := make([]string, len(pi.Addrs))
23 for i, addr := range pi.Addrs {
24 saddrs[i] = addr.Encapsulate(pidma).String()
25 }
26
27 return api.core().Request("swarm/connect", saddrs...).Exec(ctx, nil)
28 }
29
30 func (api *SwarmAPI) Disconnect(ctx context.Context, addr multiaddr.Multiaddr) error {
31 return api.core().Request("swarm/disconnect", addr.String()).Exec(ctx, nil)
32 }
33
34 type connInfo struct {
35 addr multiaddr.Multiaddr
36 peer peer.ID
37 latency time.Duration
38 muxer string
39 direction network.Direction
40 streams []protocol.ID
41 }
42
43 func (c *connInfo) ID() peer.ID {
44 return c.peer
45 }
46
47 func (c *connInfo) Address() multiaddr.Multiaddr {
48 return c.addr
49 }
50
51 func (c *connInfo) Direction() network.Direction {
52 return c.direction
53 }
54
55 func (c *connInfo) Latency() (time.Duration, error) {
56 return c.latency, nil
57 }
58
59 func (c *connInfo) Streams() ([]protocol.ID, error) {
60 return c.streams, nil
61 }
62
63 func (api *SwarmAPI) Peers(ctx context.Context) ([]iface.ConnectionInfo, error) {
64 var resp struct {
65 Peers []struct {
66 Addr string
67 Peer string
68 Latency string
69 Muxer string
70 Direction network.Direction
71 Streams []struct {
72 Protocol string
73 }
74 }
75 }
76
77 err := api.core().Request("swarm/peers").
78 Option("streams", true).
79 Option("latency", true).
80 Exec(ctx, &resp)
81 if err != nil {
82 return nil, err
83 }
84
85 res := make([]iface.ConnectionInfo, len(resp.Peers))
86 for i, conn := range resp.Peers {
87 latency, _ := time.ParseDuration(conn.Latency)
88 out := &connInfo{
89 latency: latency,
90 muxer: conn.Muxer,
91 direction: conn.Direction,
92 }
93
94 out.peer, err = peer.Decode(conn.Peer)
95 if err != nil {
96 return nil, err
97 }
98
99 out.addr, err = multiaddr.NewMultiaddr(conn.Addr)
100 if err != nil {
101 return nil, err
102 }
103
104 out.streams = make([]protocol.ID, len(conn.Streams))
105 for i, p := range conn.Streams {
106 out.streams[i] = protocol.ID(p.Protocol)
107 }
108
109 res[i] = out
110 }
111
112 return res, nil
113 }
114
115 func (api *SwarmAPI) KnownAddrs(ctx context.Context) (map[peer.ID][]multiaddr.Multiaddr, error) {
116 var out struct {
117 Addrs map[string][]string
118 }
119 if err := api.core().Request("swarm/addrs").Exec(ctx, &out); err != nil {
120 return nil, err
121 }
122 res := map[peer.ID][]multiaddr.Multiaddr{}
123 for spid, saddrs := range out.Addrs {
124 addrs := make([]multiaddr.Multiaddr, len(saddrs))
125
126 for i, addr := range saddrs {
127 a, err := multiaddr.NewMultiaddr(addr)
128 if err != nil {
129 return nil, err
130 }
131 addrs[i] = a
132 }
133
134 pid, err := peer.Decode(spid)
135 if err != nil {
136 return nil, err
137 }
138
139 res[pid] = addrs
140 }
141
142 return res, nil
143 }
144
145 func (api *SwarmAPI) LocalAddrs(ctx context.Context) ([]multiaddr.Multiaddr, error) {
146 var out struct {
147 Strings []string
148 }
149
150 if err := api.core().Request("swarm/addrs/local").Exec(ctx, &out); err != nil {
151 return nil, err
152 }
153
154 res := make([]multiaddr.Multiaddr, len(out.Strings))
155 for i, addr := range out.Strings {
156 ma, err := multiaddr.NewMultiaddr(addr)
157 if err != nil {
158 return nil, err
159 }
160 res[i] = ma
161 }
162 return res, nil
163 }
164
165 func (api *SwarmAPI) ListenAddrs(ctx context.Context) ([]multiaddr.Multiaddr, error) {
166 var out struct {
167 Strings []string
168 }
169
170 if err := api.core().Request("swarm/addrs/listen").Exec(ctx, &out); err != nil {
171 return nil, err
172 }
173
174 res := make([]multiaddr.Multiaddr, len(out.Strings))
175 for i, addr := range out.Strings {
176 ma, err := multiaddr.NewMultiaddr(addr)
177 if err != nil {
178 return nil, err
179 }
180 res[i] = ma
181 }
182 return res, nil
183 }
184
185 func (api *SwarmAPI) core() *HttpApi {
186 return (*HttpApi)(api)
187 }