Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit 0819117

Browse files
committed
Support for P2P listeners and streams
1 parent 678a362 commit 0819117

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

p2p.go

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package shell
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"strconv"
7+
8+
ma "github.com/multiformats/go-multiaddr"
9+
)
10+
11+
// P2PListener describes a P2P listener.
12+
type P2PListener struct {
13+
Protocol string
14+
Address string
15+
}
16+
17+
// P2POpenListener forwards P2P connections to a network multiaddr.
18+
func (s *Shell) P2POpenListener(ctx context.Context, protocol, maddr string) (*P2PListener, error) {
19+
if _, err := ma.NewMultiaddr(maddr); err != nil {
20+
return nil, err
21+
}
22+
23+
req := s.newRequest(ctx, "p2p/listener/open", protocol, maddr)
24+
resp, err := req.Send(s.httpcli)
25+
if err != nil {
26+
return nil, err
27+
}
28+
defer resp.Close()
29+
30+
if resp.Error != nil {
31+
return nil, resp.Error
32+
}
33+
34+
var response *P2PListener
35+
if err := json.NewDecoder(resp.Output).Decode(&response); err != nil {
36+
return nil, err
37+
}
38+
39+
return response, nil
40+
}
41+
42+
// P2PCloseListener closes one or all active P2P listeners.
43+
func (s *Shell) P2PCloseListener(ctx context.Context, protocol string, closeAll bool) error {
44+
var args []string
45+
if protocol != "" {
46+
args = append(args, protocol)
47+
}
48+
49+
req := s.newRequest(ctx, "p2p/listener/close", args...)
50+
req.Opts["all"] = strconv.FormatBool(closeAll)
51+
52+
resp, err := req.Send(s.httpcli)
53+
if err != nil {
54+
return err
55+
}
56+
defer resp.Close()
57+
58+
if resp.Error != nil {
59+
return resp.Error
60+
}
61+
62+
return nil
63+
}
64+
65+
// P2PListenerList contains a slice of P2PListeners.
66+
type P2PListenerList struct {
67+
Listeners []*P2PListener
68+
}
69+
70+
// P2PListListeners lists all P2P listeners.
71+
func (s *Shell) P2PListListeners(ctx context.Context) (*P2PListenerList, error) {
72+
req := s.newRequest(ctx, "p2p/listener/ls")
73+
resp, err := req.Send(s.httpcli)
74+
if err != nil {
75+
return nil, err
76+
}
77+
defer resp.Close()
78+
79+
if resp.Error != nil {
80+
return nil, resp.Error
81+
}
82+
83+
var response *P2PListenerList
84+
if err := json.NewDecoder(resp.Output).Decode(&response); err != nil {
85+
return nil, err
86+
}
87+
88+
return response, nil
89+
}
90+
91+
// P2PStream describes a P2P stream.
92+
type P2PStream struct {
93+
Protocol string
94+
Address string
95+
}
96+
97+
// P2PStreamDial dials to a peer's P2P listener.
98+
func (s *Shell) P2PStreamDial(ctx context.Context, peerID, protocol, listenerMaddr string) (*P2PStream, error) {
99+
if listenerMaddr != "" {
100+
if _, err := ma.NewMultiaddr(listenerMaddr); err != nil {
101+
return nil, err
102+
}
103+
}
104+
105+
args := []string{peerID, protocol}
106+
if listenerMaddr != "" {
107+
args = append(args, listenerMaddr)
108+
}
109+
110+
req := s.newRequest(ctx, "p2p/stream/dial", args...)
111+
resp, err := req.Send(s.httpcli)
112+
if err != nil {
113+
return nil, err
114+
}
115+
defer resp.Close()
116+
117+
if resp.Error != nil {
118+
return nil, resp.Error
119+
}
120+
121+
var response *P2PStream
122+
if err := json.NewDecoder(resp.Output).Decode(&response); err != nil {
123+
return nil, err
124+
}
125+
126+
return response, nil
127+
}
128+
129+
// P2PCloseStream closes one or all active P2P streams.
130+
func (s *Shell) P2PCloseStream(ctx context.Context, handlerID string, closeAll bool) error {
131+
var args []string
132+
if handlerID != "" {
133+
args = append(args, handlerID)
134+
}
135+
136+
req := s.newRequest(ctx, "p2p/stream/close", args...)
137+
req.Opts["all"] = strconv.FormatBool(closeAll)
138+
139+
resp, err := req.Send(s.httpcli)
140+
if err != nil {
141+
return err
142+
}
143+
defer resp.Close()
144+
145+
if resp.Error != nil {
146+
return resp.Error
147+
}
148+
149+
return nil
150+
}
151+
152+
// P2PStreamsList contains a slice of streams.
153+
type P2PStreamsList struct {
154+
Streams []*struct {
155+
HandlerID string
156+
Protocol string
157+
LocalPeer string
158+
LocalAddress string
159+
RemotePeer string
160+
RemoteAddress string
161+
}
162+
}
163+
164+
// P2PListStreams lists all P2P streams.
165+
func (s *Shell) P2PListStreams(ctx context.Context) (*P2PStreamsList, error) {
166+
req := s.newRequest(ctx, "p2p/stream/ls")
167+
req.Opts["headers"] = strconv.FormatBool(true)
168+
169+
resp, err := req.Send(s.httpcli)
170+
if err != nil {
171+
return nil, err
172+
}
173+
defer resp.Close()
174+
175+
if resp.Error != nil {
176+
return nil, resp.Error
177+
}
178+
179+
var response *P2PStreamsList
180+
if err := json.NewDecoder(resp.Output).Decode(&response); err != nil {
181+
return nil, err
182+
}
183+
184+
return response, nil
185+
}

p2p_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package shell
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/cheekybits/is"
8+
)
9+
10+
func TestP2PListener(t *testing.T) {
11+
is := is.New(t)
12+
s := NewShell(shellUrl)
13+
14+
listener, err := s.P2POpenListener(context.Background(), "p2p-open-listener-test", "/ip4/127.0.0.1/udp/3000")
15+
is.Nil(err)
16+
is.Equal(listener.Address, "/ip4/127.0.0.1/udp/3000")
17+
is.Equal(listener.Protocol, "/p2p/p2p-open-listener-test")
18+
19+
listenerList, err := s.P2PListListeners(context.Background())
20+
is.Nil(err)
21+
is.Equal(len(listenerList.Listeners), 1)
22+
is.Equal(listenerList.Listeners[0].Address, "/ip4/127.0.0.1/udp/3000")
23+
is.Equal(listenerList.Listeners[0].Protocol, "/p2p/p2p-open-listener-test")
24+
25+
is.Nil(s.P2PCloseListener(context.Background(), "p2p-open-listener-test", false))
26+
27+
listenerList, err = s.P2PListListeners(context.Background())
28+
is.Nil(err)
29+
is.Equal(len(listenerList.Listeners), 0)
30+
}
31+
32+
func TestP2PStreams(t *testing.T) {
33+
is := is.New(t)
34+
s := NewShell(shellUrl)
35+
36+
streamsList, err := s.P2PListStreams(context.Background())
37+
is.Nil(err)
38+
is.Equal(len(streamsList.Streams), 0)
39+
}

0 commit comments

Comments
 (0)