swap net2 -> net
Juan Batiz-Benet committed
Jan 1, 2015 at 12:45 UTC
8fb5cf95786304592d5aa994351af1211d2f3cb1
91 files changed
+411
-6460
core/bootstrap.go
+17
-16
@@ -8,6 +8,7 @@ import (
8
"time"
9
10
config "github.com/jbenet/go-ipfs/config"
11
+ host "github.com/jbenet/go-ipfs/p2p/host"
12
inet "github.com/jbenet/go-ipfs/p2p/net"
13
peer "github.com/jbenet/go-ipfs/p2p/peer"
14
dht "github.com/jbenet/go-ipfs/routing/dht"
@@ -25,7 +26,7 @@ const (
26
)
27
28
func superviseConnections(parent context.Context,
28
- n inet.Network,
29
+ h host.Host,
30
route *dht.IpfsDHT, // TODO depend on abstract interface for testing purposes
31
store peer.Peerstore,
32
peers []*config.BootstrapPeer) error {
@@ -34,7 +35,7 @@ func superviseConnections(parent context.Context,
35
ctx, _ := context.WithTimeout(parent, connectiontimeout)
36
// TODO get config from disk so |peers| always reflects the latest
37
// information
37
- if err := bootstrap(ctx, n, route, store, peers); err != nil {
38
+ if err := bootstrap(ctx, h, route, store, peers); err != nil {
39
log.Error(err)
40
}
41
select {
@@ -47,30 +48,30 @@ func superviseConnections(parent context.Context,
48
}
49
50
func bootstrap(ctx context.Context,
50
- n inet.Network,
51
+ h host.Host,
52
r *dht.IpfsDHT,
53
ps peer.Peerstore,
54
boots []*config.BootstrapPeer) error {
55
55
- connectedPeers := n.Peers()
56
+ connectedPeers := h.Network().Peers()
57
if len(connectedPeers) >= recoveryThreshold {
57
- log.Event(ctx, "bootstrapSkip", n.LocalPeer())
58
+ log.Event(ctx, "bootstrapSkip", h.ID())
59
log.Debugf("%s bootstrap skipped -- connected to %d (> %d) nodes",
59
- n.LocalPeer(), len(connectedPeers), recoveryThreshold)
60
+ h.ID(), len(connectedPeers), recoveryThreshold)
61
62
return nil
63
}
64
numCxnsToCreate := recoveryThreshold - len(connectedPeers)
65
65
- log.Event(ctx, "bootstrapStart", n.LocalPeer())
66
- log.Debugf("%s bootstrapping to %d more nodes", n.LocalPeer(), numCxnsToCreate)
66
+ log.Event(ctx, "bootstrapStart", h.ID())
67
+ log.Debugf("%s bootstrapping to %d more nodes", h.ID(), numCxnsToCreate)
68
69
var bootstrapPeers []peer.PeerInfo
70
for _, bootstrap := range boots {
71
p, err := toPeer(bootstrap)
72
if err != nil {
72
- log.Event(ctx, "bootstrapError", n.LocalPeer(), lgbl.Error(err))
73
- log.Errorf("%s bootstrap error: %s", n.LocalPeer(), err)
73
+ log.Event(ctx, "bootstrapError", h.ID(), lgbl.Error(err))
74
+ log.Errorf("%s bootstrap error: %s", h.ID(), err)
75
return err
76
}
77
bootstrapPeers = append(bootstrapPeers, p)
@@ -78,7 +79,7 @@ func bootstrap(ctx context.Context,
79
80
var notConnected []peer.PeerInfo
81
for _, p := range bootstrapPeers {
81
- if n.Connectedness(p.ID) != inet.Connected {
82
+ if h.Network().Connectedness(p.ID) != inet.Connected {
83
notConnected = append(notConnected, p)
84
}
85
}
@@ -86,17 +87,17 @@ func bootstrap(ctx context.Context,
87
if len(notConnected) < 1 {
88
s := "must bootstrap to %d more nodes, but already connected to all candidates"
89
err := fmt.Errorf(s, numCxnsToCreate)
89
- log.Event(ctx, "bootstrapError", n.LocalPeer(), lgbl.Error(err))
90
- log.Errorf("%s bootstrap error: %s", n.LocalPeer(), err)
90
+ log.Event(ctx, "bootstrapError", h.ID(), lgbl.Error(err))
91
+ log.Errorf("%s bootstrap error: %s", h.ID(), err)
92
return err
93
}
94
95
var randomSubset = randomSubsetOfPeers(notConnected, numCxnsToCreate)
96
96
- log.Debugf("%s bootstrapping to %d nodes: %s", n.LocalPeer(), numCxnsToCreate, randomSubset)
97
+ log.Debugf("%s bootstrapping to %d nodes: %s", h.ID(), numCxnsToCreate, randomSubset)
98
if err := connect(ctx, ps, r, randomSubset); err != nil {
98
- log.Event(ctx, "bootstrapError", n.LocalPeer(), lgbl.Error(err))
99
- log.Errorf("%s bootstrap error: %s", n.LocalPeer(), err)
99
+ log.Event(ctx, "bootstrapError", h.ID(), lgbl.Error(err))
100
+ log.Errorf("%s bootstrap error: %s", h.ID(), err)
101
return err
102
}
103
return nil
core/commands/publish.go
+1
-1
@@ -53,7 +53,7 @@ Publish a <ref> to another public key:
53
54
args := req.Arguments()
55
56
- if n.Network == nil {
56
+ if n.PeerHost == nil {
57
return nil, errNotOnline
58
}
59
core/commands/resolve.go
+1
-1
@@ -47,7 +47,7 @@ Resolve te value of another name:
47
48
var name string
49
50
- if n.Network == nil {
50
+ if n.PeerHost == nil {
51
return nil, errNotOnline
52
}
53
core/commands/swarm.go
+4
-4
@@ -51,11 +51,11 @@ ipfs swarm peers lists the set of peers this node is connected to.
51
return nil, err
52
}
53
54
- if n.Network == nil {
54
+ if n.PeerHost == nil {
55
return nil, errNotOnline
56
}
57
58
- conns := n.Network.Conns()
58
+ conns := n.PeerHost.Network().Conns()
59
addrs := make([]string, len(conns))
60
for i, c := range conns {
61
pid := c.RemotePeer()
@@ -95,7 +95,7 @@ ipfs swarm connect /ip4/104.131.131.82/tcp/4001/QmaCpDMGvV2BGHeYERUEnRQAwe3N8Szb
95
96
addrs := req.Arguments()
97
98
- if n.Network == nil {
98
+ if n.PeerHost == nil {
99
return nil, errNotOnline
100
}
101
@@ -108,7 +108,7 @@ ipfs swarm connect /ip4/104.131.131.82/tcp/4001/QmaCpDMGvV2BGHeYERUEnRQAwe3N8Szb
108
for i, p := range peers {
109
output[i] = "connect " + p.Pretty()
110
111
- err := n.Network.DialPeer(ctx, p)
111
+ err := n.PeerHost.Connect(ctx, peer.PeerInfo{ID: p})
112
if err != nil {
113
output[i] += " failure: " + err.Error()
114
} else {
core/core.go
+12
-10
@@ -20,8 +20,9 @@ import (
20
merkledag "github.com/jbenet/go-ipfs/merkledag"
21
namesys "github.com/jbenet/go-ipfs/namesys"
22
ic "github.com/jbenet/go-ipfs/p2p/crypto"
23
- inet "github.com/jbenet/go-ipfs/p2p/net"
24
- swarmnet "github.com/jbenet/go-ipfs/p2p/net/swarmnet"
23
+ p2phost "github.com/jbenet/go-ipfs/p2p/host"
24
+ p2pbhost "github.com/jbenet/go-ipfs/p2p/host/basic"
25
+ swarm "github.com/jbenet/go-ipfs/p2p/net/swarm"
26
peer "github.com/jbenet/go-ipfs/p2p/peer"
27
path "github.com/jbenet/go-ipfs/path"
28
pin "github.com/jbenet/go-ipfs/pin"
@@ -53,7 +54,7 @@ type IpfsNode struct {
54
55
// Services
56
Peerstore peer.Peerstore // storage for other Peer instances
56
- Network inet.Network // the network message stream
57
+ PeerHost p2phost.Host // the network host (server+client)
58
Routing routing.IpfsRouting // the routing system. recommend ipfs-dht
59
Exchange exchange.Interface // the block exchange + strategy (bitswap)
60
Blocks *bserv.BlockService // the block service, get/add blocks.
@@ -122,16 +123,17 @@ func NewIpfsNode(ctx context.Context, cfg *config.Config, online bool) (n *IpfsN
123
return nil, debugerror.Wrap(err)
124
}
125
125
- n.Network, err = swarmnet.NewNetwork(ctx, listenAddrs, n.Identity, n.Peerstore)
126
+ network, err := swarm.NewNetwork(ctx, listenAddrs, n.Identity, n.Peerstore)
127
if err != nil {
128
return nil, debugerror.Wrap(err)
129
}
129
- n.AddChildGroup(n.Network.CtxGroup())
130
+ n.AddChildGroup(network.CtxGroup())
131
+ n.PeerHost = p2pbhost.New(network)
132
133
// explicitly set these as our listen addrs.
134
// (why not do it inside inet.NewNetwork? because this way we can
135
// listen on addresses without necessarily advertising those publicly.)
134
- addrs, err := n.Network.InterfaceListenAddresses()
136
+ addrs, err := n.PeerHost.Network().InterfaceListenAddresses()
137
if err != nil {
138
return nil, debugerror.Wrap(err)
139
}
@@ -139,10 +141,10 @@ func NewIpfsNode(ctx context.Context, cfg *config.Config, online bool) (n *IpfsN
141
n.Peerstore.AddAddresses(n.Identity, addrs)
142
143
// setup diagnostics service
142
- n.Diagnostics = diag.NewDiagnostics(n.Identity, n.Network)
144
+ n.Diagnostics = diag.NewDiagnostics(n.Identity, n.PeerHost)
145
146
// setup routing service
145
- dhtRouting := dht.NewDHT(ctx, n.Identity, n.Network, n.Datastore)
147
+ dhtRouting := dht.NewDHT(ctx, n.PeerHost, n.Datastore)
148
dhtRouting.Validators[IpnsValidatorTag] = namesys.ValidateIpnsRecord
149
150
// TODO(brian): perform this inside NewDHT factory method
@@ -151,7 +153,7 @@ func NewIpfsNode(ctx context.Context, cfg *config.Config, online bool) (n *IpfsN
153
154
// setup exchange service
155
const alwaysSendToPeer = true // use YesManStrategy
154
- bitswapNetwork := bsnet.NewFromIpfsNetwork(n.Network, n.Routing)
156
+ bitswapNetwork := bsnet.NewFromIpfsHost(n.PeerHost, n.Routing)
157
158
n.Exchange = bitswap.New(ctx, n.Identity, bitswapNetwork, blockstore, alwaysSendToPeer)
159
@@ -161,7 +163,7 @@ func NewIpfsNode(ctx context.Context, cfg *config.Config, online bool) (n *IpfsN
163
// an Exchange, Network, or Routing component and have the constructor
164
// manage the wiring. In that scenario, this dangling function is a bit
165
// awkward.
164
- go superviseConnections(ctx, n.Network, dhtRouting, n.Peerstore, n.Config.Bootstrap)
166
+ go superviseConnections(ctx, n.PeerHost, dhtRouting, n.Peerstore, n.Config.Bootstrap)
167
}
168
169
// TODO(brian): when offline instantiate the BlockService with a bitswap
core/mock.go
+6
-4
@@ -11,12 +11,12 @@ import (
11
mdag "github.com/jbenet/go-ipfs/merkledag"
12
nsys "github.com/jbenet/go-ipfs/namesys"
13
ci "github.com/jbenet/go-ipfs/p2p/crypto"
14
- "github.com/jbenet/go-ipfs/p2p/net/mock"
14
+ mocknet "github.com/jbenet/go-ipfs/p2p/net/mock"
15
peer "github.com/jbenet/go-ipfs/p2p/peer"
16
path "github.com/jbenet/go-ipfs/path"
17
dht "github.com/jbenet/go-ipfs/routing/dht"
18
ds2 "github.com/jbenet/go-ipfs/util/datastore2"
19
- "github.com/jbenet/go-ipfs/util/testutil"
19
+ testutil "github.com/jbenet/go-ipfs/util/testutil"
20
)
21
22
// TODO this is super sketch. Deprecate and initialize one that shares code
@@ -44,16 +44,18 @@ func NewMockNode() (*IpfsNode, error) {
44
nd.Peerstore = peer.NewPeerstore()
45
nd.Peerstore.AddPrivKey(p, sk)
46
nd.Peerstore.AddPubKey(p, pk)
47
- nd.Network, err = mocknet.New(ctx).AddPeer(sk, testutil.RandLocalTCPAddress()) // effectively offline
47
+
48
+ nd.PeerHost, err = mocknet.New(ctx).AddPeer(sk, testutil.RandLocalTCPAddress()) // effectively offline
49
if err != nil {
50
return nil, err
51
}
52
+
53
// Temp Datastore
54
dstore := ds.NewMapDatastore()
55
nd.Datastore = ds2.CloserWrap(syncds.MutexWrap(dstore))
56
57
// Routing
56
- dht := dht.NewDHT(ctx, nd.Identity, nd.Network, nd.Datastore)
58
+ dht := dht.NewDHT(ctx, nd.PeerHost, nd.Datastore)
59
nd.Routing = dht
60
61
// Bitswap
diagnostics/diag.go
+23
-19
@@ -17,21 +17,27 @@ import (
17
ggio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io"
18
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
19
20
- pb "github.com/jbenet/go-ipfs/diagnostics/internal/pb"
21
- net "github.com/jbenet/go-ipfs/p2p/net"
20
+ host "github.com/jbenet/go-ipfs/p2p/host"
21
+ inet "github.com/jbenet/go-ipfs/p2p/net"
22
peer "github.com/jbenet/go-ipfs/p2p/peer"
23
+ protocol "github.com/jbenet/go-ipfs/p2p/protocol"
24
+
25
+ pb "github.com/jbenet/go-ipfs/diagnostics/internal/pb"
26
util "github.com/jbenet/go-ipfs/util"
27
)
28
29
var log = util.Logger("diagnostics")
30
31
+// ProtocolDiag is the diagnostics protocol.ID
32
+var ProtocolDiag protocol.ID = "/ipfs/diagnostics"
33
+
34
const ResponseTimeout = time.Second * 10
35
36
// Diagnostics is a net service that manages requesting and responding to diagnostic
37
// requests
38
type Diagnostics struct {
33
- network net.Network
34
- self peer.ID
39
+ host host.Host
40
+ self peer.ID
41
42
diagLock sync.Mutex
43
diagMap map[string]time.Time
@@ -39,15 +45,15 @@ type Diagnostics struct {
45
}
46
47
// NewDiagnostics instantiates a new diagnostics service running on the given network
42
-func NewDiagnostics(self peer.ID, inet net.Network) *Diagnostics {
48
+func NewDiagnostics(self peer.ID, h host.Host) *Diagnostics {
49
d := &Diagnostics{
44
- network: inet,
50
+ host: h,
51
self: self,
52
birth: time.Now(),
53
diagMap: make(map[string]time.Time),
54
}
55
50
- inet.SetHandler(net.ProtocolDiag, d.handleNewStream)
56
+ h.SetStreamHandler(ProtocolDiag, d.handleNewStream)
57
return d
58
}
59
@@ -92,7 +98,7 @@ func (di *DiagInfo) Marshal() []byte {
98
}
99
100
func (d *Diagnostics) getPeers() []peer.ID {
95
- return d.network.Peers()
101
+ return d.host.Network().Peers()
102
}
103
104
func (d *Diagnostics) getDiagInfo() *DiagInfo {
@@ -101,10 +107,11 @@ func (d *Diagnostics) getDiagInfo() *DiagInfo {
107
di.ID = d.self.Pretty()
108
di.LifeSpan = time.Since(d.birth)
109
di.Keys = nil // Currently no way to query datastore
104
- di.BwIn, di.BwOut = d.network.BandwidthTotals()
110
+
111
+ // di.BwIn, di.BwOut = d.host.BandwidthTotals() //TODO fix this.
112
113
for _, p := range d.getPeers() {
107
- d := connDiagInfo{d.network.Peerstore().LatencyEWMA(p), p.Pretty()}
114
+ d := connDiagInfo{d.host.Peerstore().LatencyEWMA(p), p.Pretty()}
115
di.Connections = append(di.Connections, d)
116
}
117
return di
@@ -197,13 +204,13 @@ func newMessage(diagID string) *pb.Message {
204
205
func (d *Diagnostics) sendRequest(ctx context.Context, p peer.ID, pmes *pb.Message) (*pb.Message, error) {
206
200
- s, err := d.network.NewStream(net.ProtocolDiag, p)
207
+ s, err := d.host.NewStream(ProtocolDiag, p)
208
if err != nil {
209
return nil, err
210
}
211
defer s.Close()
212
206
- r := ggio.NewDelimitedReader(s, net.MessageSizeMax)
213
+ r := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
214
w := ggio.NewDelimitedWriter(s)
215
216
start := time.Now()
@@ -274,7 +281,7 @@ func (d *Diagnostics) handleDiagnostic(p peer.ID, pmes *pb.Message) (*pb.Message
281
return resp, nil
282
}
283
277
-func (d *Diagnostics) HandleMessage(ctx context.Context, s net.Stream) error {
284
+func (d *Diagnostics) HandleMessage(ctx context.Context, s inet.Stream) error {
285
286
r := ggio.NewDelimitedReader(s, 32768) // maxsize
287
w := ggio.NewDelimitedWriter(s)
@@ -312,10 +319,7 @@ func (d *Diagnostics) HandleMessage(ctx context.Context, s net.Stream) error {
319
return nil
320
}
321
315
-func (d *Diagnostics) handleNewStream(s net.Stream) {
316
-
317
- go func() {
318
- d.HandleMessage(context.Background(), s)
319
- }()
320
-
322
+func (d *Diagnostics) handleNewStream(s inet.Stream) {
323
+ d.HandleMessage(context.Background(), s)
324
+ s.Close()
325
}
epictest/addcat_test.go
+2
-2
@@ -99,11 +99,11 @@ func DirectAddCat(data []byte, conf Config) error {
99
return errors.New("test initialization error")
100
}
101
102
- adder, err := makeCore(ctx, MocknetTestRepo(peers[0], mn.Net(peers[0]), conf))
102
+ adder, err := makeCore(ctx, MocknetTestRepo(peers[0], mn.Host(peers[0]), conf))
103
if err != nil {
104
return err
105
}
106
- catter, err := makeCore(ctx, MocknetTestRepo(peers[1], mn.Net(peers[1]), conf))
106
+ catter, err := makeCore(ctx, MocknetTestRepo(peers[1], mn.Host(peers[1]), conf))
107
if err != nil {
108
return err
109
}
epictest/core.go
+7
-7
@@ -15,7 +15,7 @@ import (
15
importer "github.com/jbenet/go-ipfs/importer"
16
chunk "github.com/jbenet/go-ipfs/importer/chunk"
17
merkledag "github.com/jbenet/go-ipfs/merkledag"
18
- net "github.com/jbenet/go-ipfs/p2p/net"
18
+ host "github.com/jbenet/go-ipfs/p2p/host"
19
peer "github.com/jbenet/go-ipfs/p2p/peer"
20
path "github.com/jbenet/go-ipfs/path"
21
dht "github.com/jbenet/go-ipfs/routing/dht"
@@ -101,7 +101,7 @@ type repo struct {
101
blockstore blockstore.Blockstore
102
exchange exchange.Interface
103
datastore datastore.ThreadSafeDatastore
104
- network net.Network
104
+ host host.Host
105
dht *dht.IpfsDHT
106
id peer.ID
107
}
@@ -126,16 +126,16 @@ func (r *repo) Exchange() exchange.Interface {
126
return r.exchange
127
}
128
129
-func MocknetTestRepo(p peer.ID, n net.Network, conf Config) RepoFactory {
129
+func MocknetTestRepo(p peer.ID, h host.Host, conf Config) RepoFactory {
130
return func(ctx context.Context) (Repo, error) {
131
const kWriteCacheElems = 100
132
const alwaysSendToPeer = true
133
dsDelay := delay.Fixed(conf.BlockstoreLatency)
134
ds := sync.MutexWrap(datastore2.WithDelay(datastore.NewMapDatastore(), dsDelay))
135
136
- log.Debugf("MocknetTestRepo: %s %s %s", p, n.LocalPeer(), n)
137
- dhtt := dht.NewDHT(ctx, p, n, ds)
138
- bsn := bsnet.NewFromIpfsNetwork(n, dhtt)
136
+ log.Debugf("MocknetTestRepo: %s %s %s", p, h.ID(), h)
137
+ dhtt := dht.NewDHT(ctx, h, ds)
138
+ bsn := bsnet.NewFromIpfsHost(h, dhtt)
139
bstore, err := blockstore.WriteCached(blockstore.NewBlockstore(ds), kWriteCacheElems)
140
if err != nil {
141
return nil, err
@@ -146,7 +146,7 @@ func MocknetTestRepo(p peer.ID, n net.Network, conf Config) RepoFactory {
146
blockstore: bstore,
147
exchange: exch,
148
datastore: ds,
149
- network: n,
149
+ host: h,
150
dht: dhtt,
151
id: p,
152
}, nil
epictest/three_legged_cat_test.go
+3
-3
@@ -42,15 +42,15 @@ func RunThreeLeggedCat(data []byte, conf Config) error {
42
if len(peers) < numPeers {
43
return errors.New("test initialization error")
44
}
45
- adder, err := makeCore(ctx, MocknetTestRepo(peers[0], mn.Net(peers[0]), conf))
45
+ adder, err := makeCore(ctx, MocknetTestRepo(peers[0], mn.Host(peers[0]), conf))
46
if err != nil {
47
return err
48
}
49
- catter, err := makeCore(ctx, MocknetTestRepo(peers[1], mn.Net(peers[1]), conf))
49
+ catter, err := makeCore(ctx, MocknetTestRepo(peers[1], mn.Host(peers[1]), conf))
50
if err != nil {
51
return err
52
}
53
- bootstrap, err := makeCore(ctx, MocknetTestRepo(peers[2], mn.Net(peers[2]), conf))
53
+ bootstrap, err := makeCore(ctx, MocknetTestRepo(peers[2], mn.Host(peers[2]), conf))
54
if err != nil {
55
return err
56
}
exchange/bitswap/network/interface.go
+3
@@ -5,9 +5,12 @@ import (
5
6
bsmsg "github.com/jbenet/go-ipfs/exchange/bitswap/message"
7
peer "github.com/jbenet/go-ipfs/p2p/peer"
8
+ protocol "github.com/jbenet/go-ipfs/p2p/protocol"
9
u "github.com/jbenet/go-ipfs/util"
10
)
11
12
+var ProtocolBitswap protocol.ID = "/ipfs/bitswap"
13
+
14
// BitSwapNetwork provides network connectivity for BitSwap sessions
15
type BitSwapNetwork interface {
16
exchange/bitswap/network/ipfs_impl.go
+10
-10
@@ -3,6 +3,7 @@ package network
3
import (
4
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5
bsmsg "github.com/jbenet/go-ipfs/exchange/bitswap/message"
6
+ host "github.com/jbenet/go-ipfs/p2p/host"
7
inet "github.com/jbenet/go-ipfs/p2p/net"
8
peer "github.com/jbenet/go-ipfs/p2p/peer"
9
routing "github.com/jbenet/go-ipfs/routing"
@@ -11,21 +12,20 @@ import (
12
13
var log = util.Logger("bitswap_network")
14
14
-// NewFromIpfsNetwork returns a BitSwapNetwork supported by underlying IPFS
15
-// Dialer & Service
16
-func NewFromIpfsNetwork(n inet.Network, r routing.IpfsRouting) BitSwapNetwork {
15
+// NewFromIpfsHost returns a BitSwapNetwork supported by underlying IPFS host
16
+func NewFromIpfsHost(host host.Host, r routing.IpfsRouting) BitSwapNetwork {
17
bitswapNetwork := impl{
18
- network: n,
18
+ host: host,
19
routing: r,
20
}
21
- n.SetHandler(inet.ProtocolBitswap, bitswapNetwork.handleNewStream)
21
+ host.SetStreamHandler(ProtocolBitswap, bitswapNetwork.handleNewStream)
22
return &bitswapNetwork
23
}
24
25
// impl transforms the ipfs network interface, which sends and receives
26
// NetMessage objects, into the bitswap network interface.
27
type impl struct {
28
- network inet.Network
28
+ host host.Host
29
routing routing.IpfsRouting
30
31
// inbound messages from the network are forwarded to the receiver
@@ -33,7 +33,7 @@ type impl struct {
33
}
34
35
func (bsnet *impl) DialPeer(ctx context.Context, p peer.ID) error {
36
- return bsnet.network.DialPeer(ctx, p)
36
+ return bsnet.host.Connect(ctx, peer.PeerInfo{ID: p})
37
}
38
39
func (bsnet *impl) SendMessage(
@@ -41,7 +41,7 @@ func (bsnet *impl) SendMessage(
41
p peer.ID,
42
outgoing bsmsg.BitSwapMessage) error {
43
44
- s, err := bsnet.network.NewStream(inet.ProtocolBitswap, p)
44
+ s, err := bsnet.host.NewStream(ProtocolBitswap, p)
45
if err != nil {
46
return err
47
}
@@ -55,7 +55,7 @@ func (bsnet *impl) SendRequest(
55
p peer.ID,
56
outgoing bsmsg.BitSwapMessage) (bsmsg.BitSwapMessage, error) {
57
58
- s, err := bsnet.network.NewStream(inet.ProtocolBitswap, p)
58
+ s, err := bsnet.host.NewStream(ProtocolBitswap, p)
59
if err != nil {
60
return nil, err
61
}
@@ -79,7 +79,7 @@ func (bsnet *impl) FindProvidersAsync(ctx context.Context, k util.Key, max int)
79
defer close(out)
80
providers := bsnet.routing.FindProvidersAsync(ctx, k, max)
81
for info := range providers {
82
- bsnet.network.Peerstore().AddAddresses(info.ID, info.Addrs)
82
+ bsnet.host.Peerstore().AddAddresses(info.ID, info.Addrs)
83
select {
84
case <-ctx.Done():
85
case out <- info.ID:
exchange/bitswap/testnet/peernet.go
+1
-1
@@ -25,7 +25,7 @@ func (pn *peernet) Adapter(p testutil.Identity) bsnet.BitSwapNetwork {
25
panic(err.Error())
26
}
27
routing := pn.routingserver.ClientWithDatastore(context.TODO(), p, ds.NewMapDatastore())
28
- return bsnet.NewFromIpfsNetwork(client, routing)
28
+ return bsnet.NewFromIpfsHost(client, routing)
29
}
30
31
func (pn *peernet) HasPeer(p peer.ID) bool {
p2p/host/basic/basic_host.go
+1
-1
@@ -5,7 +5,7 @@ import (
5
6
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
7
8
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
+ inet "github.com/jbenet/go-ipfs/p2p/net"
9
peer "github.com/jbenet/go-ipfs/p2p/peer"
10
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
11
identify "github.com/jbenet/go-ipfs/p2p/protocol/identify"
p2p/host/basic/basic_host_test.go
+1
-1
@@ -5,7 +5,7 @@ import (
5
"io"
6
"testing"
7
8
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
+ inet "github.com/jbenet/go-ipfs/p2p/net"
9
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
10
testutil "github.com/jbenet/go-ipfs/p2p/test/util"
11
p2p/host/host.go
+1
-1
@@ -5,7 +5,7 @@ import (
5
6
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
7
8
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
+ inet "github.com/jbenet/go-ipfs/p2p/net"
9
peer "github.com/jbenet/go-ipfs/p2p/peer"
10
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
11
)
p2p/net/backpressure/backpressure.go
deleted
-1
@@ -1 +0,0 @@
1
-package backpressure_tests
p2p/net/backpressure/backpressure_test.go
deleted
-373
@@ -1,373 +0,0 @@
1
-package backpressure_tests
2
-
3
-import (
4
- crand "crypto/rand"
5
- "io"
6
- "math/rand"
7
- "testing"
8
- "time"
9
-
10
- inet "github.com/jbenet/go-ipfs/p2p/net"
11
- netutil "github.com/jbenet/go-ipfs/p2p/net/swarmnet/util"
12
- peer "github.com/jbenet/go-ipfs/p2p/peer"
13
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
14
-
15
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
16
-)
17
-
18
-var log = eventlog.Logger("backpressure")
19
-
20
-// TestBackpressureStreamHandler tests whether mux handler
21
-// ratelimiting works. Meaning, since the handler is sequential
22
-// it should block senders.
23
-//
24
-// Important note: spdystream (which peerstream uses) has a set
25
-// of n workers (n=spdsystream.FRAME_WORKERS) which handle new
26
-// frames, including those starting new streams. So all of them
27
-// can be in the handler at one time. Also, the sending side
28
-// does not rate limit unless we call stream.Wait()
29
-//
30
-//
31
-// Note: right now, this happens muxer-wide. the muxer should
32
-// learn to flow control, so handlers cant block each other.
33
-func TestBackpressureStreamHandler(t *testing.T) {
34
- t.Skip(`Sadly, as cool as this test is, it doesn't work
35
-Because spdystream doesnt handle stream open backpressure
36
-well IMO. I'll see about rewriting that part when it becomes
37
-a problem.
38
-`)
39
-
40
- // a number of concurrent request handlers
41
- limit := 10
42
-
43
- // our way to signal that we're done with 1 request
44
- requestHandled := make(chan struct{})
45
-
46
- // handler rate limiting
47
- receiverRatelimit := make(chan struct{}, limit)
48
- for i := 0; i < limit; i++ {
49
- receiverRatelimit <- struct{}{}
50
- }
51
-
52
- // sender counter of successfully opened streams
53
- senderOpened := make(chan struct{}, limit*100)
54
-
55
- // sender signals it's done (errored out)
56
- senderDone := make(chan struct{})
57
-
58
- // the receiver handles requests with some rate limiting
59
- receiver := func(s inet.Stream) {
60
- log.Debug("receiver received a stream")
61
-
62
- <-receiverRatelimit // acquire
63
- go func() {
64
- // our request handler. can do stuff here. we
65
- // simulate something taking time by waiting
66
- // on requestHandled
67
- log.Error("request worker handling...")
68
- <-requestHandled
69
- log.Error("request worker done!")
70
- receiverRatelimit <- struct{}{} // release
71
- }()
72
- }
73
-
74
- // the sender opens streams as fast as possible
75
- sender := func(net inet.Network, remote peer.ID) {
76
- var s inet.Stream
77
- var err error
78
- defer func() {
79
- t.Error(err)
80
- log.Debug("sender error. exiting.")
81
- senderDone <- struct{}{}
82
- }()
83
-
84
- for {
85
- s, err = net.NewStream(inet.ProtocolTesting, remote)
86
- if err != nil {
87
- return
88
- }
89
-
90
- _ = s
91
- // if err = s.SwarmStream().Stream().Wait(); err != nil {
92
- // return
93
- // }
94
-
95
- // "count" another successfully opened stream
96
- // (large buffer so shouldn't block in normal operation)
97
- log.Debug("sender opened another stream!")
98
- senderOpened <- struct{}{}
99
- }
100
- }
101
-
102
- // count our senderOpened events
103
- countStreamsOpenedBySender := func(min int) int {
104
- opened := 0
105
- for opened < min {
106
- log.Debugf("countStreamsOpenedBySender got %d (min %d)", opened, min)
107
- select {
108
- case <-senderOpened:
109
- opened++
110
- case <-time.After(10 * time.Millisecond):
111
- }
112
- }
113
- return opened
114
- }
115
-
116
- // count our received events
117
- // waitForNReceivedStreams := func(n int) {
118
- // for n > 0 {
119
- // log.Debugf("waiting for %d received streams...", n)
120
- // select {
121
- // case <-receiverRatelimit:
122
- // n--
123
- // }
124
- // }
125
- // }
126
-
127
- testStreamsOpened := func(expected int) {
128
- log.Debugf("testing rate limited to %d streams", expected)
129
- if n := countStreamsOpenedBySender(expected); n != expected {
130
- t.Fatalf("rate limiting did not work :( -- %d != %d", expected, n)
131
- }
132
- }
133
-
134
- // ok that's enough setup. let's do it!
135
-
136
- ctx := context.Background()
137
- n1 := netutil.GenNetwork(t, ctx)
138
- n2 := netutil.GenNetwork(t, ctx)
139
-
140
- // setup receiver handler
141
- n1.SetHandler(inet.ProtocolTesting, receiver)
142
-
143
- log.Debugf("dialing %s", n2.ListenAddresses())
144
- if err := n1.DialPeer(ctx, n2.LocalPeer()); err != nil {
145
- t.Fatalf("Failed to dial:", err)
146
- }
147
-
148
- // launch sender!
149
- go sender(n2, n1.LocalPeer())
150
-
151
- // ok, what do we expect to happen? the receiver should
152
- // receive 10 requests and stop receiving, blocking the sender.
153
- // we can test this by counting 10x senderOpened requests
154
-
155
- <-senderOpened // wait for the sender to successfully open some.
156
- testStreamsOpened(limit - 1)
157
-
158
- // let's "handle" 3 requests.
159
- <-requestHandled
160
- <-requestHandled
161
- <-requestHandled
162
- // the sender should've now been able to open exactly 3 more.
163
-
164
- testStreamsOpened(3)
165
-
166
- // shouldn't have opened anything more
167
- testStreamsOpened(0)
168
-
169
- // let's "handle" 100 requests in batches of 5
170
- for i := 0; i < 20; i++ {
171
- <-requestHandled
172
- <-requestHandled
173
- <-requestHandled
174
- <-requestHandled
175
- <-requestHandled
176
- testStreamsOpened(5)
177
- }
178
-
179
- // success!
180
-
181
- // now for the sugar on top: let's tear down the receiver. it should
182
- // exit the sender.
183
- n1.Close()
184
-
185
- // shouldn't have opened anything more
186
- testStreamsOpened(0)
187
-
188
- select {
189
- case <-time.After(100 * time.Millisecond):
190
- t.Error("receiver shutdown failed to exit sender")
191
- case <-senderDone:
192
- log.Info("handler backpressure works!")
193
- }
194
-}
195
-
196
-// TestStBackpressureStreamWrite tests whether streams see proper
197
-// backpressure when writing data over the network streams.
198
-func TestStBackpressureStreamWrite(t *testing.T) {
199
-
200
- // senderWrote signals that the sender wrote bytes to remote.
201
- // the value is the count of bytes written.
202
- senderWrote := make(chan int, 10000)
203
-
204
- // sender signals it's done (errored out)
205
- senderDone := make(chan struct{})
206
-
207
- // writeStats lets us listen to all the writes and return
208
- // how many happened and how much was written
209
- writeStats := func() (int, int) {
210
- writes := 0
211
- bytes := 0
212
- for {
213
- select {
214
- case n := <-senderWrote:
215
- writes++
216
- bytes = bytes + n
217
- default:
218
- log.Debugf("stats: sender wrote %d bytes, %d writes", bytes, writes)
219
- return bytes, writes
220
- }
221
- }
222
- }
223
-
224
- // sender attempts to write as fast as possible, signaling on the
225
- // completion of every write. This makes it possible to see how
226
- // fast it's actually writing. We pair this with a receiver
227
- // that waits for a signal to read.
228
- sender := func(s inet.Stream) {
229
- defer func() {
230
- s.Close()
231
- senderDone <- struct{}{}
232
- }()
233
-
234
- // ready a buffer of random data
235
- buf := make([]byte, 65536)
236
- crand.Read(buf)
237
-
238
- for {
239
- // send a randomly sized subchunk
240
- from := rand.Intn(len(buf) / 2)
241
- to := rand.Intn(len(buf) / 2)
242
- sendbuf := buf[from : from+to]
243
-
244
- n, err := s.Write(sendbuf)
245
- if err != nil {
246
- log.Debug("sender error. exiting:", err)
247
- return
248
- }
249
-
250
- log.Debugf("sender wrote %d bytes", n)
251
- senderWrote <- n
252
- }
253
- }
254
-
255
- // receive a number of bytes from a stream.
256
- // returns the number of bytes written.
257
- receive := func(s inet.Stream, expect int) {
258
- log.Debugf("receiver to read %d bytes", expect)
259
- rbuf := make([]byte, expect)
260
- n, err := io.ReadFull(s, rbuf)
261
- if err != nil {
262
- t.Error("read failed:", err)
263
- }
264
- if expect != n {
265
- t.Error("read len differs: %d != %d", expect, n)
266
- }
267
- }
268
-
269
- // ok let's do it!
270
-
271
- // setup the networks
272
- ctx := context.Background()
273
- n1 := netutil.GenNetwork(t, ctx)
274
- n2 := netutil.GenNetwork(t, ctx)
275
-
276
- netutil.DivulgeAddresses(n1, n2)
277
- netutil.DivulgeAddresses(n2, n1)
278
-
279
- // setup sender handler on 1
280
- n1.SetHandler(inet.ProtocolTesting, sender)
281
-
282
- log.Debugf("dialing %s", n2.ListenAddresses())
283
- if err := n1.DialPeer(ctx, n2.LocalPeer()); err != nil {
284
- t.Fatalf("Failed to dial:", err)
285
- }
286
-
287
- // open a stream, from 2->1, this is our reader
288
- s, err := n2.NewStream(inet.ProtocolTesting, n1.LocalPeer())
289
- if err != nil {
290
- t.Fatal(err)
291
- }
292
-
293
- // let's make sure r/w works.
294
- testSenderWrote := func(bytesE int) {
295
- bytesA, writesA := writeStats()
296
- if bytesA != bytesE {
297
- t.Errorf("numbers failed: %d =?= %d bytes, via %d writes", bytesA, bytesE, writesA)
298
- }
299
- }
300
-
301
- // 500ms rounds of lockstep write + drain
302
- roundsStart := time.Now()
303
- roundsTotal := 0
304
- for roundsTotal < (2 << 20) {
305
- // let the sender fill its buffers, it will stop sending.
306
- <-time.After(300 * time.Millisecond)
307
- b, _ := writeStats()
308
- testSenderWrote(0)
309
- testSenderWrote(0)
310
-
311
- // drain it all, wait again
312
- receive(s, b)
313
- roundsTotal = roundsTotal + b
314
- }
315
- roundsTime := time.Now().Sub(roundsStart)
316
-
317
- // now read continously, while we measure stats.
318
- stop := make(chan struct{})
319
- contStart := time.Now()
320
-
321
- go func() {
322
- for {
323
- select {
324
- case <-stop:
325
- return
326
- default:
327
- receive(s, 2<<15)
328
- }
329
- }
330
- }()
331
-
332
- contTotal := 0
333
- for contTotal < (2 << 20) {
334
- n := <-senderWrote
335
- contTotal += n
336
- }
337
- stop <- struct{}{}
338
- contTime := time.Now().Sub(contStart)
339
-
340
- // now compare! continuous should've been faster AND larger
341
- if roundsTime < contTime {
342
- t.Error("continuous should have been faster")
343
- }
344
-
345
- if roundsTotal < contTotal {
346
- t.Error("continuous should have been larger, too!")
347
- }
348
-
349
- // and a couple rounds more for good measure ;)
350
- for i := 0; i < 3; i++ {
351
- // let the sender fill its buffers, it will stop sending.
352
- <-time.After(300 * time.Millisecond)
353
- b, _ := writeStats()
354
- testSenderWrote(0)
355
- testSenderWrote(0)
356
-
357
- // drain it all, wait again
358
- receive(s, b)
359
- }
360
-
361
- // this doesn't work :(:
362
- // // now for the sugar on top: let's tear down the receiver. it should
363
- // // exit the sender.
364
- // n1.Close()
365
- // testSenderWrote(0)
366
- // testSenderWrote(0)
367
- // select {
368
- // case <-time.After(2 * time.Second):
369
- // t.Error("receiver shutdown failed to exit sender")
370
- // case <-senderDone:
371
- // log.Info("handler backpressure works!")
372
- // }
373
-}
p2p/net/conn/conn.go
+1
-13
@@ -19,11 +19,6 @@ import (
19
20
var log = eventlog.Logger("conn")
21
22
-const (
23
- // MaxMessageSize is the size of the largest single message. (4MB)
24
- MaxMessageSize = 1 << 22
25
-)
26
-
22
// ReleaseBuffer puts the given byte array back into the buffer pool,
23
// first verifying that it is the correct size
24
func ReleaseBuffer(b []byte) {
@@ -48,15 +43,8 @@ func newSingleConn(ctx context.Context, local, remote peer.ID, maconn manet.Conn
43
maconn: maconn,
44
msgrw: msgio.NewReadWriter(maconn),
45
}
51
- log.Debugf("newSingleConn %p: %v to %v", conn, local, remote)
52
-
53
- // version handshake
54
- if err := Handshake1(ctx, conn); err != nil {
55
- conn.Close()
56
- return nil, fmt.Errorf("Handshake1 failed: %s", err)
57
- }
46
59
- log.Debugf("newSingleConn %p: %v to %v finished", conn, local, remote)
47
+ log.Debugf("newSingleConn %p: %v to %v", conn, local, remote)
48
return conn, nil
49
}
50
p2p/net/conn/handshake.go
deleted
-52
@@ -1,52 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "fmt"
5
-
6
- handshake "github.com/jbenet/go-ipfs/p2p/net/handshake"
7
- hspb "github.com/jbenet/go-ipfs/p2p/net/handshake/pb"
8
-
9
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
10
- ggprotoio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io"
11
-)
12
-
13
-// Handshake1 exchanges local and remote versions and compares them
14
-// closes remote and returns an error in case of major difference
15
-func Handshake1(ctx context.Context, c Conn) error {
16
- rpeer := c.RemotePeer()
17
- lpeer := c.LocalPeer()
18
-
19
- // setup up protobuf io
20
- maxSize := 4096
21
- r := ggprotoio.NewDelimitedReader(c, maxSize)
22
- w := ggprotoio.NewDelimitedWriter(c)
23
- localH := handshake.Handshake1Msg()
24
- remoteH := new(hspb.Handshake1)
25
-
26
- // send the outgoing handshake message
27
- if err := w.WriteMsg(localH); err != nil {
28
- return err
29
- }
30
- log.Debugf("%p sent my version (%s) to %s", c, localH, rpeer)
31
- log.Event(ctx, "handshake1Sent", lpeer)
32
-
33
- select {
34
- case <-ctx.Done():
35
- return ctx.Err()
36
- default:
37
- }
38
-
39
- if err := r.ReadMsg(remoteH); err != nil {
40
- return fmt.Errorf("could not receive remote version: %q", err)
41
- }
42
- log.Debugf("%p received remote version (%s) from %s", c, remoteH, rpeer)
43
- log.Event(ctx, "handshake1Received", lpeer)
44
-
45
- if err := handshake.Handshake1Compatible(localH, remoteH); err != nil {
46
- log.Infof("%s (%s) incompatible version with %s (%s)", lpeer, localH, rpeer, remoteH)
47
- return err
48
- }
49
-
50
- log.Debugf("%s version handshake compatible %s", lpeer, rpeer)
51
- return nil
52
-}
p2p/net/handshake/README.md
deleted
-27
@@ -1,27 +0,0 @@
1
-# IFPS Handshake
2
-
3
-The IPFS Protocol Handshake is divided into three sequential steps
4
-
5
-1. Version Handshake (`Hanshake1`)
6
-2. Secure Channel (`NewSecureConn`)
7
-3. Services (`Handshake3`)
8
-
9
-Currently these parts currently happen sequentially (costing an awful 5 RTT),
10
-but can be optimized to 2 RTT.
11
-
12
-### Version Handshake
13
-
14
-The Version Handshake ensures that nodes speaking to each other can interoperate.
15
-They send each other protocol versions and ensure there is a match on the major
16
-version (semver).
17
-
18
-### Secure Channel
19
-
20
-The second part exchanges keys and establishes a secure comm channel. This
21
-follows ECDHE TLS, but *isn't* TLS. (why will be written up elsewhere).
22
-
23
-### Services
24
-
25
-The Services portion sends any additional information on nodes needed
26
-by the nodes, e.g. Listen Address (the received address could be a Dial addr),
27
-and later on can include Service listing (dht, exchange, ipns, etc).
p2p/net/handshake/doc.go
deleted
-34
@@ -1,34 +0,0 @@
1
-/*
2
-package handshake implements the ipfs handshake protocol
3
-
4
-IPFS Handshake
5
-
6
-The IPFS Protocol Handshake is divided into three sequential steps
7
-
8
-1. Version Handshake (`Hanshake1`)
9
-
10
-2. Secure Channel (`NewSecureConn`)
11
-
12
-3. Services (`Handshake3`)
13
-
14
-Currently these parts currently happen sequentially (costing an awful 5 RTT),
15
-but can be optimized to 2 RTT.
16
-
17
-Version Handshake
18
-
19
-The Version Handshake ensures that nodes speaking to each other can interoperate.
20
-They send each other protocol versions and ensure there is a match on the major
21
-version (semver).
22
-
23
-Secure Channel
24
-
25
-The second part exchanges keys and establishes a secure comm channel. This
26
-follows ECDHE TLS, but *isn't* TLS. (why will be written up elsewhere).
27
-
28
-Services
29
-
30
-The Services portion sends any additional information on nodes needed
31
-by the nodes, e.g. Listen Address (the received address could be a Dial addr),
32
-and later on can include Service listing (dht, exchange, ipns, etc).
33
-*/
34
-package handshake
p2p/net/handshake/handshake1.go
deleted
-68
@@ -1,68 +0,0 @@
1
-package handshake
2
-
3
-import (
4
- "errors"
5
- "fmt"
6
-
7
- config "github.com/jbenet/go-ipfs/config"
8
- pb "github.com/jbenet/go-ipfs/p2p/net/handshake/pb"
9
- u "github.com/jbenet/go-ipfs/util"
10
-
11
- semver "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/coreos/go-semver/semver"
12
-)
13
-
14
-var log = u.Logger("handshake")
15
-
16
-// IpfsVersion holds the current protocol version for a client running this code
17
-var IpfsVersion *semver.Version
18
-var ClientVersion = "go-ipfs/" + config.CurrentVersionNumber
19
-
20
-func init() {
21
- var err error
22
- IpfsVersion, err = semver.NewVersion("0.0.1")
23
- if err != nil {
24
- panic(fmt.Errorf("invalid protocol version: %v", err))
25
- }
26
-}
27
-
28
-// Handshake1Msg returns the current protocol version as a protobuf message
29
-func Handshake1Msg() *pb.Handshake1 {
30
- return NewHandshake1(IpfsVersion.String(), ClientVersion)
31
-}
32
-
33
-// ErrVersionMismatch is returned when two clients don't share a protocol version
34
-var ErrVersionMismatch = errors.New("protocol missmatch")
35
-
36
-// Handshake1Compatible checks whether two versions are compatible
37
-// returns nil if they are fine
38
-func Handshake1Compatible(handshakeA, handshakeB *pb.Handshake1) error {
39
- a, err := semver.NewVersion(*handshakeA.ProtocolVersion)
40
- if err != nil {
41
- return err
42
- }
43
- b, err := semver.NewVersion(*handshakeB.ProtocolVersion)
44
- if err != nil {
45
- return err
46
- }
47
-
48
- if a.Major != b.Major {
49
- return ErrVersionMismatch
50
- }
51
-
52
- return nil
53
-}
54
-
55
-// NewHandshake1 creates a new Handshake1 from the two strings
56
-func NewHandshake1(protoVer, agentVer string) *pb.Handshake1 {
57
- if protoVer == "" {
58
- protoVer = IpfsVersion.String()
59
- }
60
- if agentVer == "" {
61
- agentVer = ClientVersion
62
- }
63
-
64
- return &pb.Handshake1{
65
- ProtocolVersion: &protoVer,
66
- AgentVersion: &agentVer,
67
- }
68
-}
p2p/net/handshake/handshake1_test.go
deleted
-23
@@ -1,23 +0,0 @@
1
-package handshake
2
-
3
-import "testing"
4
-
5
-func TestH1Compatible(t *testing.T) {
6
- tcases := []struct {
7
- a, b string
8
- expected error
9
- }{
10
- {"0.0.0", "0.0.0", nil},
11
- {"1.0.0", "1.1.0", nil},
12
- {"1.0.0", "1.0.1", nil},
13
- {"0.0.0", "1.0.0", ErrVersionMismatch},
14
- {"1.0.0", "0.0.0", ErrVersionMismatch},
15
- }
16
-
17
- for i, tcase := range tcases {
18
-
19
- if Handshake1Compatible(NewHandshake1(tcase.a, ""), NewHandshake1(tcase.b, "")) != tcase.expected {
20
- t.Fatalf("case[%d] failed", i)
21
- }
22
- }
23
-}
p2p/net/handshake/pb/Makefile
deleted
-11
@@ -1,11 +0,0 @@
1
-
2
-PB = $(wildcard *.proto)
3
-GO = $(PB:.proto=.pb.go)
4
-
5
-all: $(GO)
6
-
7
-%.pb.go: %.proto
8
- protoc --gogo_out=. --proto_path=../../../../../../:/usr/local/opt/protobuf/include:. $<
9
-
10
-clean:
11
- rm *.pb.go
p2p/net/handshake/pb/handshake.pb.go
deleted
-113
@@ -1,113 +0,0 @@
1
-// Code generated by protoc-gen-gogo.
2
-// source: handshake.proto
3
-// DO NOT EDIT!
4
-
5
-/*
6
-Package handshake_pb is a generated protocol buffer package.
7
-
8
-It is generated from these files:
9
- handshake.proto
10
-
11
-It has these top-level messages:
12
- Handshake1
13
- Handshake3
14
-*/
15
-package handshake_pb
16
-
17
-import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto"
18
-import json "encoding/json"
19
-import math "math"
20
-
21
-// Reference proto, json, and math imports to suppress error if they are not otherwise used.
22
-var _ = proto.Marshal
23
-var _ = &json.SyntaxError{}
24
-var _ = math.Inf
25
-
26
-// Handshake1 is delivered _before_ the secure channel is initialized
27
-type Handshake1 struct {
28
- // protocolVersion determines compatibility between peers
29
- ProtocolVersion *string `protobuf:"bytes,1,opt,name=protocolVersion" json:"protocolVersion,omitempty"`
30
- // agentVersion is like a UserAgent string in browsers, or client version in bittorrent
31
- // includes the client name and client. e.g. "go-ipfs/0.1.0"
32
- AgentVersion *string `protobuf:"bytes,2,opt,name=agentVersion" json:"agentVersion,omitempty"`
33
- XXX_unrecognized []byte `json:"-"`
34
-}
35
-
36
-func (m *Handshake1) Reset() { *m = Handshake1{} }
37
-func (m *Handshake1) String() string { return proto.CompactTextString(m) }
38
-func (*Handshake1) ProtoMessage() {}
39
-
40
-func (m *Handshake1) GetProtocolVersion() string {
41
- if m != nil && m.ProtocolVersion != nil {
42
- return *m.ProtocolVersion
43
- }
44
- return ""
45
-}
46
-
47
-func (m *Handshake1) GetAgentVersion() string {
48
- if m != nil && m.AgentVersion != nil {
49
- return *m.AgentVersion
50
- }
51
- return ""
52
-}
53
-
54
-// Handshake3 is delivered _after_ the secure channel is initialized
55
-type Handshake3 struct {
56
- // can include all the values in handshake1, for protocol version, etc.
57
- H1 *Handshake1 `protobuf:"bytes,5,opt,name=h1" json:"h1,omitempty"`
58
- // publicKey is this node's public key (which also gives its node.ID)
59
- // - may not need to be sent, as secure channel implies it has been sent.
60
- // - then again, if we change / disable secure channel, may still want it.
61
- PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey" json:"publicKey,omitempty"`
62
- // listenAddrs are the multiaddrs the sender node listens for open connections on
63
- ListenAddrs [][]byte `protobuf:"bytes,2,rep,name=listenAddrs" json:"listenAddrs,omitempty"`
64
- // protocols are the services this node is running
65
- Protocols []string `protobuf:"bytes,3,rep,name=protocols" json:"protocols,omitempty"`
66
- // oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
67
- // this is useful information to convey to the other side, as it helps the remote endpoint
68
- // determine whether its connection to the local peer goes through NAT.
69
- ObservedAddr []byte `protobuf:"bytes,4,opt,name=observedAddr" json:"observedAddr,omitempty"`
70
- XXX_unrecognized []byte `json:"-"`
71
-}
72
-
73
-func (m *Handshake3) Reset() { *m = Handshake3{} }
74
-func (m *Handshake3) String() string { return proto.CompactTextString(m) }
75
-func (*Handshake3) ProtoMessage() {}
76
-
77
-func (m *Handshake3) GetH1() *Handshake1 {
78
- if m != nil {
79
- return m.H1
80
- }
81
- return nil
82
-}
83
-
84
-func (m *Handshake3) GetPublicKey() []byte {
85
- if m != nil {
86
- return m.PublicKey
87
- }
88
- return nil
89
-}
90
-
91
-func (m *Handshake3) GetListenAddrs() [][]byte {
92
- if m != nil {
93
- return m.ListenAddrs
94
- }
95
- return nil
96
-}
97
-
98
-func (m *Handshake3) GetProtocols() []string {
99
- if m != nil {
100
- return m.Protocols
101
- }
102
- return nil
103
-}
104
-
105
-func (m *Handshake3) GetObservedAddr() []byte {
106
- if m != nil {
107
- return m.ObservedAddr
108
- }
109
- return nil
110
-}
111
-
112
-func init() {
113
-}
p2p/net/handshake/pb/handshake.proto
deleted
-38
@@ -1,38 +0,0 @@
1
-package handshake.pb;
2
-
3
-//import "github.com/jbenet/go-ipfs/net/mux/mux.proto";
4
-
5
-// Handshake1 is delivered _before_ the secure channel is initialized
6
-message Handshake1 {
7
- // protocolVersion determines compatibility between peers
8
- optional string protocolVersion = 1; // semver
9
-
10
- // agentVersion is like a UserAgent string in browsers, or client version in bittorrent
11
- // includes the client name and client. e.g. "go-ipfs/0.1.0"
12
- optional string agentVersion = 2; // semver
13
-
14
- // we'll have more fields here later.
15
-}
16
-
17
-// Handshake3 is delivered _after_ the secure channel is initialized
18
-message Handshake3 {
19
-
20
- // can include all the values in handshake1, for protocol version, etc.
21
- optional Handshake1 h1 = 5;
22
-
23
- // publicKey is this node's public key (which also gives its node.ID)
24
- // - may not need to be sent, as secure channel implies it has been sent.
25
- // - then again, if we change / disable secure channel, may still want it.
26
- optional bytes publicKey = 1;
27
-
28
- // listenAddrs are the multiaddrs the sender node listens for open connections on
29
- repeated bytes listenAddrs = 2;
30
-
31
- // protocols are the services this node is running
32
- repeated string protocols = 3;
33
-
34
- // oservedAddr is the multiaddr of the remote endpoint that the sender node perceives
35
- // this is useful information to convey to the other side, as it helps the remote endpoint
36
- // determine whether its connection to the local peer goes through NAT.
37
- optional bytes observedAddr = 4;
38
-}
p2p/net/interface.go
+18
-36
@@ -4,7 +4,6 @@ import (
4
"io"
5
6
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
7
- // swarm "github.com/jbenet/go-ipfs/p2p/net/swarm2"
7
peer "github.com/jbenet/go-ipfs/p2p/peer"
8
9
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@@ -12,20 +11,6 @@ import (
11
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12
)
13
15
-// ProtocolID is an identifier used to write protocol headers in streams.
16
-type ProtocolID string
17
-
18
-// These are the ProtocolIDs of the protocols running. It is useful
19
-// to keep them in one place.
20
-const (
21
- ProtocolTesting ProtocolID = "/ipfs/testing"
22
- ProtocolBitswap ProtocolID = "/ipfs/bitswap"
23
- ProtocolDHT ProtocolID = "/ipfs/dht"
24
- ProtocolIdentify ProtocolID = "/ipfs/id"
25
- ProtocolDiag ProtocolID = "/ipfs/diagnostics"
26
- ProtocolRelay ProtocolID = "/ipfs/relay"
27
-)
28
-
14
// MessageSizeMax is a soft (recommended) maximum for network messages.
15
// One can write more, as the interface is a stream. But it is useful
16
// to bunch it up into multiple read/writes when the whole message is
@@ -45,12 +30,10 @@ type Stream interface {
30
Conn() Conn
31
}
32
48
-// StreamHandler is the function protocols who wish to listen to
49
-// incoming streams must implement.
33
+// StreamHandler is the type of function used to listen for
34
+// streams opened by the remote side.
35
type StreamHandler func(Stream)
36
52
-type StreamHandlerMap map[ProtocolID]StreamHandler
53
-
37
// Conn is a connection to a remote peer. It multiplexes streams.
38
// Usually there is no need to use a Conn directly, but it may
39
// be useful to get information about the peer on the other side:
@@ -58,11 +41,15 @@ type StreamHandlerMap map[ProtocolID]StreamHandler
41
type Conn interface {
42
conn.PeerConn
43
61
- // NewStreamWithProtocol constructs a new Stream over this conn.
62
- NewStreamWithProtocol(pr ProtocolID) (Stream, error)
44
+ // NewStream constructs a new Stream over this conn.
45
+ NewStream() (Stream, error)
46
}
47
65
-// Network is the interface IPFS uses for connecting to the world.
48
+// ConnHandler is the type of function used to listen for
49
+// connections opened by the remote side.
50
+type ConnHandler func(Conn)
51
+
52
+// Network is the interface used to connect to the outside world.
53
// It dials and listens for connections. it uses a Swarm to pool
54
// connnections (see swarm pkg, and peerstream.Swarm). Connections
55
// are encrypted with a TLS-like protocol.
@@ -70,22 +57,17 @@ type Network interface {
57
Dialer
58
io.Closer
59
73
- // SetHandler sets the protocol handler on the Network's Muxer.
74
- // This operation is threadsafe.
75
- SetHandler(ProtocolID, StreamHandler)
60
+ // SetStreamHandler sets the handler for new streams opened by the
61
+ // remote side. This operation is threadsafe.
62
+ SetStreamHandler(StreamHandler)
63
77
- // Protocols returns the list of protocols this network currently
78
- // has registered handlers for.
79
- Protocols() []ProtocolID
64
+ // SetConnHandler sets the handler for new connections opened by the
65
+ // remote side. This operation is threadsafe.
66
+ SetConnHandler(ConnHandler)
67
68
// NewStream returns a new stream to given peer p.
69
// If there is no connection to p, attempts to create one.
83
- // If ProtocolID is "", writes no header.
84
- NewStream(ProtocolID, peer.ID) (Stream, error)
85
-
86
- // BandwidthTotals returns the total number of bytes passed through
87
- // the network since it was instantiated
88
- BandwidthTotals() (uint64, uint64)
70
+ NewStream(peer.ID) (Stream, error)
71
72
// ListenAddresses returns a list of addresses at which this network listens.
73
ListenAddresses() []ma.Multiaddr
@@ -112,8 +94,8 @@ type Dialer interface {
94
// LocalPeer returns the local peer associated with this network
95
LocalPeer() peer.ID
96
115
- // DialPeer attempts to establish a connection to a given peer
116
- DialPeer(context.Context, peer.ID) error
97
+ // DialPeer establishes a connection to a given peer
98
+ DialPeer(context.Context, peer.ID) (Conn, error)
99
100
// ClosePeer closes the connection to a given peer
101
ClosePeer(peer.ID) error
p2p/net/mock/interface.go
+7
-4
@@ -11,6 +11,7 @@ import (
11
"time"
12
13
ic "github.com/jbenet/go-ipfs/p2p/crypto"
14
+ host "github.com/jbenet/go-ipfs/p2p/host"
15
inet "github.com/jbenet/go-ipfs/p2p/net"
16
peer "github.com/jbenet/go-ipfs/p2p/peer"
17
@@ -20,16 +21,18 @@ import (
21
type Mocknet interface {
22
23
// GenPeer generates a peer and its inet.Network in the Mocknet
23
- GenPeer() (inet.Network, error)
24
+ GenPeer() (host.Host, error)
25
26
// AddPeer adds an existing peer. we need both a privkey and addr.
27
// ID is derived from PrivKey
27
- AddPeer(ic.PrivKey, ma.Multiaddr) (inet.Network, error)
28
+ AddPeer(ic.PrivKey, ma.Multiaddr) (host.Host, error)
29
30
// retrieve things (with randomized iteration order)
31
Peers() []peer.ID
32
Net(peer.ID) inet.Network
33
Nets() []inet.Network
34
+ Host(peer.ID) host.Host
35
+ Hosts() []host.Host
36
Links() LinkMap
37
LinksBetweenPeers(a, b peer.ID) []Link
38
LinksBetweenNets(a, b inet.Network) []Link
@@ -52,8 +55,8 @@ type Mocknet interface {
55
56
// Connections are the usual. Connecting means Dialing.
57
// **to succeed, peers must be linked beforehand**
55
- ConnectPeers(peer.ID, peer.ID) error
56
- ConnectNets(inet.Network, inet.Network) error
58
+ ConnectPeers(peer.ID, peer.ID) (inet.Conn, error)
59
+ ConnectNets(inet.Network, inet.Network) (inet.Conn, error)
60
DisconnectPeers(peer.ID, peer.ID) error
61
DisconnectNets(inet.Network, inet.Network) error
62
}
p2p/net/mock/mock.go
+1
-1
@@ -53,7 +53,7 @@ func FullMeshConnected(ctx context.Context, n int) (Mocknet, error) {
53
nets := m.Nets()
54
for _, n1 := range nets {
55
for _, n2 := range nets {
56
- if err := m.ConnectNets(n1, n2); err != nil {
56
+ if _, err := m.ConnectNets(n1, n2); err != nil {
57
return nil, err
58
}
59
}
p2p/net/mock/mock_conn.go
+1
-6
@@ -6,7 +6,6 @@ import (
6
7
ic "github.com/jbenet/go-ipfs/p2p/crypto"
8
inet "github.com/jbenet/go-ipfs/p2p/net"
9
- mux "github.com/jbenet/go-ipfs/p2p/net/services/mux"
9
peer "github.com/jbenet/go-ipfs/p2p/peer"
10
11
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
@@ -83,14 +82,10 @@ func (c *conn) openStream() *stream {
82
return sl
83
}
84
86
-func (c *conn) NewStreamWithProtocol(pr inet.ProtocolID) (inet.Stream, error) {
85
+func (c *conn) NewStream() (inet.Stream, error) {
86
log.Debugf("Conn.NewStreamWithProtocol: %s --> %s", c.local, c.remote)
87
88
s := c.openStream()
90
- if err := mux.WriteProtocolHeader(pr, s); err != nil {
91
- s.Close()
92
- return nil, err
93
- }
89
return s, nil
90
}
91
p2p/net/mock/mock_net.go
+36
-17
@@ -3,8 +3,11 @@ package mocknet
3
import (
4
"fmt"
5
"sync"
6
+ "time"
7
8
ic "github.com/jbenet/go-ipfs/p2p/crypto"
9
+ host "github.com/jbenet/go-ipfs/p2p/host"
10
+ bhost "github.com/jbenet/go-ipfs/p2p/host/basic"
11
inet "github.com/jbenet/go-ipfs/p2p/net"
12
peer "github.com/jbenet/go-ipfs/p2p/peer"
13
testutil "github.com/jbenet/go-ipfs/util/testutil"
@@ -16,9 +19,8 @@ import (
19
20
// mocknet implements mocknet.Mocknet
21
type mocknet struct {
19
- // must map on peer.ID (instead of peer.ID) because
20
- // each inet.Network has different peerstore
21
- nets map[peer.ID]*peernet
22
+ nets map[peer.ID]*peernet
23
+ hosts map[peer.ID]*bhost.BasicHost
24
25
// links make it possible to connect two peers.
26
// think of links as the physical medium.
@@ -35,33 +37,36 @@ type mocknet struct {
37
func New(ctx context.Context) Mocknet {
38
return &mocknet{
39
nets: map[peer.ID]*peernet{},
40
+ hosts: map[peer.ID]*bhost.BasicHost{},
41
links: map[peer.ID]map[peer.ID]map[*link]struct{}{},
42
cg: ctxgroup.WithContext(ctx),
43
}
44
}
45
43
-func (mn *mocknet) GenPeer() (inet.Network, error) {
44
- sk, _, err := testutil.SeededKeyPair(int64(len(mn.nets)))
46
+func (mn *mocknet) GenPeer() (host.Host, error) {
47
+ sk, _, err := testutil.SeededKeyPair(time.Now().UnixNano())
48
if err != nil {
49
return nil, err
50
}
51
52
a := testutil.RandLocalTCPAddress()
53
51
- n, err := mn.AddPeer(sk, a)
54
+ h, err := mn.AddPeer(sk, a)
55
if err != nil {
56
return nil, err
57
}
58
56
- return n, nil
59
+ return h, nil
60
}
61
59
-func (mn *mocknet) AddPeer(k ic.PrivKey, a ma.Multiaddr) (inet.Network, error) {
62
+func (mn *mocknet) AddPeer(k ic.PrivKey, a ma.Multiaddr) (host.Host, error) {
63
n, err := newPeernet(mn.cg.Context(), mn, k, a)
64
if err != nil {
65
return nil, err
66
}
67
68
+ h := bhost.New(n)
69
+
70
// make sure to add listening address!
71
// this makes debugging things simpler as remembering to register
72
// an address may cause unexpected failure.
@@ -72,8 +77,9 @@ func (mn *mocknet) AddPeer(k ic.PrivKey, a ma.Multiaddr) (inet.Network, error) {
77
78
mn.Lock()
79
mn.nets[n.peer] = n
80
+ mn.hosts[n.peer] = h
81
mn.Unlock()
76
- return n, nil
82
+ return h, nil
83
}
84
85
func (mn *mocknet) Peers() []peer.ID {
@@ -87,16 +93,29 @@ func (mn *mocknet) Peers() []peer.ID {
93
return cp
94
}
95
96
+func (mn *mocknet) Host(pid peer.ID) host.Host {
97
+ mn.RLock()
98
+ host := mn.hosts[pid]
99
+ mn.RUnlock()
100
+ return host
101
+}
102
+
103
func (mn *mocknet) Net(pid peer.ID) inet.Network {
104
+ mn.RLock()
105
+ n := mn.nets[pid]
106
+ mn.RUnlock()
107
+ return n
108
+}
109
+
110
+func (mn *mocknet) Hosts() []host.Host {
111
mn.RLock()
112
defer mn.RUnlock()
113
94
- for _, n := range mn.nets {
95
- if n.peer == pid {
96
- return n
97
- }
114
+ cp := make([]host.Host, 0, len(mn.hosts))
115
+ for _, h := range mn.hosts {
116
+ cp = append(cp, h)
117
}
99
- return nil
118
+ return cp
119
}
120
121
func (mn *mocknet) Nets() []inet.Network {
@@ -269,7 +288,7 @@ func (mn *mocknet) ConnectAll() error {
288
continue
289
}
290
272
- if err := mn.ConnectNets(n1, n2); err != nil {
291
+ if _, err := mn.ConnectNets(n1, n2); err != nil {
292
return err
293
}
294
}
@@ -277,11 +296,11 @@ func (mn *mocknet) ConnectAll() error {
296
return nil
297
}
298
280
-func (mn *mocknet) ConnectPeers(a, b peer.ID) error {
299
+func (mn *mocknet) ConnectPeers(a, b peer.ID) (inet.Conn, error) {
300
return mn.Net(a).DialPeer(mn.cg.Context(), b)
301
}
302
284
-func (mn *mocknet) ConnectNets(a, b inet.Network) error {
303
+func (mn *mocknet) ConnectNets(a, b inet.Network) (inet.Conn, error) {
304
return a.DialPeer(mn.cg.Context(), b.LocalPeer())
305
}
306
p2p/net/mock/mock_peernet.go
+46
-43
@@ -7,9 +7,6 @@ import (
7
8
ic "github.com/jbenet/go-ipfs/p2p/crypto"
9
inet "github.com/jbenet/go-ipfs/p2p/net"
10
- ids "github.com/jbenet/go-ipfs/p2p/net/services/identify"
11
- mux "github.com/jbenet/go-ipfs/p2p/net/services/mux"
12
- relay "github.com/jbenet/go-ipfs/p2p/net/services/relay"
10
peer "github.com/jbenet/go-ipfs/p2p/peer"
11
12
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@@ -30,10 +27,9 @@ type peernet struct {
27
connsByPeer map[peer.ID]map[*conn]struct{}
28
connsByLink map[*link]map[*conn]struct{}
29
33
- // needed to implement inet.Network
34
- mux mux.Mux
35
- ids *ids.IDService
36
- relay *relay.RelayService
30
+ // implement inet.Network
31
+ streamHandler inet.StreamHandler
32
+ connHandler inet.ConnHandler
33
34
cg ctxgroup.ContextGroup
35
sync.RWMutex
@@ -58,7 +54,6 @@ func newPeernet(ctx context.Context, m *mocknet, k ic.PrivKey,
54
mocknet: m,
55
peer: p,
56
ps: ps,
61
- mux: mux.Mux{Handlers: inet.StreamHandlerMap{}},
57
cg: ctxgroup.WithContext(ctx),
58
59
connsByPeer: map[peer.ID]map[*conn]struct{}{},
@@ -66,14 +61,6 @@ func newPeernet(ctx context.Context, m *mocknet, k ic.PrivKey,
61
}
62
63
n.cg.SetTeardown(n.teardown)
69
-
70
- // setup a conn handler that immediately "asks the other side about them"
71
- // this is ProtocolIdentify.
72
- n.ids = ids.NewIDService(n)
73
-
74
- // setup ProtocolRelay to allow traffic relaying.
75
- // Feed things we get for ourselves into the muxer.
76
- n.relay = relay.NewRelayService(n.cg.Context(), n, n.mux.HandleSync)
64
return n, nil
65
}
66
@@ -104,10 +91,6 @@ func (pn *peernet) Close() error {
91
return pn.cg.Close()
92
}
93
107
-func (pn *peernet) Protocols() []inet.ProtocolID {
108
- return pn.mux.Protocols()
109
-}
110
-
94
func (pn *peernet) Peerstore() peer.Peerstore {
95
return pn.ps
96
}
@@ -116,24 +99,41 @@ func (pn *peernet) String() string {
99
return fmt.Sprintf("<mock.peernet %s - %d conns>", pn.peer, len(pn.allConns()))
100
}
101
119
-// handleNewStream is an internal function to trigger the muxer handler
102
+// handleNewStream is an internal function to trigger the client's handler
103
func (pn *peernet) handleNewStream(s inet.Stream) {
121
- go pn.mux.Handle(s)
104
+ pn.RLock()
105
+ handler := pn.streamHandler
106
+ pn.RUnlock()
107
+ if handler != nil {
108
+ go handler(s)
109
+ }
110
+}
111
+
112
+// handleNewConn is an internal function to trigger the client's handler
113
+func (pn *peernet) handleNewConn(c inet.Conn) {
114
+ pn.RLock()
115
+ handler := pn.connHandler
116
+ pn.RUnlock()
117
+ if handler != nil {
118
+ go handler(c)
119
+ }
120
}
121
122
// DialPeer attempts to establish a connection to a given peer.
123
// Respects the context.
126
-func (pn *peernet) DialPeer(ctx context.Context, p peer.ID) error {
124
+func (pn *peernet) DialPeer(ctx context.Context, p peer.ID) (inet.Conn, error) {
125
return pn.connect(p)
126
}
127
130
-func (pn *peernet) connect(p peer.ID) error {
128
+func (pn *peernet) connect(p peer.ID) (*conn, error) {
129
// first, check if we already have live connections
130
pn.RLock()
131
cs, found := pn.connsByPeer[p]
132
pn.RUnlock()
133
if found && len(cs) > 0 {
136
- return nil
134
+ for c := range cs {
135
+ return c, nil
136
+ }
137
}
138
139
log.Debugf("%s (newly) dialing %s", pn.peer, p)
@@ -141,7 +141,7 @@ func (pn *peernet) connect(p peer.ID) error {
141
// ok, must create a new connection. we need a link
142
links := pn.mocknet.LinksBetweenPeers(pn.peer, p)
143
if len(links) < 1 {
144
- return fmt.Errorf("%s cannot connect to %s", pn.peer, p)
144
+ return nil, fmt.Errorf("%s cannot connect to %s", pn.peer, p)
145
}
146
147
// if many links found, how do we select? for now, randomly...
@@ -151,8 +151,8 @@ func (pn *peernet) connect(p peer.ID) error {
151
152
log.Debugf("%s dialing %s openingConn", pn.peer, p)
153
// create a new connection with link
154
- pn.openConn(p, l.(*link))
155
- return nil
154
+ c := pn.openConn(p, l.(*link))
155
+ return c, nil
156
}
157
158
func (pn *peernet) openConn(r peer.ID, l *link) *conn {
@@ -166,16 +166,15 @@ func (pn *peernet) openConn(r peer.ID, l *link) *conn {
166
func (pn *peernet) remoteOpenedConn(c *conn) {
167
log.Debugf("%s accepting connection from %s", pn.LocalPeer(), c.RemotePeer())
168
pn.addConn(c)
169
+ pn.handleNewConn(c)
170
}
171
172
// addConn constructs and adds a connection
173
// to given remote peer over given link
174
func (pn *peernet) addConn(c *conn) {
174
-
175
- // run the Identify protocol/handshake.
176
- pn.ids.IdentifyConn(c)
177
-
175
pn.Lock()
176
+ defer pn.Unlock()
177
+
178
cs, found := pn.connsByPeer[c.RemotePeer()]
179
if !found {
180
cs = map[*conn]struct{}{}
@@ -189,7 +188,6 @@ func (pn *peernet) addConn(c *conn) {
188
pn.connsByLink[c.link] = cs
189
}
190
pn.connsByLink[c.link][c] = struct{}{}
192
- pn.Unlock()
191
}
192
193
// removeConn removes a given conn
@@ -314,15 +312,14 @@ func (pn *peernet) Connectedness(p peer.ID) inet.Connectedness {
312
313
// NewStream returns a new stream to given peer p.
314
// If there is no connection to p, attempts to create one.
317
-// If ProtocolID is "", writes no header.
318
-func (pn *peernet) NewStream(pr inet.ProtocolID, p peer.ID) (inet.Stream, error) {
315
+func (pn *peernet) NewStream(p peer.ID) (inet.Stream, error) {
316
pn.Lock()
320
- defer pn.Unlock()
321
-
317
cs, found := pn.connsByPeer[p]
318
if !found || len(cs) < 1 {
319
+ pn.Unlock()
320
return nil, fmt.Errorf("no connection to peer")
321
}
322
+ pn.Unlock()
323
324
// if many conns are found, how do we select? for now, randomly...
325
// this would be an interesting place to test logic that can measure
@@ -336,15 +333,21 @@ func (pn *peernet) NewStream(pr inet.ProtocolID, p peer.ID) (inet.Stream, error)
333
n--
334
}
335
339
- return c.NewStreamWithProtocol(pr)
336
+ return c.NewStream()
337
}
338
342
-// SetHandler sets the protocol handler on the Network's Muxer.
339
+// SetStreamHandler sets the new stream handler on the Network.
340
// This operation is threadsafe.
344
-func (pn *peernet) SetHandler(p inet.ProtocolID, h inet.StreamHandler) {
345
- pn.mux.SetHandler(p, h)
341
+func (pn *peernet) SetStreamHandler(h inet.StreamHandler) {
342
+ pn.Lock()
343
+ pn.streamHandler = h
344
+ pn.Unlock()
345
}
346
348
-func (pn *peernet) IdentifyProtocol() *ids.IDService {
349
- return pn.ids
347
+// SetConnHandler sets the new conn handler on the Network.
348
+// This operation is threadsafe.
349
+func (pn *peernet) SetConnHandler(h inet.ConnHandler) {
350
+ pn.Lock()
351
+ pn.connHandler = h
352
+ pn.Unlock()
353
}
p2p/net/mock/mock_test.go
+77
-76
@@ -9,6 +9,7 @@ import (
9
10
inet "github.com/jbenet/go-ipfs/p2p/net"
11
peer "github.com/jbenet/go-ipfs/p2p/peer"
12
+ protocol "github.com/jbenet/go-ipfs/p2p/protocol"
13
testutil "github.com/jbenet/go-ipfs/util/testutil"
14
15
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@@ -46,31 +47,44 @@ func TestNetworkSetup(t *testing.T) {
47
a2 := testutil.RandLocalTCPAddress()
48
a3 := testutil.RandLocalTCPAddress()
49
49
- n1, err := mn.AddPeer(sk1, a1)
50
+ h1, err := mn.AddPeer(sk1, a1)
51
if err != nil {
52
t.Fatal(err)
53
}
53
- p1 := n1.LocalPeer()
54
+ p1 := h1.ID()
55
55
- n2, err := mn.AddPeer(sk2, a2)
56
+ h2, err := mn.AddPeer(sk2, a2)
57
if err != nil {
58
t.Fatal(err)
59
}
59
- p2 := n2.LocalPeer()
60
+ p2 := h2.ID()
61
61
- n3, err := mn.AddPeer(sk3, a3)
62
+ h3, err := mn.AddPeer(sk3, a3)
63
if err != nil {
64
t.Fatal(err)
65
}
65
- p3 := n3.LocalPeer()
66
+ p3 := h3.ID()
67
68
// check peers and net
69
+ if mn.Host(p1) != h1 {
70
+ t.Error("host for p1.ID != h1")
71
+ }
72
+ if mn.Host(p2) != h2 {
73
+ t.Error("host for p2.ID != h2")
74
+ }
75
+ if mn.Host(p3) != h3 {
76
+ t.Error("host for p3.ID != h3")
77
+ }
78
+
79
+ n1 := h1.Network()
80
if mn.Net(p1) != n1 {
81
t.Error("net for p1.ID != n1")
82
}
83
+ n2 := h2.Network()
84
if mn.Net(p2) != n2 {
85
t.Error("net for p2.ID != n1")
86
}
87
+ n3 := h3.Network()
88
if mn.Net(p3) != n3 {
89
t.Error("net for p3.ID != n1")
90
}
@@ -177,7 +191,7 @@ func TestNetworkSetup(t *testing.T) {
191
}
192
193
// connect p2->p3
180
- if err := n2.DialPeer(ctx, p3); err != nil {
194
+ if _, err := n2.DialPeer(ctx, p3); err != nil {
195
t.Error(err)
196
}
197
@@ -191,41 +205,41 @@ func TestNetworkSetup(t *testing.T) {
205
// p.NetworkConns(n3)
206
207
// can create a stream 2->3, 3->2,
194
- if _, err := n2.NewStream(inet.ProtocolDiag, p3); err != nil {
208
+ if _, err := n2.NewStream(p3); err != nil {
209
t.Error(err)
210
}
197
- if _, err := n3.NewStream(inet.ProtocolDiag, p2); err != nil {
211
+ if _, err := n3.NewStream(p2); err != nil {
212
t.Error(err)
213
}
214
215
// but not 1->2 nor 2->2 (not linked), nor 1->1 (not connected)
202
- if _, err := n1.NewStream(inet.ProtocolDiag, p2); err == nil {
216
+ if _, err := n1.NewStream(p2); err == nil {
217
t.Error("should not be able to connect")
218
}
205
- if _, err := n2.NewStream(inet.ProtocolDiag, p2); err == nil {
219
+ if _, err := n2.NewStream(p2); err == nil {
220
t.Error("should not be able to connect")
221
}
208
- if _, err := n1.NewStream(inet.ProtocolDiag, p1); err == nil {
222
+ if _, err := n1.NewStream(p1); err == nil {
223
t.Error("should not be able to connect")
224
}
225
226
// connect p1->p1 (should work)
213
- if err := n1.DialPeer(ctx, p1); err != nil {
227
+ if _, err := n1.DialPeer(ctx, p1); err != nil {
228
t.Error("p1 should be able to dial self.", err)
229
}
230
231
// and a stream too
218
- if _, err := n1.NewStream(inet.ProtocolDiag, p1); err != nil {
232
+ if _, err := n1.NewStream(p1); err != nil {
233
t.Error(err)
234
}
235
236
// connect p1->p2
223
- if err := n1.DialPeer(ctx, p2); err == nil {
237
+ if _, err := n1.DialPeer(ctx, p2); err == nil {
238
t.Error("p1 should not be able to dial p2, not connected...")
239
}
240
241
// connect p3->p1
228
- if err := n3.DialPeer(ctx, p1); err == nil {
242
+ if _, err := n3.DialPeer(ctx, p1); err == nil {
243
t.Error("p3 should not be able to dial p1, not connected...")
244
}
245
@@ -243,12 +257,12 @@ func TestNetworkSetup(t *testing.T) {
257
// should now be able to connect
258
259
// connect p1->p2
246
- if err := n1.DialPeer(ctx, p2); err != nil {
260
+ if _, err := n1.DialPeer(ctx, p2); err != nil {
261
t.Error(err)
262
}
263
264
// and a stream should work now too :)
251
- if _, err := n2.NewStream(inet.ProtocolDiag, p3); err != nil {
265
+ if _, err := n2.NewStream(p3); err != nil {
266
t.Error(err)
267
}
268
@@ -262,27 +276,25 @@ func TestStreams(t *testing.T) {
276
}
277
278
handler := func(s inet.Stream) {
265
- go func() {
266
- b := make([]byte, 4)
267
- if _, err := io.ReadFull(s, b); err != nil {
268
- panic(err)
269
- }
270
- if !bytes.Equal(b, []byte("beep")) {
271
- panic("bytes mismatch")
272
- }
273
- if _, err := s.Write([]byte("boop")); err != nil {
274
- panic(err)
275
- }
276
- s.Close()
277
- }()
279
+ b := make([]byte, 4)
280
+ if _, err := io.ReadFull(s, b); err != nil {
281
+ panic(err)
282
+ }
283
+ if !bytes.Equal(b, []byte("beep")) {
284
+ panic("bytes mismatch")
285
+ }
286
+ if _, err := s.Write([]byte("boop")); err != nil {
287
+ panic(err)
288
+ }
289
+ s.Close()
290
}
291
280
- nets := mn.Nets()
281
- for _, n := range nets {
282
- n.SetHandler(inet.ProtocolDHT, handler)
292
+ hosts := mn.Hosts()
293
+ for _, h := range mn.Hosts() {
294
+ h.SetStreamHandler(protocol.TestingID, handler)
295
}
296
285
- s, err := nets[0].NewStream(inet.ProtocolDHT, nets[1].LocalPeer())
297
+ s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID())
298
if err != nil {
299
t.Fatal(err)
300
}
@@ -352,17 +364,10 @@ func TestStreamsStress(t *testing.T) {
364
t.Fatal(err)
365
}
366
355
- protos := []inet.ProtocolID{
356
- inet.ProtocolDHT,
357
- inet.ProtocolBitswap,
358
- inet.ProtocolDiag,
359
- }
360
-
361
- nets := mn.Nets()
362
- for _, n := range nets {
363
- for _, p := range protos {
364
- n.SetHandler(p, makePonger(string(p)))
365
- }
367
+ hosts := mn.Hosts()
368
+ for _, h := range hosts {
369
+ ponger := makePonger(string(protocol.TestingID))
370
+ h.SetStreamHandler(protocol.TestingID, ponger)
371
}
372
373
var wg sync.WaitGroup
@@ -370,18 +375,16 @@ func TestStreamsStress(t *testing.T) {
375
wg.Add(1)
376
go func(i int) {
377
defer wg.Done()
373
- from := rand.Intn(len(nets))
374
- to := rand.Intn(len(nets))
375
- p := rand.Intn(3)
376
- proto := protos[p]
377
- s, err := nets[from].NewStream(protos[p], nets[to].LocalPeer())
378
+ from := rand.Intn(len(hosts))
379
+ to := rand.Intn(len(hosts))
380
+ s, err := hosts[from].NewStream(protocol.TestingID, hosts[to].ID())
381
if err != nil {
379
- log.Debugf("%d (%s) %d (%s) %d (%s)", from, nets[from], to, nets[to], p, protos[p])
382
+ log.Debugf("%d (%s) %d (%s)", from, hosts[from], to, hosts[to])
383
panic(err)
384
}
385
386
log.Infof("%d start pinging", i)
384
- makePinger(string(proto), rand.Intn(100))(s)
387
+ makePinger("pingpong", rand.Intn(100))(s)
388
log.Infof("%d done pinging", i)
389
}(i)
390
}
@@ -401,12 +404,12 @@ func TestAdding(t *testing.T) {
404
}
405
406
a := testutil.RandLocalTCPAddress()
404
- n, err := mn.AddPeer(sk, a)
407
+ h, err := mn.AddPeer(sk, a)
408
if err != nil {
409
t.Fatal(err)
410
}
411
409
- peers = append(peers, n.LocalPeer())
412
+ peers = append(peers, h.ID())
413
}
414
415
p1 := peers[0]
@@ -422,40 +425,38 @@ func TestAdding(t *testing.T) {
425
}
426
427
// set the new stream handler on p2
425
- n2 := mn.Net(p2)
426
- if n2 == nil {
427
- t.Fatalf("no network for %s", p2)
428
+ h2 := mn.Host(p2)
429
+ if h2 == nil {
430
+ t.Fatalf("no host for %s", p2)
431
}
429
- n2.SetHandler(inet.ProtocolBitswap, func(s inet.Stream) {
430
- go func() {
431
- defer s.Close()
432
+ h2.SetStreamHandler(protocol.TestingID, func(s inet.Stream) {
433
+ defer s.Close()
434
433
- b := make([]byte, 4)
434
- if _, err := io.ReadFull(s, b); err != nil {
435
- panic(err)
436
- }
437
- if string(b) != "beep" {
438
- panic("did not beep!")
439
- }
435
+ b := make([]byte, 4)
436
+ if _, err := io.ReadFull(s, b); err != nil {
437
+ panic(err)
438
+ }
439
+ if string(b) != "beep" {
440
+ panic("did not beep!")
441
+ }
442
441
- if _, err := s.Write([]byte("boop")); err != nil {
442
- panic(err)
443
- }
444
- }()
443
+ if _, err := s.Write([]byte("boop")); err != nil {
444
+ panic(err)
445
+ }
446
})
447
448
// connect p1 to p2
448
- if err := mn.ConnectPeers(p1, p2); err != nil {
449
+ if _, err := mn.ConnectPeers(p1, p2); err != nil {
450
t.Fatal(err)
451
}
452
453
// talk to p2
453
- n1 := mn.Net(p1)
454
- if n1 == nil {
454
+ h1 := mn.Host(p1)
455
+ if h1 == nil {
456
t.Fatalf("no network for %s", p1)
457
}
458
458
- s, err := n1.NewStream(inet.ProtocolBitswap, p2)
459
+ s, err := h1.NewStream(protocol.TestingID, p2)
460
if err != nil {
461
t.Fatal(err)
462
}
p2p/net/services/identify/id.go
deleted
-187
@@ -1,187 +0,0 @@
1
-package identify
2
-
3
-import (
4
- "sync"
5
-
6
- ggio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io"
7
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
8
-
9
- inet "github.com/jbenet/go-ipfs/p2p/net"
10
- handshake "github.com/jbenet/go-ipfs/p2p/net/handshake"
11
- pb "github.com/jbenet/go-ipfs/p2p/net/handshake/pb"
12
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
13
-)
14
-
15
-var log = eventlog.Logger("net/identify")
16
-
17
-// ProtocolIdentify is the ProtocolID of the Identify Service.
18
-const ProtocolIdentify inet.ProtocolID = "/ipfs/identify"
19
-
20
-// IDService is a structure that implements ProtocolIdentify.
21
-// It is a trivial service that gives the other peer some
22
-// useful information about the local peer. A sort of hello.
23
-//
24
-// The IDService sends:
25
-// * Our IPFS Protocol Version
26
-// * Our IPFS Agent Version
27
-// * Our public Listen Addresses
28
-type IDService struct {
29
- Network inet.Network
30
-
31
- // connections undergoing identification
32
- // for wait purposes
33
- currid map[inet.Conn]chan struct{}
34
- currmu sync.RWMutex
35
-}
36
-
37
-func NewIDService(n inet.Network) *IDService {
38
- s := &IDService{
39
- Network: n,
40
- currid: make(map[inet.Conn]chan struct{}),
41
- }
42
- n.SetHandler(ProtocolIdentify, s.RequestHandler)
43
- return s
44
-}
45
-
46
-func (ids *IDService) IdentifyConn(c inet.Conn) {
47
- ids.currmu.Lock()
48
- if wait, found := ids.currid[c]; found {
49
- ids.currmu.Unlock()
50
- log.Debugf("IdentifyConn called twice on: %s", c)
51
- <-wait // already identifying it. wait for it.
52
- return
53
- }
54
- ids.currid[c] = make(chan struct{})
55
- ids.currmu.Unlock()
56
-
57
- s, err := c.NewStreamWithProtocol(ProtocolIdentify)
58
- if err != nil {
59
- log.Error("network: unable to open initial stream for %s", ProtocolIdentify)
60
- log.Event(ids.Network.CtxGroup().Context(), "IdentifyOpenFailed", c.RemotePeer())
61
- } else {
62
-
63
- // ok give the response to our handler.
64
- ids.ResponseHandler(s)
65
- }
66
-
67
- ids.currmu.Lock()
68
- ch, found := ids.currid[c]
69
- delete(ids.currid, c)
70
- ids.currmu.Unlock()
71
-
72
- if !found {
73
- log.Errorf("IdentifyConn failed to find channel (programmer error) for %s", c)
74
- return
75
- }
76
-
77
- close(ch) // release everyone waiting.
78
-}
79
-
80
-func (ids *IDService) RequestHandler(s inet.Stream) {
81
- defer s.Close()
82
- c := s.Conn()
83
-
84
- w := ggio.NewDelimitedWriter(s)
85
- mes := pb.Handshake3{}
86
- ids.populateMessage(&mes, s.Conn())
87
- w.WriteMsg(&mes)
88
-
89
- log.Debugf("%s sent message to %s %s", ProtocolIdentify,
90
- c.RemotePeer(), c.RemoteMultiaddr())
91
-}
92
-
93
-func (ids *IDService) ResponseHandler(s inet.Stream) {
94
- defer s.Close()
95
- c := s.Conn()
96
-
97
- r := ggio.NewDelimitedReader(s, 2048)
98
- mes := pb.Handshake3{}
99
- if err := r.ReadMsg(&mes); err != nil {
100
- log.Errorf("%s error receiving message from %s %s", ProtocolIdentify,
101
- c.RemotePeer(), c.RemoteMultiaddr())
102
- return
103
- }
104
- ids.consumeMessage(&mes, c)
105
-
106
- log.Debugf("%s received message from %s %s", ProtocolIdentify,
107
- c.RemotePeer(), c.RemoteMultiaddr())
108
-}
109
-
110
-func (ids *IDService) populateMessage(mes *pb.Handshake3, c inet.Conn) {
111
-
112
- // set protocols this node is currently handling
113
- protos := ids.Network.Protocols()
114
- mes.Protocols = make([]string, len(protos))
115
- for i, p := range protos {
116
- mes.Protocols[i] = string(p)
117
- }
118
-
119
- // observed address so other side is informed of their
120
- // "public" address, at least in relation to us.
121
- mes.ObservedAddr = c.RemoteMultiaddr().Bytes()
122
-
123
- // set listen addrs
124
- laddrs, err := ids.Network.InterfaceListenAddresses()
125
- if err != nil {
126
- log.Error(err)
127
- } else {
128
- mes.ListenAddrs = make([][]byte, len(laddrs))
129
- for i, addr := range laddrs {
130
- mes.ListenAddrs[i] = addr.Bytes()
131
- }
132
- log.Debugf("%s sent listen addrs to %s: %s", c.LocalPeer(), c.RemotePeer(), laddrs)
133
- }
134
-
135
- // set protocol versions
136
- mes.H1 = handshake.NewHandshake1("", "")
137
-}
138
-
139
-func (ids *IDService) consumeMessage(mes *pb.Handshake3, c inet.Conn) {
140
- p := c.RemotePeer()
141
-
142
- // mes.Protocols
143
- // mes.ObservedAddr
144
-
145
- // mes.ListenAddrs
146
- laddrs := mes.GetListenAddrs()
147
- lmaddrs := make([]ma.Multiaddr, 0, len(laddrs))
148
- for _, addr := range laddrs {
149
- maddr, err := ma.NewMultiaddrBytes(addr)
150
- if err != nil {
151
- log.Errorf("%s failed to parse multiaddr from %s %s", ProtocolIdentify, p,
152
- c.RemoteMultiaddr())
153
- continue
154
- }
155
- lmaddrs = append(lmaddrs, maddr)
156
- }
157
-
158
- // update our peerstore with the addresses.
159
- ids.Network.Peerstore().AddAddresses(p, lmaddrs)
160
- log.Debugf("%s received listen addrs for %s: %s", c.LocalPeer(), c.RemotePeer(), lmaddrs)
161
-
162
- // get protocol versions
163
- pv := *mes.H1.ProtocolVersion
164
- av := *mes.H1.AgentVersion
165
- ids.Network.Peerstore().Put(p, "ProtocolVersion", pv)
166
- ids.Network.Peerstore().Put(p, "AgentVersion", av)
167
-}
168
-
169
-// IdentifyWait returns a channel which will be closed once
170
-// "ProtocolIdentify" (handshake3) finishes on given conn.
171
-// This happens async so the connection can start to be used
172
-// even if handshake3 knowledge is not necesary.
173
-// Users **MUST** call IdentifyWait _after_ IdentifyConn
174
-func (ids *IDService) IdentifyWait(c inet.Conn) <-chan struct{} {
175
- ids.currmu.Lock()
176
- ch, found := ids.currid[c]
177
- ids.currmu.Unlock()
178
- if found {
179
- return ch
180
- }
181
-
182
- // if not found, it means we are already done identifying it, or
183
- // haven't even started. either way, return a new channel closed.
184
- ch = make(chan struct{})
185
- close(ch)
186
- return ch
187
-}
p2p/net/services/identify/id_test.go
deleted
-111
@@ -1,111 +0,0 @@
1
-package identify_test
2
-
3
-import (
4
- "testing"
5
- "time"
6
-
7
- inet "github.com/jbenet/go-ipfs/p2p/net"
8
- handshake "github.com/jbenet/go-ipfs/p2p/net/handshake"
9
- netutil "github.com/jbenet/go-ipfs/p2p/net/swarmnet/util"
10
- peer "github.com/jbenet/go-ipfs/p2p/peer"
11
-
12
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
13
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
14
-)
15
-
16
-func subtestIDService(t *testing.T, postDialWait time.Duration) {
17
-
18
- // the generated networks should have the id service wired in.
19
- ctx := context.Background()
20
- n1 := netutil.GenNetwork(t, ctx)
21
- n2 := netutil.GenNetwork(t, ctx)
22
-
23
- n1p := n1.LocalPeer()
24
- n2p := n2.LocalPeer()
25
-
26
- testKnowsAddrs(t, n1, n2p, []ma.Multiaddr{}) // nothing
27
- testKnowsAddrs(t, n2, n1p, []ma.Multiaddr{}) // nothing
28
-
29
- // have n2 tell n1, so we can dial...
30
- netutil.DivulgeAddresses(n2, n1)
31
-
32
- testKnowsAddrs(t, n1, n2p, n2.Peerstore().Addresses(n2p)) // has them
33
- testKnowsAddrs(t, n2, n1p, []ma.Multiaddr{}) // nothing
34
-
35
- if err := n1.DialPeer(ctx, n2p); err != nil {
36
- t.Fatalf("Failed to dial:", err)
37
- }
38
-
39
- // we need to wait here if Dial returns before ID service is finished.
40
- if postDialWait > 0 {
41
- <-time.After(postDialWait)
42
- }
43
-
44
- // the IDService should be opened automatically, by the network.
45
- // what we should see now is that both peers know about each others listen addresses.
46
- testKnowsAddrs(t, n1, n2p, n2.Peerstore().Addresses(n2p)) // has them
47
- testHasProtocolVersions(t, n1, n2p)
48
-
49
- // now, this wait we do have to do. it's the wait for the Listening side
50
- // to be done identifying the connection.
51
- c := n2.ConnsToPeer(n1.LocalPeer())
52
- if len(c) < 1 {
53
- t.Fatal("should have connection by now at least.")
54
- }
55
- <-n2.IdentifyProtocol().IdentifyWait(c[0])
56
-
57
- // and the protocol versions.
58
- testKnowsAddrs(t, n2, n1p, n1.Peerstore().Addresses(n1p)) // has them
59
- testHasProtocolVersions(t, n2, n1p)
60
-}
61
-
62
-func testKnowsAddrs(t *testing.T, n inet.Network, p peer.ID, expected []ma.Multiaddr) {
63
- actual := n.Peerstore().Addresses(p)
64
-
65
- if len(actual) != len(expected) {
66
- t.Error("dont have the same addresses")
67
- }
68
-
69
- have := map[string]struct{}{}
70
- for _, addr := range actual {
71
- have[addr.String()] = struct{}{}
72
- }
73
- for _, addr := range expected {
74
- if _, found := have[addr.String()]; !found {
75
- t.Errorf("%s did not have addr for %s: %s", n.LocalPeer(), p, addr)
76
- // panic("ahhhhhhh")
77
- }
78
- }
79
-}
80
-
81
-func testHasProtocolVersions(t *testing.T, n inet.Network, p peer.ID) {
82
- v, err := n.Peerstore().Get(p, "ProtocolVersion")
83
- if v == nil {
84
- t.Error("no protocol version")
85
- return
86
- }
87
- if v.(string) != handshake.IpfsVersion.String() {
88
- t.Error("protocol mismatch", err)
89
- }
90
- v, err = n.Peerstore().Get(p, "AgentVersion")
91
- if v.(string) != handshake.ClientVersion {
92
- t.Error("agent version mismatch", err)
93
- }
94
-}
95
-
96
-// TestIDServiceWait gives the ID service 100ms to finish after dialing
97
-// this is becasue it used to be concurrent. Now, Dial wait till the
98
-// id service is done.
99
-func TestIDServiceWait(t *testing.T) {
100
- N := 3
101
- for i := 0; i < N; i++ {
102
- subtestIDService(t, 100*time.Millisecond)
103
- }
104
-}
105
-
106
-func TestIDServiceNoWait(t *testing.T) {
107
- N := 3
108
- for i := 0; i < N; i++ {
109
- subtestIDService(t, 0)
110
- }
111
-}
p2p/net/services/mux/mux.go
deleted
-156
@@ -1,156 +0,0 @@
1
-package mux
2
-
3
-import (
4
- "fmt"
5
- "io"
6
- "sync"
7
-
8
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
9
-
10
- inet "github.com/jbenet/go-ipfs/p2p/net"
11
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
12
- lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
13
-)
14
-
15
-var log = eventlog.Logger("net/mux")
16
-
17
-// Mux provides simple stream multixplexing.
18
-// It helps you precisely when:
19
-// * You have many streams
20
-// * You have function handlers
21
-//
22
-// It contains the handlers for each protocol accepted.
23
-// It dispatches handlers for streams opened by remote peers.
24
-//
25
-// We use a totally ad-hoc encoding:
26
-// <1 byte length in bytes><string name>
27
-// So "bitswap" is 0x0762697473776170
28
-//
29
-// NOTE: only the dialer specifies this muxing line.
30
-// This is because we're using Streams :)
31
-//
32
-// WARNING: this datastructure IS NOT threadsafe.
33
-// do not modify it once the network is using it.
34
-type Mux struct {
35
- Default inet.StreamHandler // handles unknown protocols.
36
- Handlers inet.StreamHandlerMap
37
-
38
- sync.RWMutex
39
-}
40
-
41
-// Protocols returns the list of protocols this muxer has handlers for
42
-func (m *Mux) Protocols() []inet.ProtocolID {
43
- m.RLock()
44
- l := make([]inet.ProtocolID, 0, len(m.Handlers))
45
- for p := range m.Handlers {
46
- l = append(l, p)
47
- }
48
- m.RUnlock()
49
- return l
50
-}
51
-
52
-// ReadProtocolHeader reads the stream and returns the next Handler function
53
-// according to the muxer encoding.
54
-func (m *Mux) ReadProtocolHeader(s io.Reader) (string, inet.StreamHandler, error) {
55
- // log.Error("ReadProtocolHeader")
56
- name, err := ReadLengthPrefix(s)
57
- if err != nil {
58
- return "", nil, err
59
- }
60
-
61
- // log.Debug("ReadProtocolHeader got:", name)
62
- m.RLock()
63
- h, found := m.Handlers[inet.ProtocolID(name)]
64
- m.RUnlock()
65
-
66
- switch {
67
- case !found && m.Default != nil:
68
- return name, m.Default, nil
69
- case !found && m.Default == nil:
70
- return name, nil, fmt.Errorf("%s no handler with name: %s (%d)", m, name, len(name))
71
- default:
72
- return name, h, nil
73
- }
74
-}
75
-
76
-// String returns the muxer's printing representation
77
-func (m *Mux) String() string {
78
- m.RLock()
79
- defer m.RUnlock()
80
- return fmt.Sprintf("<Muxer %p %d>", m, len(m.Handlers))
81
-}
82
-
83
-// SetHandler sets the protocol handler on the Network's Muxer.
84
-// This operation is threadsafe.
85
-func (m *Mux) SetHandler(p inet.ProtocolID, h inet.StreamHandler) {
86
- log.Debugf("%s setting handler for protocol: %s (%d)", m, p, len(p))
87
- m.Lock()
88
- m.Handlers[p] = h
89
- m.Unlock()
90
-}
91
-
92
-// Handle reads the next name off the Stream, and calls a handler function
93
-// This is done in its own goroutine, to avoid blocking the caller.
94
-func (m *Mux) Handle(s inet.Stream) {
95
- go m.HandleSync(s)
96
-}
97
-
98
-// HandleSync reads the next name off the Stream, and calls a handler function
99
-// This is done synchronously. The handler function will return before
100
-// HandleSync returns.
101
-func (m *Mux) HandleSync(s inet.Stream) {
102
- ctx := context.Background()
103
-
104
- name, handler, err := m.ReadProtocolHeader(s)
105
- if err != nil {
106
- err = fmt.Errorf("protocol mux error: %s", err)
107
- log.Error(err)
108
- log.Event(ctx, "muxError", lgbl.Error(err))
109
- return
110
- }
111
-
112
- log.Infof("muxer handle protocol: %s", name)
113
- log.Event(ctx, "muxHandle", eventlog.Metadata{"protocol": name})
114
- handler(s)
115
-}
116
-
117
-// ReadLengthPrefix reads the name from Reader with a length-byte-prefix.
118
-func ReadLengthPrefix(r io.Reader) (string, error) {
119
- // c-string identifier
120
- // the first byte is our length
121
- l := make([]byte, 1)
122
- if _, err := io.ReadFull(r, l); err != nil {
123
- return "", err
124
- }
125
- length := int(l[0])
126
-
127
- // the next are our identifier
128
- name := make([]byte, length)
129
- if _, err := io.ReadFull(r, name); err != nil {
130
- return "", err
131
- }
132
-
133
- return string(name), nil
134
-}
135
-
136
-// WriteLengthPrefix writes the name into Writer with a length-byte-prefix.
137
-func WriteLengthPrefix(w io.Writer, name string) error {
138
- // log.Error("WriteLengthPrefix", name)
139
- s := make([]byte, len(name)+1)
140
- s[0] = byte(len(name))
141
- copy(s[1:], []byte(name))
142
-
143
- _, err := w.Write(s)
144
- return err
145
-}
146
-
147
-// WriteProtocolHeader defines how a protocol is written into the header of
148
-// a stream. This is so the muxer can multiplex between services.
149
-func WriteProtocolHeader(pr inet.ProtocolID, s inet.Stream) error {
150
- if pr != "" { // only write proper protocol headers
151
- if err := WriteLengthPrefix(s, string(pr)); err != nil {
152
- return err
153
- }
154
- }
155
- return nil
156
-}
p2p/net/services/mux/mux_test.go
deleted
-65
@@ -1,65 +0,0 @@
1
-package mux
2
-
3
-import (
4
- "bytes"
5
- "testing"
6
-
7
- inet "github.com/jbenet/go-ipfs/p2p/net"
8
-)
9
-
10
-var testCases = map[string]string{
11
- "bitswap": "\u0007bitswap",
12
- "dht": "\u0003dht",
13
- "ipfs": "\u0004ipfs",
14
- "ipfsdksnafkasnfkdajfkdajfdsjadosiaaodjasofdias": ".ipfsdksnafkasnfkdajfkdajfdsjadosiaaodjasofdias",
15
-}
16
-
17
-func TestWrite(t *testing.T) {
18
- for k, v := range testCases {
19
- var buf bytes.Buffer
20
- WriteLengthPrefix(&buf, k)
21
-
22
- v2 := buf.Bytes()
23
- if !bytes.Equal(v2, []byte(v)) {
24
- t.Errorf("failed: %s - %v != %v", k, []byte(v), v2)
25
- }
26
- }
27
-}
28
-
29
-func TestHandler(t *testing.T) {
30
-
31
- outs := make(chan string, 10)
32
-
33
- h := func(n string) func(s inet.Stream) {
34
- return func(s inet.Stream) {
35
- outs <- n
36
- }
37
- }
38
-
39
- m := Mux{Handlers: inet.StreamHandlerMap{}}
40
- m.Default = h("default")
41
- m.Handlers["dht"] = h("bitswap")
42
- // m.Handlers["ipfs"] = h("bitswap") // default!
43
- m.Handlers["bitswap"] = h("bitswap")
44
- m.Handlers["ipfsdksnafkasnfkdajfkdajfdsjadosiaaodjasofdias"] = h("bitswap")
45
-
46
- for k, v := range testCases {
47
- var buf bytes.Buffer
48
- if _, err := buf.Write([]byte(v)); err != nil {
49
- t.Error(err)
50
- continue
51
- }
52
-
53
- name, _, err := m.ReadProtocolHeader(&buf)
54
- if err != nil {
55
- t.Error(err)
56
- continue
57
- }
58
-
59
- if name != k {
60
- t.Errorf("name mismatch: %s != %s", k, name)
61
- continue
62
- }
63
- }
64
-
65
-}
p2p/net/services/relay/relay.go
deleted
-159
@@ -1,159 +0,0 @@
1
-package relay
2
-
3
-import (
4
- "fmt"
5
- "io"
6
-
7
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
9
- mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
10
-
11
- inet "github.com/jbenet/go-ipfs/p2p/net"
12
- peer "github.com/jbenet/go-ipfs/p2p/peer"
13
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
14
-)
15
-
16
-var log = eventlog.Logger("relay")
17
-
18
-// ProtocolRelay is the ProtocolID of the Relay Service.
19
-const ProtocolRelay inet.ProtocolID = "/ipfs/relay"
20
-
21
-// Relay is a structure that implements ProtocolRelay.
22
-// It is a simple relay service which forwards traffic
23
-// between two directly connected peers.
24
-//
25
-// the protocol is very simple:
26
-//
27
-// /ipfs/relay\n
28
-// <multihash src id>
29
-// <multihash dst id>
30
-// <data stream>
31
-//
32
-type RelayService struct {
33
- Network inet.Network
34
- handler inet.StreamHandler // for streams sent to us locally.
35
-
36
- cg ctxgroup.ContextGroup
37
-}
38
-
39
-func NewRelayService(ctx context.Context, n inet.Network, sh inet.StreamHandler) *RelayService {
40
- s := &RelayService{
41
- Network: n,
42
- handler: sh,
43
- cg: ctxgroup.WithContext(ctx),
44
- }
45
- n.SetHandler(inet.ProtocolRelay, s.requestHandler)
46
- return s
47
-}
48
-
49
-// requestHandler is the function called by clients
50
-func (rs *RelayService) requestHandler(s inet.Stream) {
51
- if err := rs.handleStream(s); err != nil {
52
- log.Error("RelayService error:", err)
53
- }
54
-}
55
-
56
-// handleStream is our own handler, which returns an error for simplicity.
57
-func (rs *RelayService) handleStream(s inet.Stream) error {
58
- defer s.Close()
59
-
60
- // read the header (src and dst peer.IDs)
61
- src, dst, err := ReadHeader(s)
62
- if err != nil {
63
- return fmt.Errorf("stream with bad header: %s", err)
64
- }
65
-
66
- local := rs.Network.LocalPeer()
67
-
68
- switch {
69
- case src == local:
70
- return fmt.Errorf("relaying from self")
71
- case dst == local: // it's for us! yaaay.
72
- log.Debugf("%s consuming stream from %s", rs.Network.LocalPeer(), src)
73
- return rs.consumeStream(s)
74
- default: // src and dst are not local. relay it.
75
- log.Debugf("%s relaying stream %s <--> %s", rs.Network.LocalPeer(), src, dst)
76
- return rs.pipeStream(src, dst, s)
77
- }
78
-}
79
-
80
-// consumeStream connects streams directed to the local peer
81
-// to our handler, with the header now stripped (read).
82
-func (rs *RelayService) consumeStream(s inet.Stream) error {
83
- rs.handler(s) // boom.
84
- return nil
85
-}
86
-
87
-// pipeStream relays over a stream to a remote peer. It's like `cat`
88
-func (rs *RelayService) pipeStream(src, dst peer.ID, s inet.Stream) error {
89
- s2, err := rs.openStreamToPeer(dst)
90
- if err != nil {
91
- return fmt.Errorf("failed to open stream to peer: %s -- %s", dst, err)
92
- }
93
-
94
- if err := WriteHeader(s2, src, dst); err != nil {
95
- return err
96
- }
97
-
98
- // connect the series of tubes.
99
- done := make(chan retio, 2)
100
- go func() {
101
- n, err := io.Copy(s2, s)
102
- done <- retio{n, err}
103
- }()
104
- go func() {
105
- n, err := io.Copy(s, s2)
106
- done <- retio{n, err}
107
- }()
108
-
109
- r1 := <-done
110
- r2 := <-done
111
- log.Infof("relayed %d/%d bytes between %s and %s", r1.n, r2.n, src, dst)
112
-
113
- if r1.err != nil {
114
- return r1.err
115
- }
116
- return r2.err
117
-}
118
-
119
-// openStreamToPeer opens a pipe to a remote endpoint
120
-// for now, can only open streams to directly connected peers.
121
-// maybe we can do some routing later on.
122
-func (rs *RelayService) openStreamToPeer(p peer.ID) (inet.Stream, error) {
123
- return rs.Network.NewStream(ProtocolRelay, p)
124
-}
125
-
126
-func ReadHeader(r io.Reader) (src, dst peer.ID, err error) {
127
-
128
- mhr := mh.NewReader(r)
129
-
130
- s, err := mhr.ReadMultihash()
131
- if err != nil {
132
- return "", "", err
133
- }
134
-
135
- d, err := mhr.ReadMultihash()
136
- if err != nil {
137
- return "", "", err
138
- }
139
-
140
- return peer.ID(s), peer.ID(d), nil
141
-}
142
-
143
-func WriteHeader(w io.Writer, src, dst peer.ID) error {
144
- // write header to w.
145
- mhw := mh.NewWriter(w)
146
- if err := mhw.WriteMultihash(mh.Multihash(src)); err != nil {
147
- return fmt.Errorf("failed to write relay header: %s -- %s", dst, err)
148
- }
149
- if err := mhw.WriteMultihash(mh.Multihash(dst)); err != nil {
150
- return fmt.Errorf("failed to write relay header: %s -- %s", dst, err)
151
- }
152
-
153
- return nil
154
-}
155
-
156
-type retio struct {
157
- n int64
158
- err error
159
-}
p2p/net/services/relay/relay_test.go
deleted
-309
@@ -1,309 +0,0 @@
1
-package relay_test
2
-
3
-import (
4
- "io"
5
- "testing"
6
-
7
- inet "github.com/jbenet/go-ipfs/p2p/net"
8
- mux "github.com/jbenet/go-ipfs/p2p/net/services/mux"
9
- relay "github.com/jbenet/go-ipfs/p2p/net/services/relay"
10
- netutil "github.com/jbenet/go-ipfs/p2p/net/swarmnet/util"
11
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
12
-
13
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
14
-)
15
-
16
-var log = eventlog.Logger("relay_test")
17
-
18
-func TestRelaySimple(t *testing.T) {
19
-
20
- ctx := context.Background()
21
-
22
- // these networks have the relay service wired in already.
23
- n1 := netutil.GenNetwork(t, ctx)
24
- n2 := netutil.GenNetwork(t, ctx)
25
- n3 := netutil.GenNetwork(t, ctx)
26
-
27
- n1p := n1.LocalPeer()
28
- n2p := n2.LocalPeer()
29
- n3p := n3.LocalPeer()
30
-
31
- netutil.DivulgeAddresses(n2, n1)
32
- netutil.DivulgeAddresses(n2, n3)
33
-
34
- if err := n1.DialPeer(ctx, n2p); err != nil {
35
- t.Fatalf("Failed to dial:", err)
36
- }
37
- if err := n3.DialPeer(ctx, n2p); err != nil {
38
- t.Fatalf("Failed to dial:", err)
39
- }
40
-
41
- // setup handler on n3 to copy everything over to the pipe.
42
- piper, pipew := io.Pipe()
43
- n3.SetHandler(inet.ProtocolTesting, func(s inet.Stream) {
44
- log.Debug("relay stream opened to n3!")
45
- log.Debug("piping and echoing everything")
46
- w := io.MultiWriter(s, pipew)
47
- io.Copy(w, s)
48
- log.Debug("closing stream")
49
- s.Close()
50
- })
51
-
52
- // ok, now we can try to relay n1--->n2--->n3.
53
- log.Debug("open relay stream")
54
- s, err := n1.NewStream(relay.ProtocolRelay, n2p)
55
- if err != nil {
56
- t.Fatal(err)
57
- }
58
-
59
- // ok first thing we write the relay header n1->n3
60
- log.Debug("write relay header")
61
- if err := relay.WriteHeader(s, n1p, n3p); err != nil {
62
- t.Fatal(err)
63
- }
64
-
65
- // ok now the header's there, we can write the next protocol header.
66
- log.Debug("write testing header")
67
- if err := mux.WriteProtocolHeader(inet.ProtocolTesting, s); err != nil {
68
- t.Fatal(err)
69
- }
70
-
71
- // okay, now we should be able to write text, and read it out.
72
- buf1 := []byte("abcdefghij")
73
- buf2 := make([]byte, 10)
74
- buf3 := make([]byte, 10)
75
- log.Debug("write in some text.")
76
- if _, err := s.Write(buf1); err != nil {
77
- t.Fatal(err)
78
- }
79
-
80
- // read it out from the pipe.
81
- log.Debug("read it out from the pipe.")
82
- if _, err := io.ReadFull(piper, buf2); err != nil {
83
- t.Fatal(err)
84
- }
85
- if string(buf1) != string(buf2) {
86
- t.Fatal("should've gotten that text out of the pipe")
87
- }
88
-
89
- // read it out from the stream (echoed)
90
- log.Debug("read it out from the stream (echoed).")
91
- if _, err := io.ReadFull(s, buf3); err != nil {
92
- t.Fatal(err)
93
- }
94
- if string(buf1) != string(buf3) {
95
- t.Fatal("should've gotten that text out of the stream")
96
- }
97
-
98
- // sweet. relay works.
99
- log.Debug("sweet, relay works.")
100
- s.Close()
101
-}
102
-
103
-func TestRelayAcrossFour(t *testing.T) {
104
-
105
- ctx := context.Background()
106
-
107
- // these networks have the relay service wired in already.
108
- n1 := netutil.GenNetwork(t, ctx)
109
- n2 := netutil.GenNetwork(t, ctx)
110
- n3 := netutil.GenNetwork(t, ctx)
111
- n4 := netutil.GenNetwork(t, ctx)
112
- n5 := netutil.GenNetwork(t, ctx)
113
-
114
- n1p := n1.LocalPeer()
115
- n2p := n2.LocalPeer()
116
- n3p := n3.LocalPeer()
117
- n4p := n4.LocalPeer()
118
- n5p := n5.LocalPeer()
119
-
120
- netutil.DivulgeAddresses(n2, n1)
121
- netutil.DivulgeAddresses(n2, n3)
122
- netutil.DivulgeAddresses(n4, n3)
123
- netutil.DivulgeAddresses(n4, n5)
124
-
125
- if err := n1.DialPeer(ctx, n2p); err != nil {
126
- t.Fatalf("Failed to dial:", err)
127
- }
128
- if err := n3.DialPeer(ctx, n2p); err != nil {
129
- t.Fatalf("Failed to dial:", err)
130
- }
131
- if err := n3.DialPeer(ctx, n4p); err != nil {
132
- t.Fatalf("Failed to dial:", err)
133
- }
134
- if err := n5.DialPeer(ctx, n4p); err != nil {
135
- t.Fatalf("Failed to dial:", err)
136
- }
137
-
138
- // setup handler on n5 to copy everything over to the pipe.
139
- piper, pipew := io.Pipe()
140
- n5.SetHandler(inet.ProtocolTesting, func(s inet.Stream) {
141
- log.Debug("relay stream opened to n5!")
142
- log.Debug("piping and echoing everything")
143
- w := io.MultiWriter(s, pipew)
144
- io.Copy(w, s)
145
- log.Debug("closing stream")
146
- s.Close()
147
- })
148
-
149
- // ok, now we can try to relay n1--->n2--->n3--->n4--->n5
150
- log.Debug("open relay stream")
151
- s, err := n1.NewStream(relay.ProtocolRelay, n2p)
152
- if err != nil {
153
- t.Fatal(err)
154
- }
155
-
156
- log.Debugf("write relay header n1->n3 (%s -> %s)", n1p, n3p)
157
- if err := relay.WriteHeader(s, n1p, n3p); err != nil {
158
- t.Fatal(err)
159
- }
160
-
161
- log.Debugf("write relay header n1->n4 (%s -> %s)", n1p, n4p)
162
- if err := mux.WriteProtocolHeader(relay.ProtocolRelay, s); err != nil {
163
- t.Fatal(err)
164
- }
165
- if err := relay.WriteHeader(s, n1p, n4p); err != nil {
166
- t.Fatal(err)
167
- }
168
-
169
- log.Debugf("write relay header n1->n5 (%s -> %s)", n1p, n5p)
170
- if err := mux.WriteProtocolHeader(relay.ProtocolRelay, s); err != nil {
171
- t.Fatal(err)
172
- }
173
- if err := relay.WriteHeader(s, n1p, n5p); err != nil {
174
- t.Fatal(err)
175
- }
176
-
177
- // ok now the header's there, we can write the next protocol header.
178
- log.Debug("write testing header")
179
- if err := mux.WriteProtocolHeader(inet.ProtocolTesting, s); err != nil {
180
- t.Fatal(err)
181
- }
182
-
183
- // okay, now we should be able to write text, and read it out.
184
- buf1 := []byte("abcdefghij")
185
- buf2 := make([]byte, 10)
186
- buf3 := make([]byte, 10)
187
- log.Debug("write in some text.")
188
- if _, err := s.Write(buf1); err != nil {
189
- t.Fatal(err)
190
- }
191
-
192
- // read it out from the pipe.
193
- log.Debug("read it out from the pipe.")
194
- if _, err := io.ReadFull(piper, buf2); err != nil {
195
- t.Fatal(err)
196
- }
197
- if string(buf1) != string(buf2) {
198
- t.Fatal("should've gotten that text out of the pipe")
199
- }
200
-
201
- // read it out from the stream (echoed)
202
- log.Debug("read it out from the stream (echoed).")
203
- if _, err := io.ReadFull(s, buf3); err != nil {
204
- t.Fatal(err)
205
- }
206
- if string(buf1) != string(buf3) {
207
- t.Fatal("should've gotten that text out of the stream")
208
- }
209
-
210
- // sweet. relay works.
211
- log.Debug("sweet, relaying across 4 works.")
212
- s.Close()
213
-}
214
-
215
-func TestRelayStress(t *testing.T) {
216
- buflen := 1 << 18
217
- iterations := 10
218
-
219
- ctx := context.Background()
220
-
221
- // these networks have the relay service wired in already.
222
- n1 := netutil.GenNetwork(t, ctx)
223
- n2 := netutil.GenNetwork(t, ctx)
224
- n3 := netutil.GenNetwork(t, ctx)
225
-
226
- n1p := n1.LocalPeer()
227
- n2p := n2.LocalPeer()
228
- n3p := n3.LocalPeer()
229
-
230
- netutil.DivulgeAddresses(n2, n1)
231
- netutil.DivulgeAddresses(n2, n3)
232
-
233
- if err := n1.DialPeer(ctx, n2p); err != nil {
234
- t.Fatalf("Failed to dial:", err)
235
- }
236
- if err := n3.DialPeer(ctx, n2p); err != nil {
237
- t.Fatalf("Failed to dial:", err)
238
- }
239
-
240
- // setup handler on n3 to copy everything over to the pipe.
241
- piper, pipew := io.Pipe()
242
- n3.SetHandler(inet.ProtocolTesting, func(s inet.Stream) {
243
- log.Debug("relay stream opened to n3!")
244
- log.Debug("piping and echoing everything")
245
- w := io.MultiWriter(s, pipew)
246
- io.Copy(w, s)
247
- log.Debug("closing stream")
248
- s.Close()
249
- })
250
-
251
- // ok, now we can try to relay n1--->n2--->n3.
252
- log.Debug("open relay stream")
253
- s, err := n1.NewStream(relay.ProtocolRelay, n2p)
254
- if err != nil {
255
- t.Fatal(err)
256
- }
257
-
258
- // ok first thing we write the relay header n1->n3
259
- log.Debug("write relay header")
260
- if err := relay.WriteHeader(s, n1p, n3p); err != nil {
261
- t.Fatal(err)
262
- }
263
-
264
- // ok now the header's there, we can write the next protocol header.
265
- log.Debug("write testing header")
266
- if err := mux.WriteProtocolHeader(inet.ProtocolTesting, s); err != nil {
267
- t.Fatal(err)
268
- }
269
-
270
- // okay, now write lots of text and read it back out from both
271
- // the pipe and the stream.
272
- buf1 := make([]byte, buflen)
273
- buf2 := make([]byte, len(buf1))
274
- buf3 := make([]byte, len(buf1))
275
-
276
- fillbuf := func(buf []byte, b byte) {
277
- for i := range buf {
278
- buf[i] = b
279
- }
280
- }
281
-
282
- for i := 0; i < iterations; i++ {
283
- fillbuf(buf1, byte(int('a')+i))
284
- log.Debugf("writing %d bytes (%d/%d)", len(buf1), i, iterations)
285
- if _, err := s.Write(buf1); err != nil {
286
- t.Fatal(err)
287
- }
288
-
289
- log.Debug("read it out from the pipe.")
290
- if _, err := io.ReadFull(piper, buf2); err != nil {
291
- t.Fatal(err)
292
- }
293
- if string(buf1) != string(buf2) {
294
- t.Fatal("should've gotten that text out of the pipe")
295
- }
296
-
297
- // read it out from the stream (echoed)
298
- log.Debug("read it out from the stream (echoed).")
299
- if _, err := io.ReadFull(s, buf3); err != nil {
300
- t.Fatal(err)
301
- }
302
- if string(buf1) != string(buf3) {
303
- t.Fatal("should've gotten that text out of the stream")
304
- }
305
- }
306
-
307
- log.Debug("sweet, relay works under stress.")
308
- s.Close()
309
-}
p2p/net/swarm/swarm.go
+2
-1
@@ -3,6 +3,7 @@
3
package swarm
4
5
import (
6
+ inet "github.com/jbenet/go-ipfs/p2p/net"
7
peer "github.com/jbenet/go-ipfs/p2p/peer"
8
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
9
@@ -92,7 +93,7 @@ func (s *Swarm) SetConnHandler(handler ConnHandler) {
93
94
// SetStreamHandler assigns the handler for new streams.
95
// See peerstream.
95
-func (s *Swarm) SetStreamHandler(handler StreamHandler) {
96
+func (s *Swarm) SetStreamHandler(handler inet.StreamHandler) {
97
s.swarm.SetStreamHandler(func(s *ps.Stream) {
98
handler(wrapStream(s))
99
})
p2p/net/swarm/swarm_conn.go
+9
-2
@@ -4,6 +4,7 @@ import (
4
"fmt"
5
6
ic "github.com/jbenet/go-ipfs/p2p/crypto"
7
+ inet "github.com/jbenet/go-ipfs/p2p/net"
8
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
9
peer "github.com/jbenet/go-ipfs/p2p/peer"
10
@@ -74,12 +75,18 @@ func (c *Conn) RemotePublicKey() ic.PubKey {
75
return c.RawConn().RemotePublicKey()
76
}
77
77
-// NewStream returns a new Stream from this connection
78
-func (c *Conn) NewStream() (*Stream, error) {
78
+// NewSwarmStream returns a new Stream from this connection
79
+func (c *Conn) NewSwarmStream() (*Stream, error) {
80
s, err := c.StreamConn().NewStream()
81
return wrapStream(s), err
82
}
83
84
+// NewStream returns a new Stream from this connection
85
+func (c *Conn) NewStream() (inet.Stream, error) {
86
+ s, err := c.NewSwarmStream()
87
+ return inet.Stream(s), err
88
+}
89
+
90
func (c *Conn) Close() error {
91
return c.StreamConn().Close()
92
}
p2p/net/swarm/swarm_net.go
renamed
+1
-1
@@ -5,7 +5,7 @@ import (
5
6
peer "github.com/jbenet/go-ipfs/p2p/peer"
7
8
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
+ inet "github.com/jbenet/go-ipfs/p2p/net"
9
10
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11
ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
p2p/net/swarm/swarm_net_test.go
renamed
+4
-4
@@ -8,7 +8,7 @@ import (
8
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
9
10
inet "github.com/jbenet/go-ipfs/p2p/net"
11
- netutil "github.com/jbenet/go-ipfs/p2p/net/swarmnet/util"
11
+ testutil "github.com/jbenet/go-ipfs/p2p/test/util"
12
)
13
14
// TestConnectednessCorrect starts a few networks, connects a few
@@ -19,14 +19,14 @@ func TestConnectednessCorrect(t *testing.T) {
19
20
nets := make([]inet.Network, 4)
21
for i := 0; i < 4; i++ {
22
- nets[i] = netutil.GenNetwork(t, ctx)
22
+ nets[i] = testutil.GenSwarmNetwork(t, ctx)
23
}
24
25
// connect 0-1, 0-2, 0-3, 1-2, 2-3
26
27
dial := func(a, b inet.Network) {
28
- netutil.DivulgeAddresses(b, a)
29
- if err := a.DialPeer(ctx, b.LocalPeer()); err != nil {
28
+ testutil.DivulgeAddresses(b, a)
29
+ if _, err := a.DialPeer(ctx, b.LocalPeer()); err != nil {
30
t.Fatalf("Failed to dial: %s", err)
31
}
32
}
p2p/net/swarm/swarm_stream.go
+9
-6
@@ -1,6 +1,8 @@
1
package swarm
2
3
import (
4
+ inet "github.com/jbenet/go-ipfs/p2p/net"
5
+
6
ps "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
7
)
8
@@ -8,17 +10,18 @@ import (
10
// our Conn and Swarm (instead of just the ps.Conn and ps.Swarm)
11
type Stream ps.Stream
12
11
-// StreamHandler is called when new streams are opened from remote peers.
12
-// See peerstream.StreamHandler
13
-type StreamHandler func(*Stream)
14
-
13
// Stream returns the underlying peerstream.Stream
14
func (s *Stream) Stream() *ps.Stream {
15
return (*ps.Stream)(s)
16
}
17
20
-// Conn returns the Conn associated with this Stream
21
-func (s *Stream) Conn() *Conn {
18
+// Conn returns the Conn associated with this Stream, as an inet.Conn
19
+func (s *Stream) Conn() inet.Conn {
20
+ return s.SwarmConn()
21
+}
22
+
23
+// SwarmConn returns the Conn associated with this Stream, as a *Conn
24
+func (s *Stream) SwarmConn() *Conn {
25
return (*Conn)(s.Stream().Conn())
26
}
27
p2p/net/swarm/swarm_test.go
+3
-2
@@ -7,6 +7,7 @@ import (
7
"testing"
8
"time"
9
10
+ inet "github.com/jbenet/go-ipfs/p2p/net"
11
peer "github.com/jbenet/go-ipfs/p2p/peer"
12
errors "github.com/jbenet/go-ipfs/util/debugerror"
13
testutil "github.com/jbenet/go-ipfs/util/testutil"
@@ -15,12 +16,12 @@ import (
16
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
17
)
18
18
-func EchoStreamHandler(stream *Stream) {
19
+func EchoStreamHandler(stream inet.Stream) {
20
go func() {
21
defer stream.Close()
22
23
// pull out the ipfs conn
23
- c := stream.Conn().RawConn()
24
+ c := stream.Conn()
25
log.Debugf("%s ponging to %s", c.LocalPeer(), c.RemotePeer())
26
27
buf := make([]byte, 4)
p2p/net/swarmnet/net.go
deleted
-309
@@ -1,309 +0,0 @@
1
-// Package net provides an interface for ipfs to interact with the network through
2
-package net
3
-
4
-import (
5
- "fmt"
6
-
7
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
8
- peer "github.com/jbenet/go-ipfs/p2p/peer"
9
-
10
- inet "github.com/jbenet/go-ipfs/p2p/net"
11
- ids "github.com/jbenet/go-ipfs/p2p/net/services/identify"
12
- mux "github.com/jbenet/go-ipfs/p2p/net/services/mux"
13
- relay "github.com/jbenet/go-ipfs/p2p/net/services/relay"
14
- swarm "github.com/jbenet/go-ipfs/p2p/net/swarm"
15
-
16
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
17
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
18
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
19
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
20
-)
21
-
22
-var log = eventlog.Logger("net/mux")
23
-
24
-type stream swarm.Stream
25
-
26
-func (s *stream) SwarmStream() *swarm.Stream {
27
- return (*swarm.Stream)(s)
28
-}
29
-
30
-// Conn returns the connection this stream is part of.
31
-func (s *stream) Conn() inet.Conn {
32
- c := s.SwarmStream().Conn()
33
- return (*conn_)(c)
34
-}
35
-
36
-// Conn returns the connection this stream is part of.
37
-func (s *stream) Close() error {
38
- return s.SwarmStream().Close()
39
-}
40
-
41
-// Read reads bytes from a stream.
42
-func (s *stream) Read(p []byte) (n int, err error) {
43
- return s.SwarmStream().Read(p)
44
-}
45
-
46
-// Write writes bytes to a stream, flushing for each call.
47
-func (s *stream) Write(p []byte) (n int, err error) {
48
- return s.SwarmStream().Write(p)
49
-}
50
-
51
-type conn_ swarm.Conn
52
-
53
-func (s *conn_) String() string {
54
- return s.SwarmConn().String()
55
-}
56
-
57
-func (c *conn_) SwarmConn() *swarm.Conn {
58
- return (*swarm.Conn)(c)
59
-}
60
-
61
-func (c *conn_) NewStreamWithProtocol(pr inet.ProtocolID) (inet.Stream, error) {
62
- s, err := (*swarm.Conn)(c).NewStream()
63
- if err != nil {
64
- return nil, err
65
- }
66
-
67
- ss := (*stream)(s)
68
-
69
- if err := mux.WriteProtocolHeader(pr, ss); err != nil {
70
- ss.Close()
71
- return nil, err
72
- }
73
-
74
- return ss, nil
75
-}
76
-
77
-func (c *conn_) LocalMultiaddr() ma.Multiaddr {
78
- return c.SwarmConn().LocalMultiaddr()
79
-}
80
-
81
-func (c *conn_) RemoteMultiaddr() ma.Multiaddr {
82
- return c.SwarmConn().RemoteMultiaddr()
83
-}
84
-
85
-func (c *conn_) LocalPeer() peer.ID {
86
- return c.SwarmConn().LocalPeer()
87
-}
88
-
89
-func (c *conn_) RemotePeer() peer.ID {
90
- return c.SwarmConn().RemotePeer()
91
-}
92
-
93
-func (c *conn_) LocalPrivateKey() ic.PrivKey {
94
- return c.SwarmConn().LocalPrivateKey()
95
-}
96
-
97
-func (c *conn_) RemotePublicKey() ic.PubKey {
98
- return c.SwarmConn().RemotePublicKey()
99
-}
100
-
101
-// Network implements the inet.Network interface.
102
-// It uses a swarm to connect to remote hosts.
103
-type Network struct {
104
- local peer.ID // local peer
105
- ps peer.Peerstore
106
-
107
- swarm *swarm.Swarm // peer connection multiplexing
108
- mux mux.Mux // protocol multiplexing
109
- ids *ids.IDService
110
- relay *relay.RelayService
111
-
112
- cg ctxgroup.ContextGroup // for Context closing
113
-}
114
-
115
-// NewNetwork constructs a new network and starts listening on given addresses.
116
-func NewNetwork(ctx context.Context, listen []ma.Multiaddr, local peer.ID,
117
- peers peer.Peerstore) (*Network, error) {
118
-
119
- s, err := swarm.NewSwarm(ctx, listen, local, peers)
120
- if err != nil {
121
- return nil, err
122
- }
123
-
124
- n := &Network{
125
- local: local,
126
- swarm: s,
127
- mux: mux.Mux{Handlers: inet.StreamHandlerMap{}},
128
- cg: ctxgroup.WithContext(ctx),
129
- ps: peers,
130
- }
131
-
132
- n.cg.SetTeardown(n.close)
133
- n.cg.AddChildGroup(s.CtxGroup())
134
-
135
- s.SetStreamHandler(func(s *swarm.Stream) {
136
- n.mux.Handle((*stream)(s))
137
- })
138
-
139
- // setup ProtocolIdentify to immediately "asks the other side about them"
140
- n.ids = ids.NewIDService(n)
141
- s.SetConnHandler(n.newConnHandler)
142
-
143
- // setup ProtocolRelay to allow traffic relaying.
144
- // Feed things we get for ourselves into the muxer.
145
- n.relay = relay.NewRelayService(n.cg.Context(), n, n.mux.HandleSync)
146
- return n, nil
147
-}
148
-
149
-func (n *Network) newConnHandler(c *swarm.Conn) {
150
- cc := (*conn_)(c)
151
- n.ids.IdentifyConn(cc)
152
-}
153
-
154
-// DialPeer attempts to establish a connection to a given peer.
155
-// Respects the context.
156
-func (n *Network) DialPeer(ctx context.Context, p peer.ID) error {
157
- log.Debugf("[%s] network dialing peer [%s]", n.local, p)
158
- sc, err := n.swarm.Dial(ctx, p)
159
- if err != nil {
160
- return err
161
- }
162
-
163
- // identify the connection before returning.
164
- done := make(chan struct{})
165
- go func() {
166
- n.ids.IdentifyConn((*conn_)(sc))
167
- close(done)
168
- }()
169
-
170
- // respect don contexteone
171
- select {
172
- case <-done:
173
- case <-ctx.Done():
174
- return ctx.Err()
175
- }
176
-
177
- log.Debugf("network for %s finished dialing %s", n.local, p)
178
- return nil
179
-}
180
-
181
-// Protocols returns the ProtocolIDs of all the registered handlers.
182
-func (n *Network) Protocols() []inet.ProtocolID {
183
- return n.mux.Protocols()
184
-}
185
-
186
-// CtxGroup returns the network's ContextGroup
187
-func (n *Network) CtxGroup() ctxgroup.ContextGroup {
188
- return n.cg
189
-}
190
-
191
-// Swarm returns the network's peerstream.Swarm
192
-func (n *Network) Swarm() *swarm.Swarm {
193
- return n.Swarm()
194
-}
195
-
196
-// LocalPeer the network's LocalPeer
197
-func (n *Network) LocalPeer() peer.ID {
198
- return n.swarm.LocalPeer()
199
-}
200
-
201
-// Peers returns the connected peers
202
-func (n *Network) Peers() []peer.ID {
203
- return n.swarm.Peers()
204
-}
205
-
206
-// Peers returns the connected peers
207
-func (n *Network) Peerstore() peer.Peerstore {
208
- return n.ps
209
-}
210
-
211
-// Conns returns the connected peers
212
-func (n *Network) Conns() []inet.Conn {
213
- conns1 := n.swarm.Connections()
214
- out := make([]inet.Conn, len(conns1))
215
- for i, c := range conns1 {
216
- out[i] = (*conn_)(c)
217
- }
218
- return out
219
-}
220
-
221
-// ConnsToPeer returns the connections in this Netowrk for given peer.
222
-func (n *Network) ConnsToPeer(p peer.ID) []inet.Conn {
223
- conns1 := n.swarm.ConnectionsToPeer(p)
224
- out := make([]inet.Conn, len(conns1))
225
- for i, c := range conns1 {
226
- out[i] = (*conn_)(c)
227
- }
228
- return out
229
-}
230
-
231
-// ClosePeer connection to peer
232
-func (n *Network) ClosePeer(p peer.ID) error {
233
- return n.swarm.CloseConnection(p)
234
-}
235
-
236
-// close is the real teardown function
237
-func (n *Network) close() error {
238
- return n.swarm.Close()
239
-}
240
-
241
-// Close calls the ContextCloser func
242
-func (n *Network) Close() error {
243
- return n.cg.Close()
244
-}
245
-
246
-// BandwidthTotals returns the total amount of bandwidth transferred
247
-func (n *Network) BandwidthTotals() (in uint64, out uint64) {
248
- // need to implement this. probably best to do it in swarm this time.
249
- // need a "metrics" object
250
- return 0, 0
251
-}
252
-
253
-// ListenAddresses returns a list of addresses at which this network listens.
254
-func (n *Network) ListenAddresses() []ma.Multiaddr {
255
- return n.swarm.ListenAddresses()
256
-}
257
-
258
-// InterfaceListenAddresses returns a list of addresses at which this network
259
-// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
260
-// use the known local interfaces.
261
-func (n *Network) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
262
- return swarm.InterfaceListenAddresses(n.swarm)
263
-}
264
-
265
-// Connectedness returns a state signaling connection capabilities
266
-// For now only returns Connected || NotConnected. Expand into more later.
267
-func (n *Network) Connectedness(p peer.ID) inet.Connectedness {
268
- c := n.swarm.ConnectionsToPeer(p)
269
- if c != nil && len(c) > 0 {
270
- return inet.Connected
271
- }
272
- return inet.NotConnected
273
-}
274
-
275
-// NewStream returns a new stream to given peer p.
276
-// If there is no connection to p, attempts to create one.
277
-// If ProtocolID is "", writes no header.
278
-func (n *Network) NewStream(pr inet.ProtocolID, p peer.ID) (inet.Stream, error) {
279
- log.Debugf("[%s] network opening stream to peer [%s]: %s", n.local, p, pr)
280
- s, err := n.swarm.NewStreamWithPeer(p)
281
- if err != nil {
282
- return nil, err
283
- }
284
-
285
- ss := (*stream)(s)
286
-
287
- if err := mux.WriteProtocolHeader(pr, ss); err != nil {
288
- ss.Close()
289
- return nil, err
290
- }
291
-
292
- return ss, nil
293
-}
294
-
295
-// SetHandler sets the protocol handler on the Network's Muxer.
296
-// This operation is threadsafe.
297
-func (n *Network) SetHandler(p inet.ProtocolID, h inet.StreamHandler) {
298
- n.mux.SetHandler(p, h)
299
-}
300
-
301
-// String returns a string representation of Network.
302
-func (n *Network) String() string {
303
- return fmt.Sprintf("<Network %s>", n.LocalPeer())
304
-}
305
-
306
-// IdentifyProtocol returns the network's IDService
307
-func (n *Network) IdentifyProtocol() *ids.IDService {
308
- return n.ids
309
-}
p2p/net/swarmnet/net_test.go
deleted
-78
@@ -1,78 +0,0 @@
1
-package net_test
2
-
3
-import (
4
- "fmt"
5
- "testing"
6
- "time"
7
-
8
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
9
-
10
- inet "github.com/jbenet/go-ipfs/p2p/net"
11
- netutil "github.com/jbenet/go-ipfs/p2p/net/swarmnet/util"
12
-)
13
-
14
-// TestConnectednessCorrect starts a few networks, connects a few
15
-// and tests Connectedness value is correct.
16
-func TestConnectednessCorrect(t *testing.T) {
17
-
18
- ctx := context.Background()
19
-
20
- nets := make([]inet.Network, 4)
21
- for i := 0; i < 4; i++ {
22
- nets[i] = netutil.GenNetwork(t, ctx)
23
- }
24
-
25
- // connect 0-1, 0-2, 0-3, 1-2, 2-3
26
-
27
- dial := func(a, b inet.Network) {
28
- netutil.DivulgeAddresses(b, a)
29
- if err := a.DialPeer(ctx, b.LocalPeer()); err != nil {
30
- t.Fatalf("Failed to dial: %s", err)
31
- }
32
- }
33
-
34
- dial(nets[0], nets[1])
35
- dial(nets[0], nets[3])
36
- dial(nets[1], nets[2])
37
- dial(nets[3], nets[2])
38
-
39
- // there's something wrong with dial, i think. it's not finishing
40
- // completely. there must be some async stuff.
41
- <-time.After(100 * time.Millisecond)
42
-
43
- // test those connected show up correctly
44
-
45
- // test connected
46
- expectConnectedness(t, nets[0], nets[1], inet.Connected)
47
- expectConnectedness(t, nets[0], nets[3], inet.Connected)
48
- expectConnectedness(t, nets[1], nets[2], inet.Connected)
49
- expectConnectedness(t, nets[3], nets[2], inet.Connected)
50
-
51
- // test not connected
52
- expectConnectedness(t, nets[0], nets[2], inet.NotConnected)
53
- expectConnectedness(t, nets[1], nets[3], inet.NotConnected)
54
-
55
- for _, n := range nets {
56
- n.Close()
57
- }
58
-}
59
-
60
-func expectConnectedness(t *testing.T, a, b inet.Network, expected inet.Connectedness) {
61
- es := "%s is connected to %s, but Connectedness incorrect. %s %s"
62
- if a.Connectedness(b.LocalPeer()) != expected {
63
- t.Errorf(es, a, b, printConns(a), printConns(b))
64
- }
65
-
66
- // test symmetric case
67
- if b.Connectedness(a.LocalPeer()) != expected {
68
- t.Errorf(es, b, a, printConns(b), printConns(a))
69
- }
70
-}
71
-
72
-func printConns(n inet.Network) string {
73
- s := fmt.Sprintf("Connections in %s:\n", n)
74
- for _, c := range n.Conns() {
75
- s = s + fmt.Sprintf("- %s\n", c)
76
- }
77
- return s
78
-}
p2p/net/swarmnet/util/util.go
deleted
-31
@@ -1,31 +0,0 @@
1
-package testutil
2
-
3
-import (
4
- "testing"
5
-
6
- inet "github.com/jbenet/go-ipfs/p2p/net"
7
- sn "github.com/jbenet/go-ipfs/p2p/net/swarmnet"
8
- peer "github.com/jbenet/go-ipfs/p2p/peer"
9
- tu "github.com/jbenet/go-ipfs/util/testutil"
10
-
11
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12
-)
13
-
14
-func GenNetwork(t *testing.T, ctx context.Context) *sn.Network {
15
- p := tu.RandPeerNetParamsOrFatal(t)
16
- ps := peer.NewPeerstore()
17
- ps.AddAddress(p.ID, p.Addr)
18
- ps.AddPubKey(p.ID, p.PubKey)
19
- ps.AddPrivKey(p.ID, p.PrivKey)
20
- n, err := sn.NewNetwork(ctx, ps.Addresses(p.ID), p.ID, ps)
21
- if err != nil {
22
- t.Fatal(err)
23
- }
24
- return n
25
-}
26
-
27
-func DivulgeAddresses(a, b inet.Network) {
28
- id := a.LocalPeer()
29
- addrs := a.Peerstore().Addresses(id)
30
- b.Peerstore().AddAddresses(id, addrs)
31
-}
p2p/net2/README.md
deleted
-17
@@ -1,17 +0,0 @@
1
-# Network
2
-
3
-The IPFS Network package handles all of the peer-to-peer networking. It connects to other hosts, it encrypts communications, it muxes messages between the network's client services and target hosts. It has multiple subcomponents:
4
-
5
-- `Conn` - a connection to a single Peer
6
- - `MultiConn` - a set of connections to a single Peer
7
- - `SecureConn` - an encrypted (tls-like) connection
8
-- `Swarm` - holds connections to Peers, multiplexes from/to each `MultiConn`
9
-- `Muxer` - multiplexes between `Services` and `Swarm`. Handles `Requet/Reply`.
10
- - `Service` - connects between an outside client service and Network.
11
- - `Handler` - the client service part that handles requests
12
-
13
-It looks a bit like this:
14
-
15
-<center>
16
-
17
-</center>
p2p/net2/conn/conn.go
deleted
-157
@@ -1,157 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "fmt"
5
- "net"
6
- "time"
7
-
8
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
9
- msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
10
- mpool "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio/mpool"
11
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12
- manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
13
-
14
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
15
- peer "github.com/jbenet/go-ipfs/p2p/peer"
16
- u "github.com/jbenet/go-ipfs/util"
17
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
18
-)
19
-
20
-var log = eventlog.Logger("conn")
21
-
22
-// ReleaseBuffer puts the given byte array back into the buffer pool,
23
-// first verifying that it is the correct size
24
-func ReleaseBuffer(b []byte) {
25
- log.Debugf("Releasing buffer! (cap,size = %d, %d)", cap(b), len(b))
26
- mpool.ByteSlicePool.Put(uint32(cap(b)), b)
27
-}
28
-
29
-// singleConn represents a single connection to another Peer (IPFS Node).
30
-type singleConn struct {
31
- local peer.ID
32
- remote peer.ID
33
- maconn manet.Conn
34
- msgrw msgio.ReadWriteCloser
35
-}
36
-
37
-// newConn constructs a new connection
38
-func newSingleConn(ctx context.Context, local, remote peer.ID, maconn manet.Conn) (Conn, error) {
39
-
40
- conn := &singleConn{
41
- local: local,
42
- remote: remote,
43
- maconn: maconn,
44
- msgrw: msgio.NewReadWriter(maconn),
45
- }
46
-
47
- log.Debugf("newSingleConn %p: %v to %v", conn, local, remote)
48
- return conn, nil
49
-}
50
-
51
-// close is the internal close function, called by ContextCloser.Close
52
-func (c *singleConn) Close() error {
53
- log.Debugf("%s closing Conn with %s", c.local, c.remote)
54
- // close underlying connection
55
- return c.msgrw.Close()
56
-}
57
-
58
-// ID is an identifier unique to this connection.
59
-func (c *singleConn) ID() string {
60
- return ID(c)
61
-}
62
-
63
-func (c *singleConn) String() string {
64
- return String(c, "singleConn")
65
-}
66
-
67
-func (c *singleConn) LocalAddr() net.Addr {
68
- return c.maconn.LocalAddr()
69
-}
70
-
71
-func (c *singleConn) RemoteAddr() net.Addr {
72
- return c.maconn.RemoteAddr()
73
-}
74
-
75
-func (c *singleConn) LocalPrivateKey() ic.PrivKey {
76
- return nil
77
-}
78
-
79
-func (c *singleConn) RemotePublicKey() ic.PubKey {
80
- return nil
81
-}
82
-
83
-func (c *singleConn) SetDeadline(t time.Time) error {
84
- return c.maconn.SetDeadline(t)
85
-}
86
-func (c *singleConn) SetReadDeadline(t time.Time) error {
87
- return c.maconn.SetReadDeadline(t)
88
-}
89
-
90
-func (c *singleConn) SetWriteDeadline(t time.Time) error {
91
- return c.maconn.SetWriteDeadline(t)
92
-}
93
-
94
-// LocalMultiaddr is the Multiaddr on this side
95
-func (c *singleConn) LocalMultiaddr() ma.Multiaddr {
96
- return c.maconn.LocalMultiaddr()
97
-}
98
-
99
-// RemoteMultiaddr is the Multiaddr on the remote side
100
-func (c *singleConn) RemoteMultiaddr() ma.Multiaddr {
101
- return c.maconn.RemoteMultiaddr()
102
-}
103
-
104
-// LocalPeer is the Peer on this side
105
-func (c *singleConn) LocalPeer() peer.ID {
106
- return c.local
107
-}
108
-
109
-// RemotePeer is the Peer on the remote side
110
-func (c *singleConn) RemotePeer() peer.ID {
111
- return c.remote
112
-}
113
-
114
-// Read reads data, net.Conn style
115
-func (c *singleConn) Read(buf []byte) (int, error) {
116
- return c.msgrw.Read(buf)
117
-}
118
-
119
-// Write writes data, net.Conn style
120
-func (c *singleConn) Write(buf []byte) (int, error) {
121
- return c.msgrw.Write(buf)
122
-}
123
-
124
-func (c *singleConn) NextMsgLen() (int, error) {
125
- return c.msgrw.NextMsgLen()
126
-}
127
-
128
-// ReadMsg reads data, net.Conn style
129
-func (c *singleConn) ReadMsg() ([]byte, error) {
130
- return c.msgrw.ReadMsg()
131
-}
132
-
133
-// WriteMsg writes data, net.Conn style
134
-func (c *singleConn) WriteMsg(buf []byte) error {
135
- return c.msgrw.WriteMsg(buf)
136
-}
137
-
138
-// ReleaseMsg releases a buffer
139
-func (c *singleConn) ReleaseMsg(m []byte) {
140
- c.msgrw.ReleaseMsg(m)
141
-}
142
-
143
-// ID returns the ID of a given Conn.
144
-func ID(c Conn) string {
145
- l := fmt.Sprintf("%s/%s", c.LocalMultiaddr(), c.LocalPeer().Pretty())
146
- r := fmt.Sprintf("%s/%s", c.RemoteMultiaddr(), c.RemotePeer().Pretty())
147
- lh := u.Hash([]byte(l))
148
- rh := u.Hash([]byte(r))
149
- ch := u.XOR(lh, rh)
150
- return u.Key(ch).Pretty()
151
-}
152
-
153
-// String returns the user-friendly String representation of a conn
154
-func String(c Conn, typ string) string {
155
- return fmt.Sprintf("%s (%s) <-- %s %p --> (%s) %s",
156
- c.LocalPeer(), c.LocalMultiaddr(), typ, c, c.RemoteMultiaddr(), c.RemotePeer())
157
-}
p2p/net2/conn/conn_test.go
deleted
-122
@@ -1,122 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "bytes"
5
- "fmt"
6
- "os"
7
- "runtime"
8
- "sync"
9
- "testing"
10
- "time"
11
-
12
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
13
-)
14
-
15
-func testOneSendRecv(t *testing.T, c1, c2 Conn) {
16
- log.Debugf("testOneSendRecv from %s to %s", c1.LocalPeer(), c2.LocalPeer())
17
- m1 := []byte("hello")
18
- if err := c1.WriteMsg(m1); err != nil {
19
- t.Fatal(err)
20
- }
21
- m2, err := c2.ReadMsg()
22
- if err != nil {
23
- t.Fatal(err)
24
- }
25
- if !bytes.Equal(m1, m2) {
26
- t.Fatal("failed to send: %s %s", m1, m2)
27
- }
28
-}
29
-
30
-func testNotOneSendRecv(t *testing.T, c1, c2 Conn) {
31
- m1 := []byte("hello")
32
- if err := c1.WriteMsg(m1); err == nil {
33
- t.Fatal("write should have failed", err)
34
- }
35
- _, err := c2.ReadMsg()
36
- if err == nil {
37
- t.Fatal("read should have failed", err)
38
- }
39
-}
40
-
41
-func TestClose(t *testing.T) {
42
- // t.Skip("Skipping in favor of another test")
43
-
44
- ctx, cancel := context.WithCancel(context.Background())
45
- defer cancel()
46
- c1, c2, _, _ := setupSingleConn(t, ctx)
47
-
48
- testOneSendRecv(t, c1, c2)
49
- testOneSendRecv(t, c2, c1)
50
-
51
- c1.Close()
52
- testNotOneSendRecv(t, c1, c2)
53
-
54
- c2.Close()
55
- testNotOneSendRecv(t, c2, c1)
56
- testNotOneSendRecv(t, c1, c2)
57
-}
58
-
59
-func TestCloseLeak(t *testing.T) {
60
- // t.Skip("Skipping in favor of another test")
61
- if testing.Short() {
62
- t.SkipNow()
63
- }
64
-
65
- if os.Getenv("TRAVIS") == "true" {
66
- t.Skip("this doesn't work well on travis")
67
- }
68
-
69
- var wg sync.WaitGroup
70
-
71
- runPair := func(num int) {
72
- ctx, cancel := context.WithCancel(context.Background())
73
- c1, c2, _, _ := setupSingleConn(t, ctx)
74
-
75
- for i := 0; i < num; i++ {
76
- b1 := []byte(fmt.Sprintf("beep%d", i))
77
- c1.WriteMsg(b1)
78
- b2, err := c2.ReadMsg()
79
- if err != nil {
80
- panic(err)
81
- }
82
- if !bytes.Equal(b1, b2) {
83
- panic(fmt.Errorf("bytes not equal: %s != %s", b1, b2))
84
- }
85
-
86
- b2 = []byte(fmt.Sprintf("boop%d", i))
87
- c2.WriteMsg(b2)
88
- b1, err = c1.ReadMsg()
89
- if err != nil {
90
- panic(err)
91
- }
92
- if !bytes.Equal(b1, b2) {
93
- panic(fmt.Errorf("bytes not equal: %s != %s", b1, b2))
94
- }
95
-
96
- <-time.After(time.Microsecond * 5)
97
- }
98
-
99
- c1.Close()
100
- c2.Close()
101
- cancel() // close the listener
102
- wg.Done()
103
- }
104
-
105
- var cons = 5
106
- var msgs = 50
107
- log.Debugf("Running %d connections * %d msgs.\n", cons, msgs)
108
- for i := 0; i < cons; i++ {
109
- wg.Add(1)
110
- go runPair(msgs)
111
- }
112
-
113
- log.Debugf("Waiting...\n")
114
- wg.Wait()
115
- // done!
116
-
117
- <-time.After(time.Millisecond * 150)
118
- if runtime.NumGoroutine() > 20 {
119
- // panic("uncomment me to debug")
120
- t.Fatal("leaking goroutines:", runtime.NumGoroutine())
121
- }
122
-}
p2p/net2/conn/dial.go
deleted
-131
@@ -1,131 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "fmt"
5
- "strings"
6
-
7
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9
- manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
10
-
11
- peer "github.com/jbenet/go-ipfs/p2p/peer"
12
- debugerror "github.com/jbenet/go-ipfs/util/debugerror"
13
-)
14
-
15
-// String returns the string rep of d.
16
-func (d *Dialer) String() string {
17
- return fmt.Sprintf("<Dialer %s %s ...>", d.LocalPeer, d.LocalAddrs[0])
18
-}
19
-
20
-// Dial connects to a peer over a particular address
21
-// Ensures raddr is part of peer.Addresses()
22
-// Example: d.DialAddr(ctx, peer.Addresses()[0], peer)
23
-func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (Conn, error) {
24
-
25
- network, _, err := manet.DialArgs(raddr)
26
- if err != nil {
27
- return nil, err
28
- }
29
-
30
- if strings.HasPrefix(raddr.String(), "/ip4/0.0.0.0") {
31
- return nil, debugerror.Errorf("Attempted to connect to zero address: %s", raddr)
32
- }
33
-
34
- var laddr ma.Multiaddr
35
- if len(d.LocalAddrs) > 0 {
36
- // laddr := MultiaddrNetMatch(raddr, d.LocalAddrs)
37
- laddr = NetAddress(network, d.LocalAddrs)
38
- if laddr == nil {
39
- return nil, debugerror.Errorf("No local address for network %s", network)
40
- }
41
- }
42
-
43
- // TODO: try to get reusing addr/ports to work.
44
- // madialer := manet.Dialer{LocalAddr: laddr}
45
- madialer := manet.Dialer{}
46
-
47
- log.Debugf("%s dialing %s %s", d.LocalPeer, remote, raddr)
48
- maconn, err := madialer.Dial(raddr)
49
- if err != nil {
50
- return nil, err
51
- }
52
-
53
- var connOut Conn
54
- var errOut error
55
- done := make(chan struct{})
56
-
57
- // do it async to ensure we respect don contexteone
58
- go func() {
59
- defer func() { done <- struct{}{} }()
60
-
61
- c, err := newSingleConn(ctx, d.LocalPeer, remote, maconn)
62
- if err != nil {
63
- errOut = err
64
- return
65
- }
66
-
67
- if d.PrivateKey == nil {
68
- log.Warning("dialer %s dialing INSECURELY %s at %s!", d, remote, raddr)
69
- connOut = c
70
- return
71
- }
72
- c2, err := newSecureConn(ctx, d.PrivateKey, c)
73
- if err != nil {
74
- errOut = err
75
- c.Close()
76
- return
77
- }
78
-
79
- connOut = c2
80
- }()
81
-
82
- select {
83
- case <-ctx.Done():
84
- maconn.Close()
85
- return nil, ctx.Err()
86
- case <-done:
87
- // whew, finished.
88
- }
89
-
90
- return connOut, errOut
91
-}
92
-
93
-// MultiaddrProtocolsMatch returns whether two multiaddrs match in protocol stacks.
94
-func MultiaddrProtocolsMatch(a, b ma.Multiaddr) bool {
95
- ap := a.Protocols()
96
- bp := b.Protocols()
97
-
98
- if len(ap) != len(bp) {
99
- return false
100
- }
101
-
102
- for i, api := range ap {
103
- if api != bp[i] {
104
- return false
105
- }
106
- }
107
-
108
- return true
109
-}
110
-
111
-// MultiaddrNetMatch returns the first Multiaddr found to match network.
112
-func MultiaddrNetMatch(tgt ma.Multiaddr, srcs []ma.Multiaddr) ma.Multiaddr {
113
- for _, a := range srcs {
114
- if MultiaddrProtocolsMatch(tgt, a) {
115
- return a
116
- }
117
- }
118
- return nil
119
-}
120
-
121
-// NetAddress returns the first Multiaddr found for a given network.
122
-func NetAddress(n string, addrs []ma.Multiaddr) ma.Multiaddr {
123
- for _, a := range addrs {
124
- for _, p := range a.Protocols() {
125
- if p.Name == n {
126
- return a
127
- }
128
- }
129
- }
130
- return nil
131
-}
p2p/net2/conn/dial_test.go
deleted
-165
@@ -1,165 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "io"
5
- "net"
6
- "testing"
7
- "time"
8
-
9
- tu "github.com/jbenet/go-ipfs/util/testutil"
10
-
11
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12
-)
13
-
14
-func echoListen(ctx context.Context, listener Listener) {
15
- for {
16
- c, err := listener.Accept()
17
- if err != nil {
18
-
19
- select {
20
- case <-ctx.Done():
21
- return
22
- default:
23
- }
24
-
25
- if ne, ok := err.(net.Error); ok && ne.Temporary() {
26
- <-time.After(time.Microsecond * 10)
27
- continue
28
- }
29
-
30
- log.Debugf("echoListen: listener appears to be closing")
31
- return
32
- }
33
-
34
- go echo(c.(Conn))
35
- }
36
-}
37
-
38
-func echo(c Conn) {
39
- io.Copy(c, c)
40
-}
41
-
42
-func setupSecureConn(t *testing.T, ctx context.Context) (a, b Conn, p1, p2 tu.PeerNetParams) {
43
- return setupConn(t, ctx, true)
44
-}
45
-
46
-func setupSingleConn(t *testing.T, ctx context.Context) (a, b Conn, p1, p2 tu.PeerNetParams) {
47
- return setupConn(t, ctx, false)
48
-}
49
-
50
-func setupConn(t *testing.T, ctx context.Context, secure bool) (a, b Conn, p1, p2 tu.PeerNetParams) {
51
-
52
- p1 = tu.RandPeerNetParamsOrFatal(t)
53
- p2 = tu.RandPeerNetParamsOrFatal(t)
54
- laddr := p1.Addr
55
-
56
- key1 := p1.PrivKey
57
- key2 := p2.PrivKey
58
- if !secure {
59
- key1 = nil
60
- key2 = nil
61
- }
62
- l1, err := Listen(ctx, laddr, p1.ID, key1)
63
- if err != nil {
64
- t.Fatal(err)
65
- }
66
-
67
- d2 := &Dialer{
68
- LocalPeer: p2.ID,
69
- PrivateKey: key2,
70
- }
71
-
72
- var c2 Conn
73
-
74
- done := make(chan error)
75
- go func() {
76
- var err error
77
- c2, err = d2.Dial(ctx, p1.Addr, p1.ID)
78
- if err != nil {
79
- done <- err
80
- }
81
- close(done)
82
- }()
83
-
84
- c1, err := l1.Accept()
85
- if err != nil {
86
- t.Fatal("failed to accept", err)
87
- }
88
- if err := <-done; err != nil {
89
- t.Fatal(err)
90
- }
91
-
92
- return c1.(Conn), c2, p1, p2
93
-}
94
-
95
-func testDialer(t *testing.T, secure bool) {
96
- // t.Skip("Skipping in favor of another test")
97
-
98
- p1 := tu.RandPeerNetParamsOrFatal(t)
99
- p2 := tu.RandPeerNetParamsOrFatal(t)
100
-
101
- key1 := p1.PrivKey
102
- key2 := p2.PrivKey
103
- if !secure {
104
- key1 = nil
105
- key2 = nil
106
- }
107
-
108
- ctx, cancel := context.WithCancel(context.Background())
109
- l1, err := Listen(ctx, p1.Addr, p1.ID, key1)
110
- if err != nil {
111
- t.Fatal(err)
112
- }
113
-
114
- d2 := &Dialer{
115
- LocalPeer: p2.ID,
116
- PrivateKey: key2,
117
- }
118
-
119
- go echoListen(ctx, l1)
120
-
121
- c, err := d2.Dial(ctx, p1.Addr, p1.ID)
122
- if err != nil {
123
- t.Fatal("error dialing peer", err)
124
- }
125
-
126
- // fmt.Println("sending")
127
- c.WriteMsg([]byte("beep"))
128
- c.WriteMsg([]byte("boop"))
129
-
130
- out, err := c.ReadMsg()
131
- if err != nil {
132
- t.Fatal(err)
133
- }
134
-
135
- // fmt.Println("recving", string(out))
136
- data := string(out)
137
- if data != "beep" {
138
- t.Error("unexpected conn output", data)
139
- }
140
-
141
- out, err = c.ReadMsg()
142
- if err != nil {
143
- t.Fatal(err)
144
- }
145
-
146
- data = string(out)
147
- if string(out) != "boop" {
148
- t.Error("unexpected conn output", data)
149
- }
150
-
151
- // fmt.Println("closing")
152
- c.Close()
153
- l1.Close()
154
- cancel()
155
-}
156
-
157
-func TestDialerInsecure(t *testing.T) {
158
- // t.Skip("Skipping in favor of another test")
159
- testDialer(t, false)
160
-}
161
-
162
-func TestDialerSecure(t *testing.T) {
163
- // t.Skip("Skipping in favor of another test")
164
- testDialer(t, true)
165
-}
p2p/net2/conn/interface.go
deleted
-84
@@ -1,84 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "io"
5
- "net"
6
- "time"
7
-
8
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
9
- peer "github.com/jbenet/go-ipfs/p2p/peer"
10
- u "github.com/jbenet/go-ipfs/util"
11
-
12
- msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
13
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
14
-)
15
-
16
-// Map maps Keys (Peer.IDs) to Connections.
17
-type Map map[u.Key]Conn
18
-
19
-type PeerConn interface {
20
- // LocalPeer (this side) ID, PrivateKey, and Address
21
- LocalPeer() peer.ID
22
- LocalPrivateKey() ic.PrivKey
23
- LocalMultiaddr() ma.Multiaddr
24
-
25
- // RemotePeer ID, PublicKey, and Address
26
- RemotePeer() peer.ID
27
- RemotePublicKey() ic.PubKey
28
- RemoteMultiaddr() ma.Multiaddr
29
-}
30
-
31
-// Conn is a generic message-based Peer-to-Peer connection.
32
-type Conn interface {
33
- PeerConn
34
-
35
- // ID is an identifier unique to this connection.
36
- ID() string
37
-
38
- // can't just say "net.Conn" cause we have duplicate methods.
39
- LocalAddr() net.Addr
40
- RemoteAddr() net.Addr
41
- SetDeadline(t time.Time) error
42
- SetReadDeadline(t time.Time) error
43
- SetWriteDeadline(t time.Time) error
44
-
45
- msgio.Reader
46
- msgio.Writer
47
- io.Closer
48
-}
49
-
50
-// Dialer is an object that can open connections. We could have a "convenience"
51
-// Dial function as before, but it would have many arguments, as dialing is
52
-// no longer simple (need a peerstore, a local peer, a context, a network, etc)
53
-type Dialer struct {
54
-
55
- // LocalPeer is the identity of the local Peer.
56
- LocalPeer peer.ID
57
-
58
- // LocalAddrs is a set of local addresses to use.
59
- LocalAddrs []ma.Multiaddr
60
-
61
- // PrivateKey used to initialize a secure connection.
62
- // Warning: if PrivateKey is nil, connection will not be secured.
63
- PrivateKey ic.PrivKey
64
-}
65
-
66
-// Listener is an object that can accept connections. It matches net.Listener
67
-type Listener interface {
68
-
69
- // Accept waits for and returns the next connection to the listener.
70
- Accept() (net.Conn, error)
71
-
72
- // Addr is the local address
73
- Addr() net.Addr
74
-
75
- // Multiaddr is the local multiaddr address
76
- Multiaddr() ma.Multiaddr
77
-
78
- // LocalPeer is the identity of the local Peer.
79
- LocalPeer() peer.ID
80
-
81
- // Close closes the listener.
82
- // Any blocked Accept operations will be unblocked and return errors.
83
- Close() error
84
-}
p2p/net2/conn/listen.go
deleted
-115
@@ -1,115 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "fmt"
5
- "net"
6
-
7
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
9
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
10
- manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
11
-
12
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
13
- peer "github.com/jbenet/go-ipfs/p2p/peer"
14
-)
15
-
16
-// listener is an object that can accept connections. It implements Listener
17
-type listener struct {
18
- manet.Listener
19
-
20
- maddr ma.Multiaddr // Local multiaddr to listen on
21
- local peer.ID // LocalPeer is the identity of the local Peer
22
- privk ic.PrivKey // private key to use to initialize secure conns
23
-
24
- cg ctxgroup.ContextGroup
25
-}
26
-
27
-func (l *listener) teardown() error {
28
- defer log.Debugf("listener closed: %s %s", l.local, l.maddr)
29
- return l.Listener.Close()
30
-}
31
-
32
-func (l *listener) Close() error {
33
- log.Debugf("listener closing: %s %s", l.local, l.maddr)
34
- return l.cg.Close()
35
-}
36
-
37
-func (l *listener) String() string {
38
- return fmt.Sprintf("<Listener %s %s>", l.local, l.maddr)
39
-}
40
-
41
-// Accept waits for and returns the next connection to the listener.
42
-// Note that unfortunately this
43
-func (l *listener) Accept() (net.Conn, error) {
44
-
45
- // listeners dont have contexts. given changes dont make sense here anymore
46
- // note that the parent of listener will Close, which will interrupt all io.
47
- // Contexts and io don't mix.
48
- ctx := context.Background()
49
-
50
- maconn, err := l.Listener.Accept()
51
- if err != nil {
52
- return nil, err
53
- }
54
-
55
- c, err := newSingleConn(ctx, l.local, "", maconn)
56
- if err != nil {
57
- return nil, fmt.Errorf("Error accepting connection: %v", err)
58
- }
59
-
60
- if l.privk == nil {
61
- log.Warning("listener %s listening INSECURELY!", l)
62
- return c, nil
63
- }
64
- sc, err := newSecureConn(ctx, l.privk, c)
65
- if err != nil {
66
- return nil, fmt.Errorf("Error securing connection: %v", err)
67
- }
68
- return sc, nil
69
-}
70
-
71
-func (l *listener) Addr() net.Addr {
72
- return l.Listener.Addr()
73
-}
74
-
75
-// Multiaddr is the identity of the local Peer.
76
-func (l *listener) Multiaddr() ma.Multiaddr {
77
- return l.maddr
78
-}
79
-
80
-// LocalPeer is the identity of the local Peer.
81
-func (l *listener) LocalPeer() peer.ID {
82
- return l.local
83
-}
84
-
85
-func (l *listener) Loggable() map[string]interface{} {
86
- return map[string]interface{}{
87
- "listener": map[string]interface{}{
88
- "peer": l.LocalPeer(),
89
- "address": l.Multiaddr(),
90
- "secure": (l.privk != nil),
91
- },
92
- }
93
-}
94
-
95
-// Listen listens on the particular multiaddr, with given peer and peerstore.
96
-func Listen(ctx context.Context, addr ma.Multiaddr, local peer.ID, sk ic.PrivKey) (Listener, error) {
97
-
98
- ml, err := manet.Listen(addr)
99
- if err != nil {
100
- return nil, fmt.Errorf("Failed to listen on %s: %s", addr, err)
101
- }
102
-
103
- l := &listener{
104
- Listener: ml,
105
- maddr: addr,
106
- local: local,
107
- privk: sk,
108
- cg: ctxgroup.WithContext(ctx),
109
- }
110
- l.cg.SetTeardown(l.teardown)
111
-
112
- log.Infof("swarm listening on %s", l.Multiaddr())
113
- log.Event(ctx, "swarmListen", l)
114
- return l, nil
115
-}
p2p/net2/conn/secure_conn.go
deleted
-154
@@ -1,154 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "net"
5
- "time"
6
-
7
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
9
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
10
-
11
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
12
- secio "github.com/jbenet/go-ipfs/p2p/crypto/secio"
13
- peer "github.com/jbenet/go-ipfs/p2p/peer"
14
- errors "github.com/jbenet/go-ipfs/util/debugerror"
15
-)
16
-
17
-// secureConn wraps another Conn object with an encrypted channel.
18
-type secureConn struct {
19
-
20
- // the wrapped conn
21
- insecure Conn
22
-
23
- // secure io (wrapping insecure)
24
- secure msgio.ReadWriteCloser
25
-
26
- // secure Session
27
- session secio.Session
28
-}
29
-
30
-// newConn constructs a new connection
31
-func newSecureConn(ctx context.Context, sk ic.PrivKey, insecure Conn) (Conn, error) {
32
-
33
- if insecure == nil {
34
- return nil, errors.New("insecure is nil")
35
- }
36
- if insecure.LocalPeer() == "" {
37
- return nil, errors.New("insecure.LocalPeer() is nil")
38
- }
39
- if sk == nil {
40
- panic("way")
41
- return nil, errors.New("private key is nil")
42
- }
43
-
44
- // NewSession performs the secure handshake, which takes multiple RTT
45
- sessgen := secio.SessionGenerator{LocalID: insecure.LocalPeer(), PrivateKey: sk}
46
- session, err := sessgen.NewSession(ctx, insecure)
47
- if err != nil {
48
- return nil, err
49
- }
50
-
51
- conn := &secureConn{
52
- insecure: insecure,
53
- session: session,
54
- secure: session.ReadWriter(),
55
- }
56
- log.Debugf("newSecureConn: %v to %v handshake success!", conn.LocalPeer(), conn.RemotePeer())
57
- return conn, nil
58
-}
59
-
60
-func (c *secureConn) Close() error {
61
- if err := c.secure.Close(); err != nil {
62
- c.insecure.Close()
63
- return err
64
- }
65
- return c.insecure.Close()
66
-}
67
-
68
-// ID is an identifier unique to this connection.
69
-func (c *secureConn) ID() string {
70
- return ID(c)
71
-}
72
-
73
-func (c *secureConn) String() string {
74
- return String(c, "secureConn")
75
-}
76
-
77
-func (c *secureConn) LocalAddr() net.Addr {
78
- return c.insecure.LocalAddr()
79
-}
80
-
81
-func (c *secureConn) RemoteAddr() net.Addr {
82
- return c.insecure.RemoteAddr()
83
-}
84
-
85
-func (c *secureConn) SetDeadline(t time.Time) error {
86
- return c.insecure.SetDeadline(t)
87
-}
88
-
89
-func (c *secureConn) SetReadDeadline(t time.Time) error {
90
- return c.insecure.SetReadDeadline(t)
91
-}
92
-
93
-func (c *secureConn) SetWriteDeadline(t time.Time) error {
94
- return c.insecure.SetWriteDeadline(t)
95
-}
96
-
97
-// LocalMultiaddr is the Multiaddr on this side
98
-func (c *secureConn) LocalMultiaddr() ma.Multiaddr {
99
- return c.insecure.LocalMultiaddr()
100
-}
101
-
102
-// RemoteMultiaddr is the Multiaddr on the remote side
103
-func (c *secureConn) RemoteMultiaddr() ma.Multiaddr {
104
- return c.insecure.RemoteMultiaddr()
105
-}
106
-
107
-// LocalPeer is the Peer on this side
108
-func (c *secureConn) LocalPeer() peer.ID {
109
- return c.session.LocalPeer()
110
-}
111
-
112
-// RemotePeer is the Peer on the remote side
113
-func (c *secureConn) RemotePeer() peer.ID {
114
- return c.session.RemotePeer()
115
-}
116
-
117
-// LocalPrivateKey is the public key of the peer on this side
118
-func (c *secureConn) LocalPrivateKey() ic.PrivKey {
119
- return c.session.LocalPrivateKey()
120
-}
121
-
122
-// RemotePubKey is the public key of the peer on the remote side
123
-func (c *secureConn) RemotePublicKey() ic.PubKey {
124
- return c.session.RemotePublicKey()
125
-}
126
-
127
-// Read reads data, net.Conn style
128
-func (c *secureConn) Read(buf []byte) (int, error) {
129
- return c.secure.Read(buf)
130
-}
131
-
132
-// Write writes data, net.Conn style
133
-func (c *secureConn) Write(buf []byte) (int, error) {
134
- return c.secure.Write(buf)
135
-}
136
-
137
-func (c *secureConn) NextMsgLen() (int, error) {
138
- return c.secure.NextMsgLen()
139
-}
140
-
141
-// ReadMsg reads data, net.Conn style
142
-func (c *secureConn) ReadMsg() ([]byte, error) {
143
- return c.secure.ReadMsg()
144
-}
145
-
146
-// WriteMsg writes data, net.Conn style
147
-func (c *secureConn) WriteMsg(buf []byte) error {
148
- return c.secure.WriteMsg(buf)
149
-}
150
-
151
-// ReleaseMsg releases a buffer
152
-func (c *secureConn) ReleaseMsg(m []byte) {
153
- c.secure.ReleaseMsg(m)
154
-}
p2p/net2/conn/secure_conn_test.go
deleted
-199
@@ -1,199 +0,0 @@
1
-package conn
2
-
3
-import (
4
- "bytes"
5
- "os"
6
- "runtime"
7
- "sync"
8
- "testing"
9
- "time"
10
-
11
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
12
-
13
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
14
-)
15
-
16
-func upgradeToSecureConn(t *testing.T, ctx context.Context, sk ic.PrivKey, c Conn) (Conn, error) {
17
- if c, ok := c.(*secureConn); ok {
18
- return c, nil
19
- }
20
-
21
- // shouldn't happen, because dial + listen already return secure conns.
22
- s, err := newSecureConn(ctx, sk, c)
23
- if err != nil {
24
- return nil, err
25
- }
26
- return s, nil
27
-}
28
-
29
-func secureHandshake(t *testing.T, ctx context.Context, sk ic.PrivKey, c Conn, done chan error) {
30
- _, err := upgradeToSecureConn(t, ctx, sk, c)
31
- done <- err
32
-}
33
-
34
-func TestSecureSimple(t *testing.T) {
35
- // t.Skip("Skipping in favor of another test")
36
-
37
- numMsgs := 100
38
- if testing.Short() {
39
- numMsgs = 10
40
- }
41
-
42
- ctx := context.Background()
43
- c1, c2, p1, p2 := setupSingleConn(t, ctx)
44
-
45
- done := make(chan error)
46
- go secureHandshake(t, ctx, p1.PrivKey, c1, done)
47
- go secureHandshake(t, ctx, p2.PrivKey, c2, done)
48
-
49
- for i := 0; i < 2; i++ {
50
- if err := <-done; err != nil {
51
- t.Fatal(err)
52
- }
53
- }
54
-
55
- for i := 0; i < numMsgs; i++ {
56
- testOneSendRecv(t, c1, c2)
57
- testOneSendRecv(t, c2, c1)
58
- }
59
-
60
- c1.Close()
61
- c2.Close()
62
-}
63
-
64
-func TestSecureClose(t *testing.T) {
65
- // t.Skip("Skipping in favor of another test")
66
-
67
- ctx := context.Background()
68
- c1, c2, p1, p2 := setupSingleConn(t, ctx)
69
-
70
- done := make(chan error)
71
- go secureHandshake(t, ctx, p1.PrivKey, c1, done)
72
- go secureHandshake(t, ctx, p2.PrivKey, c2, done)
73
-
74
- for i := 0; i < 2; i++ {
75
- if err := <-done; err != nil {
76
- t.Fatal(err)
77
- }
78
- }
79
-
80
- testOneSendRecv(t, c1, c2)
81
-
82
- c1.Close()
83
- testNotOneSendRecv(t, c1, c2)
84
-
85
- c2.Close()
86
- testNotOneSendRecv(t, c1, c2)
87
- testNotOneSendRecv(t, c2, c1)
88
-
89
-}
90
-
91
-func TestSecureCancelHandshake(t *testing.T) {
92
- // t.Skip("Skipping in favor of another test")
93
-
94
- ctx, cancel := context.WithCancel(context.Background())
95
- c1, c2, p1, p2 := setupSingleConn(t, ctx)
96
-
97
- done := make(chan error)
98
- go secureHandshake(t, ctx, p1.PrivKey, c1, done)
99
- <-time.After(time.Millisecond)
100
- cancel() // cancel ctx
101
- go secureHandshake(t, ctx, p2.PrivKey, c2, done)
102
-
103
- for i := 0; i < 2; i++ {
104
- if err := <-done; err == nil {
105
- t.Error("cancel should've errored out")
106
- }
107
- }
108
-}
109
-
110
-func TestSecureHandshakeFailsWithWrongKeys(t *testing.T) {
111
- // t.Skip("Skipping in favor of another test")
112
-
113
- ctx, cancel := context.WithCancel(context.Background())
114
- defer cancel()
115
- c1, c2, p1, p2 := setupSingleConn(t, ctx)
116
-
117
- done := make(chan error)
118
- go secureHandshake(t, ctx, p2.PrivKey, c1, done)
119
- go secureHandshake(t, ctx, p1.PrivKey, c2, done)
120
-
121
- for i := 0; i < 2; i++ {
122
- if err := <-done; err == nil {
123
- t.Fatal("wrong keys should've errored out.")
124
- }
125
- }
126
-}
127
-
128
-func TestSecureCloseLeak(t *testing.T) {
129
- // t.Skip("Skipping in favor of another test")
130
-
131
- if testing.Short() {
132
- t.SkipNow()
133
- }
134
- if os.Getenv("TRAVIS") == "true" {
135
- t.Skip("this doesn't work well on travis")
136
- }
137
-
138
- runPair := func(c1, c2 Conn, num int) {
139
- log.Debugf("runPair %d", num)
140
-
141
- for i := 0; i < num; i++ {
142
- log.Debugf("runPair iteration %d", i)
143
- b1 := []byte("beep")
144
- c1.WriteMsg(b1)
145
- b2, err := c2.ReadMsg()
146
- if err != nil {
147
- panic(err)
148
- }
149
- if !bytes.Equal(b1, b2) {
150
- panic("bytes not equal")
151
- }
152
-
153
- b2 = []byte("beep")
154
- c2.WriteMsg(b2)
155
- b1, err = c1.ReadMsg()
156
- if err != nil {
157
- panic(err)
158
- }
159
- if !bytes.Equal(b1, b2) {
160
- panic("bytes not equal")
161
- }
162
-
163
- <-time.After(time.Microsecond * 5)
164
- }
165
- }
166
-
167
- var cons = 5
168
- var msgs = 50
169
- log.Debugf("Running %d connections * %d msgs.\n", cons, msgs)
170
-
171
- var wg sync.WaitGroup
172
- for i := 0; i < cons; i++ {
173
- wg.Add(1)
174
-
175
- ctx, cancel := context.WithCancel(context.Background())
176
- c1, c2, _, _ := setupSecureConn(t, ctx)
177
- go func(c1, c2 Conn) {
178
-
179
- defer func() {
180
- c1.Close()
181
- c2.Close()
182
- cancel()
183
- wg.Done()
184
- }()
185
-
186
- runPair(c1, c2, msgs)
187
- }(c1, c2)
188
- }
189
-
190
- log.Debugf("Waiting...\n")
191
- wg.Wait()
192
- // done!
193
-
194
- <-time.After(time.Millisecond * 150)
195
- if runtime.NumGoroutine() > 20 {
196
- // panic("uncomment me to debug")
197
- t.Fatal("leaking goroutines:", runtime.NumGoroutine())
198
- }
199
-}
p2p/net2/interface.go
deleted
-133
@@ -1,133 +0,0 @@
1
-package net
2
-
3
-import (
4
- "io"
5
-
6
- conn "github.com/jbenet/go-ipfs/p2p/net2/conn"
7
- peer "github.com/jbenet/go-ipfs/p2p/peer"
8
-
9
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
10
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
11
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12
-)
13
-
14
-// MessageSizeMax is a soft (recommended) maximum for network messages.
15
-// One can write more, as the interface is a stream. But it is useful
16
-// to bunch it up into multiple read/writes when the whole message is
17
-// a single, large serialized object.
18
-const MessageSizeMax = 2 << 22 // 4MB
19
-
20
-// Stream represents a bidirectional channel between two agents in
21
-// the IPFS network. "agent" is as granular as desired, potentially
22
-// being a "request -> reply" pair, or whole protocols.
23
-// Streams are backed by SPDY streams underneath the hood.
24
-type Stream interface {
25
- io.Reader
26
- io.Writer
27
- io.Closer
28
-
29
- // Conn returns the connection this stream is part of.
30
- Conn() Conn
31
-}
32
-
33
-// StreamHandler is the type of function used to listen for
34
-// streams opened by the remote side.
35
-type StreamHandler func(Stream)
36
-
37
-// Conn is a connection to a remote peer. It multiplexes streams.
38
-// Usually there is no need to use a Conn directly, but it may
39
-// be useful to get information about the peer on the other side:
40
-// stream.Conn().RemotePeer()
41
-type Conn interface {
42
- conn.PeerConn
43
-
44
- // NewStream constructs a new Stream over this conn.
45
- NewStream() (Stream, error)
46
-}
47
-
48
-// ConnHandler is the type of function used to listen for
49
-// connections opened by the remote side.
50
-type ConnHandler func(Conn)
51
-
52
-// Network is the interface used to connect to the outside world.
53
-// It dials and listens for connections. it uses a Swarm to pool
54
-// connnections (see swarm pkg, and peerstream.Swarm). Connections
55
-// are encrypted with a TLS-like protocol.
56
-type Network interface {
57
- Dialer
58
- io.Closer
59
-
60
- // SetStreamHandler sets the handler for new streams opened by the
61
- // remote side. This operation is threadsafe.
62
- SetStreamHandler(StreamHandler)
63
-
64
- // SetConnHandler sets the handler for new connections opened by the
65
- // remote side. This operation is threadsafe.
66
- SetConnHandler(ConnHandler)
67
-
68
- // NewStream returns a new stream to given peer p.
69
- // If there is no connection to p, attempts to create one.
70
- NewStream(peer.ID) (Stream, error)
71
-
72
- // ListenAddresses returns a list of addresses at which this network listens.
73
- ListenAddresses() []ma.Multiaddr
74
-
75
- // InterfaceListenAddresses returns a list of addresses at which this network
76
- // listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
77
- // use the known local interfaces.
78
- InterfaceListenAddresses() ([]ma.Multiaddr, error)
79
-
80
- // CtxGroup returns the network's contextGroup
81
- CtxGroup() ctxgroup.ContextGroup
82
-}
83
-
84
-// Dialer represents a service that can dial out to peers
85
-// (this is usually just a Network, but other services may not need the whole
86
-// stack, and thus it becomes easier to mock)
87
-type Dialer interface {
88
-
89
- // Peerstore returns the internal peerstore
90
- // This is useful to tell the dialer about a new address for a peer.
91
- // Or use one of the public keys found out over the network.
92
- Peerstore() peer.Peerstore
93
-
94
- // LocalPeer returns the local peer associated with this network
95
- LocalPeer() peer.ID
96
-
97
- // DialPeer establishes a connection to a given peer
98
- DialPeer(context.Context, peer.ID) (Conn, error)
99
-
100
- // ClosePeer closes the connection to a given peer
101
- ClosePeer(peer.ID) error
102
-
103
- // Connectedness returns a state signaling connection capabilities
104
- Connectedness(peer.ID) Connectedness
105
-
106
- // Peers returns the peers connected
107
- Peers() []peer.ID
108
-
109
- // Conns returns the connections in this Netowrk
110
- Conns() []Conn
111
-
112
- // ConnsToPeer returns the connections in this Netowrk for given peer.
113
- ConnsToPeer(p peer.ID) []Conn
114
-}
115
-
116
-// Connectedness signals the capacity for a connection with a given node.
117
-// It is used to signal to services and other peers whether a node is reachable.
118
-type Connectedness int
119
-
120
-const (
121
- // NotConnected means no connection to peer, and no extra information (default)
122
- NotConnected Connectedness = iota
123
-
124
- // Connected means has an open, live connection to peer
125
- Connected
126
-
127
- // CanConnect means recently connected to peer, terminated gracefully
128
- CanConnect
129
-
130
- // CannotConnect means recently attempted connecting but failed to connect.
131
- // (should signal "made effort, failed")
132
- CannotConnect
133
-)
p2p/net2/mock/interface.go
deleted
-101
@@ -1,101 +0,0 @@
1
-// Package mocknet provides a mock net.Network to test with.
2
-//
3
-// - a Mocknet has many inet.Networks
4
-// - a Mocknet has many Links
5
-// - a Link joins two inet.Networks
6
-// - inet.Conns and inet.Streams are created by inet.Networks
7
-package mocknet
8
-
9
-import (
10
- "io"
11
- "time"
12
-
13
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
14
- host "github.com/jbenet/go-ipfs/p2p/host"
15
- inet "github.com/jbenet/go-ipfs/p2p/net2"
16
- peer "github.com/jbenet/go-ipfs/p2p/peer"
17
-
18
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
19
-)
20
-
21
-type Mocknet interface {
22
-
23
- // GenPeer generates a peer and its inet.Network in the Mocknet
24
- GenPeer() (host.Host, error)
25
-
26
- // AddPeer adds an existing peer. we need both a privkey and addr.
27
- // ID is derived from PrivKey
28
- AddPeer(ic.PrivKey, ma.Multiaddr) (host.Host, error)
29
-
30
- // retrieve things (with randomized iteration order)
31
- Peers() []peer.ID
32
- Net(peer.ID) inet.Network
33
- Nets() []inet.Network
34
- Host(peer.ID) host.Host
35
- Hosts() []host.Host
36
- Links() LinkMap
37
- LinksBetweenPeers(a, b peer.ID) []Link
38
- LinksBetweenNets(a, b inet.Network) []Link
39
-
40
- // Links are the **ability to connect**.
41
- // think of Links as the physical medium.
42
- // For p1 and p2 to connect, a link must exist between them.
43
- // (this makes it possible to test dial failures, and
44
- // things like relaying traffic)
45
- LinkPeers(peer.ID, peer.ID) (Link, error)
46
- LinkNets(inet.Network, inet.Network) (Link, error)
47
- Unlink(Link) error
48
- UnlinkPeers(peer.ID, peer.ID) error
49
- UnlinkNets(inet.Network, inet.Network) error
50
-
51
- // LinkDefaults are the default options that govern links
52
- // if they do not have thier own option set.
53
- SetLinkDefaults(LinkOptions)
54
- LinkDefaults() LinkOptions
55
-
56
- // Connections are the usual. Connecting means Dialing.
57
- // **to succeed, peers must be linked beforehand**
58
- ConnectPeers(peer.ID, peer.ID) (inet.Conn, error)
59
- ConnectNets(inet.Network, inet.Network) (inet.Conn, error)
60
- DisconnectPeers(peer.ID, peer.ID) error
61
- DisconnectNets(inet.Network, inet.Network) error
62
-}
63
-
64
-// LinkOptions are used to change aspects of the links.
65
-// Sorry but they dont work yet :(
66
-type LinkOptions struct {
67
- Latency time.Duration
68
- Bandwidth int // in bytes-per-second
69
- // we can make these values distributions down the road.
70
-}
71
-
72
-// Link represents the **possibility** of a connection between
73
-// two peers. Think of it like physical network links. Without
74
-// them, the peers can try and try but they won't be able to
75
-// connect. This allows constructing topologies where specific
76
-// nodes cannot talk to each other directly. :)
77
-type Link interface {
78
- Networks() []inet.Network
79
- Peers() []peer.ID
80
-
81
- SetOptions(LinkOptions)
82
- Options() LinkOptions
83
-
84
- // Metrics() Metrics
85
-}
86
-
87
-// LinkMap is a 3D map to give us an easy way to track links.
88
-// (wow, much map. so data structure. how compose. ahhh pointer)
89
-type LinkMap map[string]map[string]map[Link]struct{}
90
-
91
-// Printer lets you inspect things :)
92
-type Printer interface {
93
- // MocknetLinks shows the entire Mocknet's link table :)
94
- MocknetLinks(mn Mocknet)
95
- NetworkConns(ni inet.Network)
96
-}
97
-
98
-// PrinterTo returns a Printer ready to write to w.
99
-func PrinterTo(w io.Writer) Printer {
100
- return &printer{w}
101
-}
p2p/net2/mock/mock.go
deleted
-63
@@ -1,63 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
5
-
6
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7
-)
8
-
9
-var log = eventlog.Logger("mocknet")
10
-
11
-// WithNPeers constructs a Mocknet with N peers.
12
-func WithNPeers(ctx context.Context, n int) (Mocknet, error) {
13
- m := New(ctx)
14
- for i := 0; i < n; i++ {
15
- if _, err := m.GenPeer(); err != nil {
16
- return nil, err
17
- }
18
- }
19
- return m, nil
20
-}
21
-
22
-// FullMeshLinked constructs a Mocknet with full mesh of Links.
23
-// This means that all the peers **can** connect to each other
24
-// (not that they already are connected. you can use m.ConnectAll())
25
-func FullMeshLinked(ctx context.Context, n int) (Mocknet, error) {
26
- m, err := WithNPeers(ctx, n)
27
- if err != nil {
28
- return nil, err
29
- }
30
-
31
- nets := m.Nets()
32
- for _, n1 := range nets {
33
- for _, n2 := range nets {
34
- // yes, even self.
35
- if _, err := m.LinkNets(n1, n2); err != nil {
36
- return nil, err
37
- }
38
- }
39
- }
40
-
41
- return m, nil
42
-}
43
-
44
-// FullMeshConnected constructs a Mocknet with full mesh of Connections.
45
-// This means that all the peers have dialed and are ready to talk to
46
-// each other.
47
-func FullMeshConnected(ctx context.Context, n int) (Mocknet, error) {
48
- m, err := FullMeshLinked(ctx, n)
49
- if err != nil {
50
- return nil, err
51
- }
52
-
53
- nets := m.Nets()
54
- for _, n1 := range nets {
55
- for _, n2 := range nets {
56
- if _, err := m.ConnectNets(n1, n2); err != nil {
57
- return nil, err
58
- }
59
- }
60
- }
61
-
62
- return m, nil
63
-}
p2p/net2/mock/mock_conn.go
deleted
-120
@@ -1,120 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "container/list"
5
- "sync"
6
-
7
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
8
- inet "github.com/jbenet/go-ipfs/p2p/net2"
9
- peer "github.com/jbenet/go-ipfs/p2p/peer"
10
-
11
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12
-)
13
-
14
-// conn represents one side's perspective of a
15
-// live connection between two peers.
16
-// it goes over a particular link.
17
-type conn struct {
18
- local peer.ID
19
- remote peer.ID
20
-
21
- localAddr ma.Multiaddr
22
- remoteAddr ma.Multiaddr
23
-
24
- localPrivKey ic.PrivKey
25
- remotePubKey ic.PubKey
26
-
27
- net *peernet
28
- link *link
29
- rconn *conn // counterpart
30
- streams list.List
31
-
32
- sync.RWMutex
33
-}
34
-
35
-func (c *conn) Close() error {
36
- for _, s := range c.allStreams() {
37
- s.Close()
38
- }
39
- c.net.removeConn(c)
40
- return nil
41
-}
42
-
43
-func (c *conn) addStream(s *stream) {
44
- c.Lock()
45
- s.conn = c
46
- c.streams.PushBack(s)
47
- c.Unlock()
48
-}
49
-
50
-func (c *conn) removeStream(s *stream) {
51
- c.Lock()
52
- defer c.Unlock()
53
- for e := c.streams.Front(); e != nil; e = e.Next() {
54
- if s == e.Value {
55
- c.streams.Remove(e)
56
- return
57
- }
58
- }
59
-}
60
-
61
-func (c *conn) allStreams() []inet.Stream {
62
- c.RLock()
63
- defer c.RUnlock()
64
-
65
- strs := make([]inet.Stream, 0, c.streams.Len())
66
- for e := c.streams.Front(); e != nil; e = e.Next() {
67
- s := e.Value.(*stream)
68
- strs = append(strs, s)
69
- }
70
- return strs
71
-}
72
-
73
-func (c *conn) remoteOpenedStream(s *stream) {
74
- c.addStream(s)
75
- c.net.handleNewStream(s)
76
-}
77
-
78
-func (c *conn) openStream() *stream {
79
- sl, sr := c.link.newStreamPair()
80
- c.addStream(sl)
81
- c.rconn.remoteOpenedStream(sr)
82
- return sl
83
-}
84
-
85
-func (c *conn) NewStream() (inet.Stream, error) {
86
- log.Debugf("Conn.NewStreamWithProtocol: %s --> %s", c.local, c.remote)
87
-
88
- s := c.openStream()
89
- return s, nil
90
-}
91
-
92
-// LocalMultiaddr is the Multiaddr on this side
93
-func (c *conn) LocalMultiaddr() ma.Multiaddr {
94
- return c.localAddr
95
-}
96
-
97
-// LocalPeer is the Peer on our side of the connection
98
-func (c *conn) LocalPeer() peer.ID {
99
- return c.local
100
-}
101
-
102
-// LocalPrivateKey is the private key of the peer on our side.
103
-func (c *conn) LocalPrivateKey() ic.PrivKey {
104
- return c.localPrivKey
105
-}
106
-
107
-// RemoteMultiaddr is the Multiaddr on the remote side
108
-func (c *conn) RemoteMultiaddr() ma.Multiaddr {
109
- return c.remoteAddr
110
-}
111
-
112
-// RemotePeer is the Peer on the remote side
113
-func (c *conn) RemotePeer() peer.ID {
114
- return c.remote
115
-}
116
-
117
-// RemotePublicKey is the private key of the peer on our side.
118
-func (c *conn) RemotePublicKey() ic.PubKey {
119
- return c.remotePubKey
120
-}
p2p/net2/mock/mock_link.go
deleted
-93
@@ -1,93 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "io"
5
- "sync"
6
-
7
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
- peer "github.com/jbenet/go-ipfs/p2p/peer"
9
-)
10
-
11
-// link implements mocknet.Link
12
-// and, for simplicity, inet.Conn
13
-type link struct {
14
- mock *mocknet
15
- nets []*peernet
16
- opts LinkOptions
17
-
18
- // this could have addresses on both sides.
19
-
20
- sync.RWMutex
21
-}
22
-
23
-func newLink(mn *mocknet, opts LinkOptions) *link {
24
- return &link{mock: mn, opts: opts}
25
-}
26
-
27
-func (l *link) newConnPair(dialer *peernet) (*conn, *conn) {
28
- l.RLock()
29
- defer l.RUnlock()
30
-
31
- mkconn := func(ln, rn *peernet) *conn {
32
- c := &conn{net: ln, link: l}
33
- c.local = ln.peer
34
- c.remote = rn.peer
35
-
36
- c.localAddr = ln.ps.Addresses(ln.peer)[0]
37
- c.remoteAddr = rn.ps.Addresses(rn.peer)[0]
38
-
39
- c.localPrivKey = ln.ps.PrivKey(ln.peer)
40
- c.remotePubKey = rn.ps.PubKey(rn.peer)
41
-
42
- return c
43
- }
44
-
45
- c1 := mkconn(l.nets[0], l.nets[1])
46
- c2 := mkconn(l.nets[1], l.nets[0])
47
- c1.rconn = c2
48
- c2.rconn = c1
49
-
50
- if dialer == c1.net {
51
- return c1, c2
52
- }
53
- return c2, c1
54
-}
55
-
56
-func (l *link) newStreamPair() (*stream, *stream) {
57
- r1, w1 := io.Pipe()
58
- r2, w2 := io.Pipe()
59
-
60
- s1 := &stream{Reader: r1, Writer: w2}
61
- s2 := &stream{Reader: r2, Writer: w1}
62
- return s1, s2
63
-}
64
-
65
-func (l *link) Networks() []inet.Network {
66
- l.RLock()
67
- defer l.RUnlock()
68
-
69
- cp := make([]inet.Network, len(l.nets))
70
- for i, n := range l.nets {
71
- cp[i] = n
72
- }
73
- return cp
74
-}
75
-
76
-func (l *link) Peers() []peer.ID {
77
- l.RLock()
78
- defer l.RUnlock()
79
-
80
- cp := make([]peer.ID, len(l.nets))
81
- for i, n := range l.nets {
82
- cp[i] = n.peer
83
- }
84
- return cp
85
-}
86
-
87
-func (l *link) SetOptions(o LinkOptions) {
88
- l.opts = o
89
-}
90
-
91
-func (l *link) Options() LinkOptions {
92
- return l.opts
93
-}
p2p/net2/mock/mock_net.go
deleted
-340
@@ -1,340 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "fmt"
5
- "sync"
6
-
7
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
8
- host "github.com/jbenet/go-ipfs/p2p/host"
9
- bhost "github.com/jbenet/go-ipfs/p2p/host/basic"
10
- inet "github.com/jbenet/go-ipfs/p2p/net2"
11
- peer "github.com/jbenet/go-ipfs/p2p/peer"
12
- testutil "github.com/jbenet/go-ipfs/util/testutil"
13
-
14
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
15
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
16
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
17
-)
18
-
19
-// mocknet implements mocknet.Mocknet
20
-type mocknet struct {
21
- nets map[peer.ID]*peernet
22
- hosts map[peer.ID]*bhost.BasicHost
23
-
24
- // links make it possible to connect two peers.
25
- // think of links as the physical medium.
26
- // usually only one, but there could be multiple
27
- // **links are shared between peers**
28
- links map[peer.ID]map[peer.ID]map[*link]struct{}
29
-
30
- linkDefaults LinkOptions
31
-
32
- cg ctxgroup.ContextGroup // for Context closing
33
- sync.RWMutex
34
-}
35
-
36
-func New(ctx context.Context) Mocknet {
37
- return &mocknet{
38
- nets: map[peer.ID]*peernet{},
39
- hosts: map[peer.ID]*bhost.BasicHost{},
40
- links: map[peer.ID]map[peer.ID]map[*link]struct{}{},
41
- cg: ctxgroup.WithContext(ctx),
42
- }
43
-}
44
-
45
-func (mn *mocknet) GenPeer() (host.Host, error) {
46
- sk, _, err := testutil.RandKeyPair(512)
47
- if err != nil {
48
- return nil, err
49
- }
50
-
51
- a := testutil.RandLocalTCPAddress()
52
-
53
- h, err := mn.AddPeer(sk, a)
54
- if err != nil {
55
- return nil, err
56
- }
57
-
58
- return h, nil
59
-}
60
-
61
-func (mn *mocknet) AddPeer(k ic.PrivKey, a ma.Multiaddr) (host.Host, error) {
62
- n, err := newPeernet(mn.cg.Context(), mn, k, a)
63
- if err != nil {
64
- return nil, err
65
- }
66
-
67
- h := bhost.New(n)
68
-
69
- // make sure to add listening address!
70
- // this makes debugging things simpler as remembering to register
71
- // an address may cause unexpected failure.
72
- n.Peerstore().AddAddress(n.LocalPeer(), a)
73
- log.Debugf("mocknet added listen addr for peer: %s -- %s", n.LocalPeer(), a)
74
-
75
- mn.cg.AddChildGroup(n.cg)
76
-
77
- mn.Lock()
78
- mn.nets[n.peer] = n
79
- mn.hosts[n.peer] = h
80
- mn.Unlock()
81
- return h, nil
82
-}
83
-
84
-func (mn *mocknet) Peers() []peer.ID {
85
- mn.RLock()
86
- defer mn.RUnlock()
87
-
88
- cp := make([]peer.ID, 0, len(mn.nets))
89
- for _, n := range mn.nets {
90
- cp = append(cp, n.peer)
91
- }
92
- return cp
93
-}
94
-
95
-func (mn *mocknet) Host(pid peer.ID) host.Host {
96
- mn.RLock()
97
- host := mn.hosts[pid]
98
- mn.RUnlock()
99
- return host
100
-}
101
-
102
-func (mn *mocknet) Net(pid peer.ID) inet.Network {
103
- mn.RLock()
104
- n := mn.nets[pid]
105
- mn.RUnlock()
106
- return n
107
-}
108
-
109
-func (mn *mocknet) Hosts() []host.Host {
110
- mn.RLock()
111
- defer mn.RUnlock()
112
-
113
- cp := make([]host.Host, 0, len(mn.hosts))
114
- for _, h := range mn.hosts {
115
- cp = append(cp, h)
116
- }
117
- return cp
118
-}
119
-
120
-func (mn *mocknet) Nets() []inet.Network {
121
- mn.RLock()
122
- defer mn.RUnlock()
123
-
124
- cp := make([]inet.Network, 0, len(mn.nets))
125
- for _, n := range mn.nets {
126
- cp = append(cp, n)
127
- }
128
- return cp
129
-}
130
-
131
-// Links returns a copy of the internal link state map.
132
-// (wow, much map. so data structure. how compose. ahhh pointer)
133
-func (mn *mocknet) Links() LinkMap {
134
- mn.RLock()
135
- defer mn.RUnlock()
136
-
137
- links := map[string]map[string]map[Link]struct{}{}
138
- for p1, lm := range mn.links {
139
- sp1 := string(p1)
140
- links[sp1] = map[string]map[Link]struct{}{}
141
- for p2, ls := range lm {
142
- sp2 := string(p2)
143
- links[sp1][sp2] = map[Link]struct{}{}
144
- for l := range ls {
145
- links[sp1][sp2][l] = struct{}{}
146
- }
147
- }
148
- }
149
- return links
150
-}
151
-
152
-func (mn *mocknet) LinkAll() error {
153
- nets := mn.Nets()
154
- for _, n1 := range nets {
155
- for _, n2 := range nets {
156
- if _, err := mn.LinkNets(n1, n2); err != nil {
157
- return err
158
- }
159
- }
160
- }
161
- return nil
162
-}
163
-
164
-func (mn *mocknet) LinkPeers(p1, p2 peer.ID) (Link, error) {
165
- mn.RLock()
166
- n1 := mn.nets[p1]
167
- n2 := mn.nets[p2]
168
- mn.RUnlock()
169
-
170
- if n1 == nil {
171
- return nil, fmt.Errorf("network for p1 not in mocknet")
172
- }
173
-
174
- if n2 == nil {
175
- return nil, fmt.Errorf("network for p2 not in mocknet")
176
- }
177
-
178
- return mn.LinkNets(n1, n2)
179
-}
180
-
181
-func (mn *mocknet) validate(n inet.Network) (*peernet, error) {
182
- // WARNING: assumes locks acquired
183
-
184
- nr, ok := n.(*peernet)
185
- if !ok {
186
- return nil, fmt.Errorf("Network not supported (use mock package nets only)")
187
- }
188
-
189
- if _, found := mn.nets[nr.peer]; !found {
190
- return nil, fmt.Errorf("Network not on mocknet. is it from another mocknet?")
191
- }
192
-
193
- return nr, nil
194
-}
195
-
196
-func (mn *mocknet) LinkNets(n1, n2 inet.Network) (Link, error) {
197
- mn.RLock()
198
- n1r, err1 := mn.validate(n1)
199
- n2r, err2 := mn.validate(n2)
200
- ld := mn.linkDefaults
201
- mn.RUnlock()
202
-
203
- if err1 != nil {
204
- return nil, err1
205
- }
206
- if err2 != nil {
207
- return nil, err2
208
- }
209
-
210
- l := newLink(mn, ld)
211
- l.nets = append(l.nets, n1r, n2r)
212
- mn.addLink(l)
213
- return l, nil
214
-}
215
-
216
-func (mn *mocknet) Unlink(l2 Link) error {
217
-
218
- l, ok := l2.(*link)
219
- if !ok {
220
- return fmt.Errorf("only links from mocknet are supported")
221
- }
222
-
223
- mn.removeLink(l)
224
- return nil
225
-}
226
-
227
-func (mn *mocknet) UnlinkPeers(p1, p2 peer.ID) error {
228
- ls := mn.LinksBetweenPeers(p1, p2)
229
- if ls == nil {
230
- return fmt.Errorf("no link between p1 and p2")
231
- }
232
-
233
- for _, l := range ls {
234
- if err := mn.Unlink(l); err != nil {
235
- return err
236
- }
237
- }
238
- return nil
239
-}
240
-
241
-func (mn *mocknet) UnlinkNets(n1, n2 inet.Network) error {
242
- return mn.UnlinkPeers(n1.LocalPeer(), n2.LocalPeer())
243
-}
244
-
245
-// get from the links map. and lazily contruct.
246
-func (mn *mocknet) linksMapGet(p1, p2 peer.ID) *map[*link]struct{} {
247
-
248
- l1, found := mn.links[p1]
249
- if !found {
250
- mn.links[p1] = map[peer.ID]map[*link]struct{}{}
251
- l1 = mn.links[p1] // so we make sure it's there.
252
- }
253
-
254
- l2, found := l1[p2]
255
- if !found {
256
- m := map[*link]struct{}{}
257
- l1[p2] = m
258
- l2 = l1[p2]
259
- }
260
-
261
- return &l2
262
-}
263
-
264
-func (mn *mocknet) addLink(l *link) {
265
- mn.Lock()
266
- defer mn.Unlock()
267
-
268
- n1, n2 := l.nets[0], l.nets[1]
269
- (*mn.linksMapGet(n1.peer, n2.peer))[l] = struct{}{}
270
- (*mn.linksMapGet(n2.peer, n1.peer))[l] = struct{}{}
271
-}
272
-
273
-func (mn *mocknet) removeLink(l *link) {
274
- mn.Lock()
275
- defer mn.Unlock()
276
-
277
- n1, n2 := l.nets[0], l.nets[1]
278
- delete(*mn.linksMapGet(n1.peer, n2.peer), l)
279
- delete(*mn.linksMapGet(n2.peer, n1.peer), l)
280
-}
281
-
282
-func (mn *mocknet) ConnectAll() error {
283
- nets := mn.Nets()
284
- for _, n1 := range nets {
285
- for _, n2 := range nets {
286
- if n1 == n2 {
287
- continue
288
- }
289
-
290
- if _, err := mn.ConnectNets(n1, n2); err != nil {
291
- return err
292
- }
293
- }
294
- }
295
- return nil
296
-}
297
-
298
-func (mn *mocknet) ConnectPeers(a, b peer.ID) (inet.Conn, error) {
299
- return mn.Net(a).DialPeer(mn.cg.Context(), b)
300
-}
301
-
302
-func (mn *mocknet) ConnectNets(a, b inet.Network) (inet.Conn, error) {
303
- return a.DialPeer(mn.cg.Context(), b.LocalPeer())
304
-}
305
-
306
-func (mn *mocknet) DisconnectPeers(p1, p2 peer.ID) error {
307
- return mn.Net(p1).ClosePeer(p2)
308
-}
309
-
310
-func (mn *mocknet) DisconnectNets(n1, n2 inet.Network) error {
311
- return n1.ClosePeer(n2.LocalPeer())
312
-}
313
-
314
-func (mn *mocknet) LinksBetweenPeers(p1, p2 peer.ID) []Link {
315
- mn.RLock()
316
- defer mn.RUnlock()
317
-
318
- ls2 := *mn.linksMapGet(p1, p2)
319
- cp := make([]Link, 0, len(ls2))
320
- for l := range ls2 {
321
- cp = append(cp, l)
322
- }
323
- return cp
324
-}
325
-
326
-func (mn *mocknet) LinksBetweenNets(n1, n2 inet.Network) []Link {
327
- return mn.LinksBetweenPeers(n1.LocalPeer(), n2.LocalPeer())
328
-}
329
-
330
-func (mn *mocknet) SetLinkDefaults(o LinkOptions) {
331
- mn.Lock()
332
- mn.linkDefaults = o
333
- mn.Unlock()
334
-}
335
-
336
-func (mn *mocknet) LinkDefaults() LinkOptions {
337
- mn.RLock()
338
- defer mn.RUnlock()
339
- return mn.linkDefaults
340
-}
p2p/net2/mock/mock_peernet.go
deleted
-353
@@ -1,353 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "fmt"
5
- "math/rand"
6
- "sync"
7
-
8
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
9
- inet "github.com/jbenet/go-ipfs/p2p/net2"
10
- peer "github.com/jbenet/go-ipfs/p2p/peer"
11
-
12
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
13
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
14
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
15
-)
16
-
17
-// peernet implements inet.Network
18
-type peernet struct {
19
- mocknet *mocknet // parent
20
-
21
- peer peer.ID
22
- ps peer.Peerstore
23
-
24
- // conns are actual live connections between peers.
25
- // many conns could run over each link.
26
- // **conns are NOT shared between peers**
27
- connsByPeer map[peer.ID]map[*conn]struct{}
28
- connsByLink map[*link]map[*conn]struct{}
29
-
30
- // implement inet.Network
31
- streamHandler inet.StreamHandler
32
- connHandler inet.ConnHandler
33
-
34
- cg ctxgroup.ContextGroup
35
- sync.RWMutex
36
-}
37
-
38
-// newPeernet constructs a new peernet
39
-func newPeernet(ctx context.Context, m *mocknet, k ic.PrivKey,
40
- a ma.Multiaddr) (*peernet, error) {
41
-
42
- p, err := peer.IDFromPublicKey(k.GetPublic())
43
- if err != nil {
44
- return nil, err
45
- }
46
-
47
- // create our own entirely, so that peers knowledge doesn't get shared
48
- ps := peer.NewPeerstore()
49
- ps.AddAddress(p, a)
50
- ps.AddPrivKey(p, k)
51
- ps.AddPubKey(p, k.GetPublic())
52
-
53
- n := &peernet{
54
- mocknet: m,
55
- peer: p,
56
- ps: ps,
57
- cg: ctxgroup.WithContext(ctx),
58
-
59
- connsByPeer: map[peer.ID]map[*conn]struct{}{},
60
- connsByLink: map[*link]map[*conn]struct{}{},
61
- }
62
-
63
- n.cg.SetTeardown(n.teardown)
64
- return n, nil
65
-}
66
-
67
-func (pn *peernet) teardown() error {
68
-
69
- // close the connections
70
- for _, c := range pn.allConns() {
71
- c.Close()
72
- }
73
- return nil
74
-}
75
-
76
-// allConns returns all the connections between this peer and others
77
-func (pn *peernet) allConns() []*conn {
78
- pn.RLock()
79
- var cs []*conn
80
- for _, csl := range pn.connsByPeer {
81
- for c := range csl {
82
- cs = append(cs, c)
83
- }
84
- }
85
- pn.RUnlock()
86
- return cs
87
-}
88
-
89
-// Close calls the ContextCloser func
90
-func (pn *peernet) Close() error {
91
- return pn.cg.Close()
92
-}
93
-
94
-func (pn *peernet) Peerstore() peer.Peerstore {
95
- return pn.ps
96
-}
97
-
98
-func (pn *peernet) String() string {
99
- return fmt.Sprintf("<mock.peernet %s - %d conns>", pn.peer, len(pn.allConns()))
100
-}
101
-
102
-// handleNewStream is an internal function to trigger the client's handler
103
-func (pn *peernet) handleNewStream(s inet.Stream) {
104
- pn.RLock()
105
- handler := pn.streamHandler
106
- pn.RUnlock()
107
- if handler != nil {
108
- go handler(s)
109
- }
110
-}
111
-
112
-// handleNewConn is an internal function to trigger the client's handler
113
-func (pn *peernet) handleNewConn(c inet.Conn) {
114
- pn.RLock()
115
- handler := pn.connHandler
116
- pn.RUnlock()
117
- if handler != nil {
118
- go handler(c)
119
- }
120
-}
121
-
122
-// DialPeer attempts to establish a connection to a given peer.
123
-// Respects the context.
124
-func (pn *peernet) DialPeer(ctx context.Context, p peer.ID) (inet.Conn, error) {
125
- return pn.connect(p)
126
-}
127
-
128
-func (pn *peernet) connect(p peer.ID) (*conn, error) {
129
- // first, check if we already have live connections
130
- pn.RLock()
131
- cs, found := pn.connsByPeer[p]
132
- pn.RUnlock()
133
- if found && len(cs) > 0 {
134
- for c := range cs {
135
- return c, nil
136
- }
137
- }
138
-
139
- log.Debugf("%s (newly) dialing %s", pn.peer, p)
140
-
141
- // ok, must create a new connection. we need a link
142
- links := pn.mocknet.LinksBetweenPeers(pn.peer, p)
143
- if len(links) < 1 {
144
- return nil, fmt.Errorf("%s cannot connect to %s", pn.peer, p)
145
- }
146
-
147
- // if many links found, how do we select? for now, randomly...
148
- // this would be an interesting place to test logic that can measure
149
- // links (network interfaces) and select properly
150
- l := links[rand.Intn(len(links))]
151
-
152
- log.Debugf("%s dialing %s openingConn", pn.peer, p)
153
- // create a new connection with link
154
- c := pn.openConn(p, l.(*link))
155
- return c, nil
156
-}
157
-
158
-func (pn *peernet) openConn(r peer.ID, l *link) *conn {
159
- lc, rc := l.newConnPair(pn)
160
- log.Debugf("%s opening connection to %s", pn.LocalPeer(), lc.RemotePeer())
161
- pn.addConn(lc)
162
- rc.net.remoteOpenedConn(rc)
163
- return lc
164
-}
165
-
166
-func (pn *peernet) remoteOpenedConn(c *conn) {
167
- log.Debugf("%s accepting connection from %s", pn.LocalPeer(), c.RemotePeer())
168
- pn.addConn(c)
169
- pn.handleNewConn(c)
170
-}
171
-
172
-// addConn constructs and adds a connection
173
-// to given remote peer over given link
174
-func (pn *peernet) addConn(c *conn) {
175
- pn.Lock()
176
- defer pn.Unlock()
177
-
178
- cs, found := pn.connsByPeer[c.RemotePeer()]
179
- if !found {
180
- cs = map[*conn]struct{}{}
181
- pn.connsByPeer[c.RemotePeer()] = cs
182
- }
183
- pn.connsByPeer[c.RemotePeer()][c] = struct{}{}
184
-
185
- cs, found = pn.connsByLink[c.link]
186
- if !found {
187
- cs = map[*conn]struct{}{}
188
- pn.connsByLink[c.link] = cs
189
- }
190
- pn.connsByLink[c.link][c] = struct{}{}
191
-}
192
-
193
-// removeConn removes a given conn
194
-func (pn *peernet) removeConn(c *conn) {
195
- pn.Lock()
196
- defer pn.Unlock()
197
-
198
- cs, found := pn.connsByLink[c.link]
199
- if !found || len(cs) < 1 {
200
- panic("attempting to remove a conn that doesnt exist")
201
- }
202
- delete(cs, c)
203
-
204
- cs, found = pn.connsByPeer[c.remote]
205
- if !found {
206
- panic("attempting to remove a conn that doesnt exist")
207
- }
208
- delete(cs, c)
209
-}
210
-
211
-// CtxGroup returns the network's ContextGroup
212
-func (pn *peernet) CtxGroup() ctxgroup.ContextGroup {
213
- return pn.cg
214
-}
215
-
216
-// LocalPeer the network's LocalPeer
217
-func (pn *peernet) LocalPeer() peer.ID {
218
- return pn.peer
219
-}
220
-
221
-// Peers returns the connected peers
222
-func (pn *peernet) Peers() []peer.ID {
223
- pn.RLock()
224
- defer pn.RUnlock()
225
-
226
- peers := make([]peer.ID, 0, len(pn.connsByPeer))
227
- for _, cs := range pn.connsByPeer {
228
- for c := range cs {
229
- peers = append(peers, c.remote)
230
- break
231
- }
232
- }
233
- return peers
234
-}
235
-
236
-// Conns returns all the connections of this peer
237
-func (pn *peernet) Conns() []inet.Conn {
238
- pn.RLock()
239
- defer pn.RUnlock()
240
-
241
- out := make([]inet.Conn, 0, len(pn.connsByPeer))
242
- for _, cs := range pn.connsByPeer {
243
- for c := range cs {
244
- out = append(out, c)
245
- }
246
- }
247
- return out
248
-}
249
-
250
-func (pn *peernet) ConnsToPeer(p peer.ID) []inet.Conn {
251
- pn.RLock()
252
- defer pn.RUnlock()
253
-
254
- cs, found := pn.connsByPeer[p]
255
- if !found || len(cs) == 0 {
256
- return nil
257
- }
258
-
259
- var cs2 []inet.Conn
260
- for c := range cs {
261
- cs2 = append(cs2, c)
262
- }
263
- return cs2
264
-}
265
-
266
-// ClosePeer connections to peer
267
-func (pn *peernet) ClosePeer(p peer.ID) error {
268
- pn.RLock()
269
- cs, found := pn.connsByPeer[p]
270
- pn.RUnlock()
271
- if !found {
272
- return nil
273
- }
274
-
275
- for c := range cs {
276
- c.Close()
277
- }
278
- return nil
279
-}
280
-
281
-// BandwidthTotals returns the total amount of bandwidth transferred
282
-func (pn *peernet) BandwidthTotals() (in uint64, out uint64) {
283
- // need to implement this. probably best to do it in swarm this time.
284
- // need a "metrics" object
285
- return 0, 0
286
-}
287
-
288
-// ListenAddresses returns a list of addresses at which this network listens.
289
-func (pn *peernet) ListenAddresses() []ma.Multiaddr {
290
- return pn.Peerstore().Addresses(pn.LocalPeer())
291
-}
292
-
293
-// InterfaceListenAddresses returns a list of addresses at which this network
294
-// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
295
-// use the known local interfaces.
296
-func (pn *peernet) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
297
- return pn.ListenAddresses(), nil
298
-}
299
-
300
-// Connectedness returns a state signaling connection capabilities
301
-// For now only returns Connecter || NotConnected. Expand into more later.
302
-func (pn *peernet) Connectedness(p peer.ID) inet.Connectedness {
303
- pn.Lock()
304
- defer pn.Unlock()
305
-
306
- cs, found := pn.connsByPeer[p]
307
- if found && len(cs) > 0 {
308
- return inet.Connected
309
- }
310
- return inet.NotConnected
311
-}
312
-
313
-// NewStream returns a new stream to given peer p.
314
-// If there is no connection to p, attempts to create one.
315
-func (pn *peernet) NewStream(p peer.ID) (inet.Stream, error) {
316
- pn.Lock()
317
- cs, found := pn.connsByPeer[p]
318
- if !found || len(cs) < 1 {
319
- pn.Unlock()
320
- return nil, fmt.Errorf("no connection to peer")
321
- }
322
- pn.Unlock()
323
-
324
- // if many conns are found, how do we select? for now, randomly...
325
- // this would be an interesting place to test logic that can measure
326
- // links (network interfaces) and select properly
327
- n := rand.Intn(len(cs))
328
- var c *conn
329
- for c = range cs {
330
- if n == 0 {
331
- break
332
- }
333
- n--
334
- }
335
-
336
- return c.NewStream()
337
-}
338
-
339
-// SetStreamHandler sets the new stream handler on the Network.
340
-// This operation is threadsafe.
341
-func (pn *peernet) SetStreamHandler(h inet.StreamHandler) {
342
- pn.Lock()
343
- pn.streamHandler = h
344
- pn.Unlock()
345
-}
346
-
347
-// SetConnHandler sets the new conn handler on the Network.
348
-// This operation is threadsafe.
349
-func (pn *peernet) SetConnHandler(h inet.ConnHandler) {
350
- pn.Lock()
351
- pn.connHandler = h
352
- pn.Unlock()
353
-}
p2p/net2/mock/mock_printer.go
deleted
-36
@@ -1,36 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "fmt"
5
- "io"
6
-
7
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
- peer "github.com/jbenet/go-ipfs/p2p/peer"
9
-)
10
-
11
-// separate object so our interfaces are separate :)
12
-type printer struct {
13
- w io.Writer
14
-}
15
-
16
-func (p *printer) MocknetLinks(mn Mocknet) {
17
- links := mn.Links()
18
-
19
- fmt.Fprintf(p.w, "Mocknet link map:\n")
20
- for p1, lm := range links {
21
- fmt.Fprintf(p.w, "\t%s linked to:\n", peer.ID(p1))
22
- for p2, l := range lm {
23
- fmt.Fprintf(p.w, "\t\t%s (%d links)\n", peer.ID(p2), len(l))
24
- }
25
- }
26
- fmt.Fprintf(p.w, "\n")
27
-}
28
-
29
-func (p *printer) NetworkConns(ni inet.Network) {
30
-
31
- fmt.Fprintf(p.w, "%s connected to:\n", ni.LocalPeer())
32
- for _, c := range ni.Conns() {
33
- fmt.Fprintf(p.w, "\t%s (addr: %s)\n", c.RemotePeer(), c.RemoteMultiaddr())
34
- }
35
- fmt.Fprintf(p.w, "\n")
36
-}
p2p/net2/mock/mock_stream.go
deleted
-29
@@ -1,29 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "io"
5
-
6
- inet "github.com/jbenet/go-ipfs/p2p/net2"
7
-)
8
-
9
-// stream implements inet.Stream
10
-type stream struct {
11
- io.Reader
12
- io.Writer
13
- conn *conn
14
-}
15
-
16
-func (s *stream) Close() error {
17
- s.conn.removeStream(s)
18
- if r, ok := (s.Reader).(io.Closer); ok {
19
- r.Close()
20
- }
21
- if w, ok := (s.Writer).(io.Closer); ok {
22
- return w.Close()
23
- }
24
- return nil
25
-}
26
-
27
-func (s *stream) Conn() inet.Conn {
28
- return s.conn
29
-}
p2p/net2/mock/mock_test.go
deleted
-475
@@ -1,475 +0,0 @@
1
-package mocknet
2
-
3
-import (
4
- "bytes"
5
- "io"
6
- "math/rand"
7
- "sync"
8
- "testing"
9
-
10
- inet "github.com/jbenet/go-ipfs/p2p/net2"
11
- peer "github.com/jbenet/go-ipfs/p2p/peer"
12
- protocol "github.com/jbenet/go-ipfs/p2p/protocol"
13
- testutil "github.com/jbenet/go-ipfs/util/testutil"
14
-
15
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
16
-)
17
-
18
-func randPeer(t *testing.T) peer.ID {
19
- p, err := testutil.RandPeerID()
20
- if err != nil {
21
- t.Fatal(err)
22
- }
23
- return p
24
-}
25
-
26
-func TestNetworkSetup(t *testing.T) {
27
-
28
- ctx := context.Background()
29
- sk1, _, err := testutil.RandKeyPair(512)
30
- if err != nil {
31
- t.Fatal(t)
32
- }
33
- sk2, _, err := testutil.RandKeyPair(512)
34
- if err != nil {
35
- t.Fatal(t)
36
- }
37
- sk3, _, err := testutil.RandKeyPair(512)
38
- if err != nil {
39
- t.Fatal(t)
40
- }
41
- mn := New(ctx)
42
- // peers := []peer.ID{p1, p2, p3}
43
-
44
- // add peers to mock net
45
-
46
- a1 := testutil.RandLocalTCPAddress()
47
- a2 := testutil.RandLocalTCPAddress()
48
- a3 := testutil.RandLocalTCPAddress()
49
-
50
- h1, err := mn.AddPeer(sk1, a1)
51
- if err != nil {
52
- t.Fatal(err)
53
- }
54
- p1 := h1.ID()
55
-
56
- h2, err := mn.AddPeer(sk2, a2)
57
- if err != nil {
58
- t.Fatal(err)
59
- }
60
- p2 := h2.ID()
61
-
62
- h3, err := mn.AddPeer(sk3, a3)
63
- if err != nil {
64
- t.Fatal(err)
65
- }
66
- p3 := h3.ID()
67
-
68
- // check peers and net
69
- if mn.Host(p1) != h1 {
70
- t.Error("host for p1.ID != h1")
71
- }
72
- if mn.Host(p2) != h2 {
73
- t.Error("host for p2.ID != h2")
74
- }
75
- if mn.Host(p3) != h3 {
76
- t.Error("host for p3.ID != h3")
77
- }
78
-
79
- n1 := h1.Network()
80
- if mn.Net(p1) != n1 {
81
- t.Error("net for p1.ID != n1")
82
- }
83
- n2 := h2.Network()
84
- if mn.Net(p2) != n2 {
85
- t.Error("net for p2.ID != n1")
86
- }
87
- n3 := h3.Network()
88
- if mn.Net(p3) != n3 {
89
- t.Error("net for p3.ID != n1")
90
- }
91
-
92
- // link p1<-->p2, p1<-->p1, p2<-->p3, p3<-->p2
93
-
94
- l12, err := mn.LinkPeers(p1, p2)
95
- if err != nil {
96
- t.Fatal(err)
97
- }
98
- if !(l12.Networks()[0] == n1 && l12.Networks()[1] == n2) &&
99
- !(l12.Networks()[0] == n2 && l12.Networks()[1] == n1) {
100
- t.Error("l12 networks incorrect")
101
- }
102
-
103
- l11, err := mn.LinkPeers(p1, p1)
104
- if err != nil {
105
- t.Fatal(err)
106
- }
107
- if !(l11.Networks()[0] == n1 && l11.Networks()[1] == n1) {
108
- t.Error("l11 networks incorrect")
109
- }
110
-
111
- l23, err := mn.LinkPeers(p2, p3)
112
- if err != nil {
113
- t.Fatal(err)
114
- }
115
- if !(l23.Networks()[0] == n2 && l23.Networks()[1] == n3) &&
116
- !(l23.Networks()[0] == n3 && l23.Networks()[1] == n2) {
117
- t.Error("l23 networks incorrect")
118
- }
119
-
120
- l32, err := mn.LinkPeers(p3, p2)
121
- if err != nil {
122
- t.Fatal(err)
123
- }
124
- if !(l32.Networks()[0] == n2 && l32.Networks()[1] == n3) &&
125
- !(l32.Networks()[0] == n3 && l32.Networks()[1] == n2) {
126
- t.Error("l32 networks incorrect")
127
- }
128
-
129
- // check things
130
-
131
- links12 := mn.LinksBetweenPeers(p1, p2)
132
- if len(links12) != 1 {
133
- t.Errorf("should be 1 link bt. p1 and p2 (found %d)", len(links12))
134
- }
135
- if links12[0] != l12 {
136
- t.Error("links 1-2 should be l12.")
137
- }
138
-
139
- links11 := mn.LinksBetweenPeers(p1, p1)
140
- if len(links11) != 1 {
141
- t.Errorf("should be 1 link bt. p1 and p1 (found %d)", len(links11))
142
- }
143
- if links11[0] != l11 {
144
- t.Error("links 1-1 should be l11.")
145
- }
146
-
147
- links23 := mn.LinksBetweenPeers(p2, p3)
148
- if len(links23) != 2 {
149
- t.Errorf("should be 2 link bt. p2 and p3 (found %d)", len(links23))
150
- }
151
- if !((links23[0] == l23 && links23[1] == l32) ||
152
- (links23[0] == l32 && links23[1] == l23)) {
153
- t.Error("links 2-3 should be l23 and l32.")
154
- }
155
-
156
- // unlinking
157
-
158
- if err := mn.UnlinkPeers(p2, p1); err != nil {
159
- t.Error(err)
160
- }
161
-
162
- // check only one link affected:
163
-
164
- links12 = mn.LinksBetweenPeers(p1, p2)
165
- if len(links12) != 0 {
166
- t.Errorf("should be 0 now...", len(links12))
167
- }
168
-
169
- links11 = mn.LinksBetweenPeers(p1, p1)
170
- if len(links11) != 1 {
171
- t.Errorf("should be 1 link bt. p1 and p1 (found %d)", len(links11))
172
- }
173
- if links11[0] != l11 {
174
- t.Error("links 1-1 should be l11.")
175
- }
176
-
177
- links23 = mn.LinksBetweenPeers(p2, p3)
178
- if len(links23) != 2 {
179
- t.Errorf("should be 2 link bt. p2 and p3 (found %d)", len(links23))
180
- }
181
- if !((links23[0] == l23 && links23[1] == l32) ||
182
- (links23[0] == l32 && links23[1] == l23)) {
183
- t.Error("links 2-3 should be l23 and l32.")
184
- }
185
-
186
- // check connecting
187
-
188
- // first, no conns
189
- if len(n2.Conns()) > 0 || len(n3.Conns()) > 0 {
190
- t.Error("should have 0 conn. Got: (%d, %d)", len(n2.Conns()), len(n3.Conns()))
191
- }
192
-
193
- // connect p2->p3
194
- if _, err := n2.DialPeer(ctx, p3); err != nil {
195
- t.Error(err)
196
- }
197
-
198
- if len(n2.Conns()) != 1 || len(n3.Conns()) != 1 {
199
- t.Errorf("should have (1,1) conn. Got: (%d, %d)", len(n2.Conns()), len(n3.Conns()))
200
- }
201
-
202
- // p := PrinterTo(os.Stdout)
203
- // p.NetworkConns(n1)
204
- // p.NetworkConns(n2)
205
- // p.NetworkConns(n3)
206
-
207
- // can create a stream 2->3, 3->2,
208
- if _, err := n2.NewStream(p3); err != nil {
209
- t.Error(err)
210
- }
211
- if _, err := n3.NewStream(p2); err != nil {
212
- t.Error(err)
213
- }
214
-
215
- // but not 1->2 nor 2->2 (not linked), nor 1->1 (not connected)
216
- if _, err := n1.NewStream(p2); err == nil {
217
- t.Error("should not be able to connect")
218
- }
219
- if _, err := n2.NewStream(p2); err == nil {
220
- t.Error("should not be able to connect")
221
- }
222
- if _, err := n1.NewStream(p1); err == nil {
223
- t.Error("should not be able to connect")
224
- }
225
-
226
- // connect p1->p1 (should work)
227
- if _, err := n1.DialPeer(ctx, p1); err != nil {
228
- t.Error("p1 should be able to dial self.", err)
229
- }
230
-
231
- // and a stream too
232
- if _, err := n1.NewStream(p1); err != nil {
233
- t.Error(err)
234
- }
235
-
236
- // connect p1->p2
237
- if _, err := n1.DialPeer(ctx, p2); err == nil {
238
- t.Error("p1 should not be able to dial p2, not connected...")
239
- }
240
-
241
- // connect p3->p1
242
- if _, err := n3.DialPeer(ctx, p1); err == nil {
243
- t.Error("p3 should not be able to dial p1, not connected...")
244
- }
245
-
246
- // relink p1->p2
247
-
248
- l12, err = mn.LinkPeers(p1, p2)
249
- if err != nil {
250
- t.Fatal(err)
251
- }
252
- if !(l12.Networks()[0] == n1 && l12.Networks()[1] == n2) &&
253
- !(l12.Networks()[0] == n2 && l12.Networks()[1] == n1) {
254
- t.Error("l12 networks incorrect")
255
- }
256
-
257
- // should now be able to connect
258
-
259
- // connect p1->p2
260
- if _, err := n1.DialPeer(ctx, p2); err != nil {
261
- t.Error(err)
262
- }
263
-
264
- // and a stream should work now too :)
265
- if _, err := n2.NewStream(p3); err != nil {
266
- t.Error(err)
267
- }
268
-
269
-}
270
-
271
-func TestStreams(t *testing.T) {
272
-
273
- mn, err := FullMeshConnected(context.Background(), 3)
274
- if err != nil {
275
- t.Fatal(err)
276
- }
277
-
278
- handler := func(s inet.Stream) {
279
- b := make([]byte, 4)
280
- if _, err := io.ReadFull(s, b); err != nil {
281
- panic(err)
282
- }
283
- if !bytes.Equal(b, []byte("beep")) {
284
- panic("bytes mismatch")
285
- }
286
- if _, err := s.Write([]byte("boop")); err != nil {
287
- panic(err)
288
- }
289
- s.Close()
290
- }
291
-
292
- hosts := mn.Hosts()
293
- for _, h := range mn.Hosts() {
294
- h.SetStreamHandler(protocol.TestingID, handler)
295
- }
296
-
297
- s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID())
298
- if err != nil {
299
- t.Fatal(err)
300
- }
301
-
302
- if _, err := s.Write([]byte("beep")); err != nil {
303
- panic(err)
304
- }
305
- b := make([]byte, 4)
306
- if _, err := io.ReadFull(s, b); err != nil {
307
- panic(err)
308
- }
309
- if !bytes.Equal(b, []byte("boop")) {
310
- panic("bytes mismatch 2")
311
- }
312
-
313
-}
314
-
315
-func makePinger(st string, n int) func(inet.Stream) {
316
- return func(s inet.Stream) {
317
- go func() {
318
- defer s.Close()
319
-
320
- for i := 0; i < n; i++ {
321
- b := make([]byte, 4+len(st))
322
- if _, err := s.Write([]byte("ping" + st)); err != nil {
323
- panic(err)
324
- }
325
- if _, err := io.ReadFull(s, b); err != nil {
326
- panic(err)
327
- }
328
- if !bytes.Equal(b, []byte("pong"+st)) {
329
- panic("bytes mismatch")
330
- }
331
- }
332
- }()
333
- }
334
-}
335
-
336
-func makePonger(st string) func(inet.Stream) {
337
- return func(s inet.Stream) {
338
- go func() {
339
- defer s.Close()
340
-
341
- for {
342
- b := make([]byte, 4+len(st))
343
- if _, err := io.ReadFull(s, b); err != nil {
344
- if err == io.EOF {
345
- return
346
- }
347
- panic(err)
348
- }
349
- if !bytes.Equal(b, []byte("ping"+st)) {
350
- panic("bytes mismatch")
351
- }
352
- if _, err := s.Write([]byte("pong" + st)); err != nil {
353
- panic(err)
354
- }
355
- }
356
- }()
357
- }
358
-}
359
-
360
-func TestStreamsStress(t *testing.T) {
361
-
362
- mn, err := FullMeshConnected(context.Background(), 100)
363
- if err != nil {
364
- t.Fatal(err)
365
- }
366
-
367
- hosts := mn.Hosts()
368
- for _, h := range hosts {
369
- ponger := makePonger(string(protocol.TestingID))
370
- h.SetStreamHandler(protocol.TestingID, ponger)
371
- }
372
-
373
- var wg sync.WaitGroup
374
- for i := 0; i < 1000; i++ {
375
- wg.Add(1)
376
- go func(i int) {
377
- defer wg.Done()
378
- from := rand.Intn(len(hosts))
379
- to := rand.Intn(len(hosts))
380
- s, err := hosts[from].NewStream(protocol.TestingID, hosts[to].ID())
381
- if err != nil {
382
- log.Debugf("%d (%s) %d (%s)", from, hosts[from], to, hosts[to])
383
- panic(err)
384
- }
385
-
386
- log.Infof("%d start pinging", i)
387
- makePinger("pingpong", rand.Intn(100))(s)
388
- log.Infof("%d done pinging", i)
389
- }(i)
390
- }
391
-
392
- wg.Wait()
393
-}
394
-
395
-func TestAdding(t *testing.T) {
396
-
397
- mn := New(context.Background())
398
-
399
- peers := []peer.ID{}
400
- for i := 0; i < 3; i++ {
401
- sk, _, err := testutil.RandKeyPair(512)
402
- if err != nil {
403
- t.Fatal(err)
404
- }
405
-
406
- a := testutil.RandLocalTCPAddress()
407
- h, err := mn.AddPeer(sk, a)
408
- if err != nil {
409
- t.Fatal(err)
410
- }
411
-
412
- peers = append(peers, h.ID())
413
- }
414
-
415
- p1 := peers[0]
416
- p2 := peers[1]
417
-
418
- // link them
419
- for _, p1 := range peers {
420
- for _, p2 := range peers {
421
- if _, err := mn.LinkPeers(p1, p2); err != nil {
422
- t.Error(err)
423
- }
424
- }
425
- }
426
-
427
- // set the new stream handler on p2
428
- h2 := mn.Host(p2)
429
- if h2 == nil {
430
- t.Fatalf("no host for %s", p2)
431
- }
432
- h2.SetStreamHandler(protocol.TestingID, func(s inet.Stream) {
433
- defer s.Close()
434
-
435
- b := make([]byte, 4)
436
- if _, err := io.ReadFull(s, b); err != nil {
437
- panic(err)
438
- }
439
- if string(b) != "beep" {
440
- panic("did not beep!")
441
- }
442
-
443
- if _, err := s.Write([]byte("boop")); err != nil {
444
- panic(err)
445
- }
446
- })
447
-
448
- // connect p1 to p2
449
- if _, err := mn.ConnectPeers(p1, p2); err != nil {
450
- t.Fatal(err)
451
- }
452
-
453
- // talk to p2
454
- h1 := mn.Host(p1)
455
- if h1 == nil {
456
- t.Fatalf("no network for %s", p1)
457
- }
458
-
459
- s, err := h1.NewStream(protocol.TestingID, p2)
460
- if err != nil {
461
- t.Fatal(err)
462
- }
463
-
464
- if _, err := s.Write([]byte("beep")); err != nil {
465
- t.Error(err)
466
- }
467
- b := make([]byte, 4)
468
- if _, err := io.ReadFull(s, b); err != nil {
469
- t.Error(err)
470
- }
471
- if !bytes.Equal(b, []byte("boop")) {
472
- t.Error("bytes mismatch 2")
473
- }
474
-
475
-}
p2p/net2/swarm/addr.go
deleted
-124
@@ -1,124 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- conn "github.com/jbenet/go-ipfs/p2p/net/conn"
5
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
6
-
7
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9
- manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
10
-)
11
-
12
-// ListenAddresses returns a list of addresses at which this swarm listens.
13
-func (s *Swarm) ListenAddresses() []ma.Multiaddr {
14
- listeners := s.swarm.Listeners()
15
- addrs := make([]ma.Multiaddr, 0, len(listeners))
16
- for _, l := range listeners {
17
- if l2, ok := l.NetListener().(conn.Listener); ok {
18
- addrs = append(addrs, l2.Multiaddr())
19
- }
20
- }
21
- return addrs
22
-}
23
-
24
-// InterfaceListenAddresses returns a list of addresses at which this swarm
25
-// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
26
-// use the known local interfaces.
27
-func InterfaceListenAddresses(s *Swarm) ([]ma.Multiaddr, error) {
28
- return resolveUnspecifiedAddresses(s.ListenAddresses())
29
-}
30
-
31
-// resolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
32
-// use the known local interfaces.
33
-func resolveUnspecifiedAddresses(unspecifiedAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
34
- var outputAddrs []ma.Multiaddr
35
-
36
- // todo optimize: only fetch these if we have a "any" addr.
37
- ifaceAddrs, err := interfaceAddresses()
38
- if err != nil {
39
- return nil, err
40
- }
41
-
42
- for _, a := range unspecifiedAddrs {
43
-
44
- // split address into its components
45
- split := ma.Split(a)
46
-
47
- // if first component (ip) is not unspecified, use it as is.
48
- if !manet.IsIPUnspecified(split[0]) {
49
- outputAddrs = append(outputAddrs, a)
50
- continue
51
- }
52
-
53
- // unspecified? add one address per interface.
54
- for _, ia := range ifaceAddrs {
55
- split[0] = ia
56
- joined := ma.Join(split...)
57
- outputAddrs = append(outputAddrs, joined)
58
- }
59
- }
60
-
61
- log.Event(context.TODO(), "interfaceListenAddresses", func() eventlog.Loggable {
62
- var addrs []string
63
- for _, addr := range outputAddrs {
64
- addrs = append(addrs, addr.String())
65
- }
66
- return eventlog.Metadata{"addresses": addrs}
67
- }())
68
- log.Debug("InterfaceListenAddresses:", outputAddrs)
69
- return outputAddrs, nil
70
-}
71
-
72
-// interfaceAddresses returns a list of addresses associated with local machine
73
-func interfaceAddresses() ([]ma.Multiaddr, error) {
74
- maddrs, err := manet.InterfaceMultiaddrs()
75
- if err != nil {
76
- return nil, err
77
- }
78
-
79
- var nonLoopback []ma.Multiaddr
80
- for _, a := range maddrs {
81
- if !manet.IsIPLoopback(a) {
82
- nonLoopback = append(nonLoopback, a)
83
- }
84
- }
85
-
86
- return nonLoopback, nil
87
-}
88
-
89
-// addrInList returns whether or not an address is part of a list.
90
-// this is useful to check if NAT is happening (or other bugs?)
91
-func addrInList(addr ma.Multiaddr, list []ma.Multiaddr) bool {
92
- for _, addr2 := range list {
93
- if addr.Equal(addr2) {
94
- return true
95
- }
96
- }
97
- return false
98
-}
99
-
100
-// checkNATWarning checks if our observed addresses differ. if so,
101
-// informs the user that certain things might not work yet
102
-func checkNATWarning(s *Swarm, observed ma.Multiaddr, expected ma.Multiaddr) {
103
- if observed.Equal(expected) {
104
- return
105
- }
106
-
107
- listen, err := InterfaceListenAddresses(s)
108
- if err != nil {
109
- log.Errorf("Error retrieving swarm.InterfaceListenAddresses: %s", err)
110
- return
111
- }
112
-
113
- if !addrInList(observed, listen) { // probably a nat
114
- log.Warningf(natWarning, observed, listen)
115
- }
116
-}
117
-
118
-const natWarning = `Remote peer observed our address to be: %s
119
-The local addresses are: %s
120
-Thus, connection is going through NAT, and other connections may fail.
121
-
122
-IPFS NAT traversal is still under development. Please bug us on github or irc to fix this.
123
-Baby steps: http://jbenet.static.s3.amazonaws.com/271dfcf/baby-steps.gif
124
-`
p2p/net2/swarm/simul_test.go
deleted
-66
@@ -1,66 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "sync"
5
- "testing"
6
- "time"
7
-
8
- peer "github.com/jbenet/go-ipfs/p2p/peer"
9
-
10
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12
-)
13
-
14
-func TestSimultOpen(t *testing.T) {
15
- // t.Skip("skipping for another test")
16
-
17
- ctx := context.Background()
18
- swarms, peers := makeSwarms(ctx, t, 2)
19
-
20
- // connect everyone
21
- {
22
- var wg sync.WaitGroup
23
- connect := func(s *Swarm, dst peer.ID, addr ma.Multiaddr) {
24
- // copy for other peer
25
- s.peers.AddAddress(dst, addr)
26
- if _, err := s.Dial(ctx, dst); err != nil {
27
- t.Fatal("error swarm dialing to peer", err)
28
- }
29
- wg.Done()
30
- }
31
-
32
- log.Info("Connecting swarms simultaneously.")
33
- wg.Add(2)
34
- go connect(swarms[0], swarms[1].local, peers[1].Addr)
35
- go connect(swarms[1], swarms[0].local, peers[0].Addr)
36
- wg.Wait()
37
- }
38
-
39
- for _, s := range swarms {
40
- s.Close()
41
- }
42
-}
43
-
44
-func TestSimultOpenMany(t *testing.T) {
45
- // t.Skip("very very slow")
46
-
47
- addrs := 20
48
- SubtestSwarm(t, addrs, 10)
49
-}
50
-
51
-func TestSimultOpenFewStress(t *testing.T) {
52
- if testing.Short() {
53
- t.SkipNow()
54
- }
55
- // t.Skip("skipping for another test")
56
-
57
- msgs := 40
58
- swarms := 2
59
- rounds := 10
60
- // rounds := 100
61
-
62
- for i := 0; i < rounds; i++ {
63
- SubtestSwarm(t, swarms, msgs)
64
- <-time.After(10 * time.Millisecond)
65
- }
66
-}
p2p/net2/swarm/swarm.go
deleted
-158
@@ -1,158 +0,0 @@
1
-// package swarm implements a connection muxer with a pair of channels
2
-// to synchronize all network communication.
3
-package swarm
4
-
5
-import (
6
- inet "github.com/jbenet/go-ipfs/p2p/net2"
7
- peer "github.com/jbenet/go-ipfs/p2p/peer"
8
- eventlog "github.com/jbenet/go-ipfs/util/eventlog"
9
-
10
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
12
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
13
- ps "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
14
-)
15
-
16
-var log = eventlog.Logger("swarm2")
17
-
18
-// Swarm is a connection muxer, allowing connections to other peers to
19
-// be opened and closed, while still using the same Chan for all
20
-// communication. The Chan sends/receives Messages, which note the
21
-// destination or source Peer.
22
-//
23
-// Uses peerstream.Swarm
24
-type Swarm struct {
25
- swarm *ps.Swarm
26
- local peer.ID
27
- peers peer.Peerstore
28
- connh ConnHandler
29
-
30
- cg ctxgroup.ContextGroup
31
-}
32
-
33
-// NewSwarm constructs a Swarm, with a Chan.
34
-func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
35
- local peer.ID, peers peer.Peerstore) (*Swarm, error) {
36
-
37
- s := &Swarm{
38
- swarm: ps.NewSwarm(),
39
- local: local,
40
- peers: peers,
41
- cg: ctxgroup.WithContext(ctx),
42
- }
43
-
44
- // configure Swarm
45
- s.cg.SetTeardown(s.teardown)
46
- s.SetConnHandler(nil) // make sure to setup our own conn handler.
47
-
48
- return s, s.listen(listenAddrs)
49
-}
50
-
51
-func (s *Swarm) teardown() error {
52
- return s.swarm.Close()
53
-}
54
-
55
-// CtxGroup returns the Context Group of the swarm
56
-func (s *Swarm) CtxGroup() ctxgroup.ContextGroup {
57
- return s.cg
58
-}
59
-
60
-// Close stops the Swarm.
61
-func (s *Swarm) Close() error {
62
- return s.cg.Close()
63
-}
64
-
65
-// StreamSwarm returns the underlying peerstream.Swarm
66
-func (s *Swarm) StreamSwarm() *ps.Swarm {
67
- return s.swarm
68
-}
69
-
70
-// SetConnHandler assigns the handler for new connections.
71
-// See peerstream. You will rarely use this. See SetStreamHandler
72
-func (s *Swarm) SetConnHandler(handler ConnHandler) {
73
-
74
- // handler is nil if user wants to clear the old handler.
75
- if handler == nil {
76
- s.swarm.SetConnHandler(func(psconn *ps.Conn) {
77
- s.connHandler(psconn)
78
- })
79
- return
80
- }
81
-
82
- s.swarm.SetConnHandler(func(psconn *ps.Conn) {
83
- // sc is nil if closed in our handler.
84
- if sc := s.connHandler(psconn); sc != nil {
85
- // call the user's handler. in a goroutine for sync safety.
86
- go handler(sc)
87
- }
88
- })
89
-}
90
-
91
-// SetStreamHandler assigns the handler for new streams.
92
-// See peerstream.
93
-func (s *Swarm) SetStreamHandler(handler inet.StreamHandler) {
94
- s.swarm.SetStreamHandler(func(s *ps.Stream) {
95
- handler(wrapStream(s))
96
- })
97
-}
98
-
99
-// NewStreamWithPeer creates a new stream on any available connection to p
100
-func (s *Swarm) NewStreamWithPeer(p peer.ID) (*Stream, error) {
101
- // if we have no connections, try connecting.
102
- if len(s.ConnectionsToPeer(p)) == 0 {
103
- log.Debug("Swarm: NewStreamWithPeer no connections. Attempting to connect...")
104
- if _, err := s.Dial(context.Background(), p); err != nil {
105
- return nil, err
106
- }
107
- }
108
- log.Debug("Swarm: NewStreamWithPeer...")
109
-
110
- st, err := s.swarm.NewStreamWithGroup(p)
111
- return wrapStream(st), err
112
-}
113
-
114
-// StreamsWithPeer returns all the live Streams to p
115
-func (s *Swarm) StreamsWithPeer(p peer.ID) []*Stream {
116
- return wrapStreams(ps.StreamsWithGroup(p, s.swarm.Streams()))
117
-}
118
-
119
-// ConnectionsToPeer returns all the live connections to p
120
-func (s *Swarm) ConnectionsToPeer(p peer.ID) []*Conn {
121
- return wrapConns(ps.ConnsWithGroup(p, s.swarm.Conns()))
122
-}
123
-
124
-// Connections returns a slice of all connections.
125
-func (s *Swarm) Connections() []*Conn {
126
- return wrapConns(s.swarm.Conns())
127
-}
128
-
129
-// CloseConnection removes a given peer from swarm + closes the connection
130
-func (s *Swarm) CloseConnection(p peer.ID) error {
131
- conns := s.swarm.ConnsWithGroup(p) // boom.
132
- for _, c := range conns {
133
- c.Close()
134
- }
135
- return nil
136
-}
137
-
138
-// Peers returns a copy of the set of peers swarm is connected to.
139
-func (s *Swarm) Peers() []peer.ID {
140
- conns := s.Connections()
141
-
142
- seen := make(map[peer.ID]struct{})
143
- peers := make([]peer.ID, 0, len(conns))
144
- for _, c := range conns {
145
- p := c.RemotePeer()
146
- if _, found := seen[p]; found {
147
- continue
148
- }
149
-
150
- peers = append(peers, p)
151
- }
152
- return peers
153
-}
154
-
155
-// LocalPeer returns the local peer swarm is associated to.
156
-func (s *Swarm) LocalPeer() peer.ID {
157
- return s.local
158
-}
p2p/net2/swarm/swarm_conn.go
deleted
-141
@@ -1,141 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "fmt"
5
-
6
- ic "github.com/jbenet/go-ipfs/p2p/crypto"
7
- conn "github.com/jbenet/go-ipfs/p2p/net/conn"
8
- inet "github.com/jbenet/go-ipfs/p2p/net2"
9
- peer "github.com/jbenet/go-ipfs/p2p/peer"
10
-
11
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
13
- ps "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
14
-)
15
-
16
-// a Conn is a simple wrapper around a ps.Conn that also exposes
17
-// some of the methods from the underlying conn.Conn.
18
-// There's **five** "layers" to each connection:
19
-// * 0. the net.Conn - underlying net.Conn (TCP/UDP/UTP/etc)
20
-// * 1. the manet.Conn - provides multiaddr friendly Conn
21
-// * 2. the conn.Conn - provides Peer friendly Conn (inc Secure channel)
22
-// * 3. the peerstream.Conn - provides peerstream / spdysptream happiness
23
-// * 4. the Conn - abstracts everyting out, exposing only key parts of underlying layers
24
-// (I know, this is kinda crazy. it's more historical than a good design. though the
25
-// layers do build up pieces of functionality. and they're all just io.RW :) )
26
-type Conn ps.Conn
27
-
28
-// ConnHandler is called when new conns are opened from remote peers.
29
-// See peerstream.ConnHandler
30
-type ConnHandler func(*Conn)
31
-
32
-func (c *Conn) StreamConn() *ps.Conn {
33
- return (*ps.Conn)(c)
34
-}
35
-
36
-func (c *Conn) RawConn() conn.Conn {
37
- // righly panic if these things aren't true. it is an expected
38
- // invariant that these Conns are all of the typewe expect:
39
- // ps.Conn wrapping a conn.Conn
40
- // if we get something else it is programmer error.
41
- return (*ps.Conn)(c).NetConn().(conn.Conn)
42
-}
43
-
44
-func (c *Conn) String() string {
45
- return fmt.Sprintf("<SwarmConn %s>", c.RawConn())
46
-}
47
-
48
-// LocalMultiaddr is the Multiaddr on this side
49
-func (c *Conn) LocalMultiaddr() ma.Multiaddr {
50
- return c.RawConn().LocalMultiaddr()
51
-}
52
-
53
-// LocalPeer is the Peer on our side of the connection
54
-func (c *Conn) LocalPeer() peer.ID {
55
- return c.RawConn().LocalPeer()
56
-}
57
-
58
-// RemoteMultiaddr is the Multiaddr on the remote side
59
-func (c *Conn) RemoteMultiaddr() ma.Multiaddr {
60
- return c.RawConn().RemoteMultiaddr()
61
-}
62
-
63
-// RemotePeer is the Peer on the remote side
64
-func (c *Conn) RemotePeer() peer.ID {
65
- return c.RawConn().RemotePeer()
66
-}
67
-
68
-// LocalPrivateKey is the public key of the peer on this side
69
-func (c *Conn) LocalPrivateKey() ic.PrivKey {
70
- return c.RawConn().LocalPrivateKey()
71
-}
72
-
73
-// RemotePublicKey is the public key of the peer on the remote side
74
-func (c *Conn) RemotePublicKey() ic.PubKey {
75
- return c.RawConn().RemotePublicKey()
76
-}
77
-
78
-// NewSwarmStream returns a new Stream from this connection
79
-func (c *Conn) NewSwarmStream() (*Stream, error) {
80
- s, err := c.StreamConn().NewStream()
81
- return wrapStream(s), err
82
-}
83
-
84
-// NewStream returns a new Stream from this connection
85
-func (c *Conn) NewStream() (inet.Stream, error) {
86
- s, err := c.NewSwarmStream()
87
- return inet.Stream(s), err
88
-}
89
-
90
-func (c *Conn) Close() error {
91
- return c.StreamConn().Close()
92
-}
93
-
94
-func wrapConn(psc *ps.Conn) (*Conn, error) {
95
- // grab the underlying connection.
96
- if _, ok := psc.NetConn().(conn.Conn); !ok {
97
- // this should never happen. if we see it ocurring it means that we added
98
- // a Listener to the ps.Swarm that is NOT one of our net/conn.Listener.
99
- return nil, fmt.Errorf("swarm connHandler: invalid conn (not a conn.Conn): %s", psc)
100
- }
101
- return (*Conn)(psc), nil
102
-}
103
-
104
-// wrapConns returns a *Conn for all these ps.Conns
105
-func wrapConns(conns1 []*ps.Conn) []*Conn {
106
- conns2 := make([]*Conn, len(conns1))
107
- for i, c1 := range conns1 {
108
- if c2, err := wrapConn(c1); err == nil {
109
- conns2[i] = c2
110
- }
111
- }
112
- return conns2
113
-}
114
-
115
-// newConnSetup does the swarm's "setup" for a connection. returns the underlying
116
-// conn.Conn this method is used by both swarm.Dial and ps.Swarm connHandler
117
-func (s *Swarm) newConnSetup(ctx context.Context, psConn *ps.Conn) (*Conn, error) {
118
-
119
- // wrap with a Conn
120
- sc, err := wrapConn(psConn)
121
- if err != nil {
122
- return nil, err
123
- }
124
-
125
- // if we have a public key, make sure we add it to our peerstore!
126
- // This is an important detail. Otherwise we must fetch the public
127
- // key from the DHT or some other system.
128
- if pk := sc.RemotePublicKey(); pk != nil {
129
- s.peers.AddPubKey(sc.RemotePeer(), pk)
130
- }
131
-
132
- // ok great! we can use it. add it to our group.
133
-
134
- // set the RemotePeer as a group on the conn. this lets us group
135
- // connections in the StreamSwarm by peer, and get a streams from
136
- // any available connection in the group (better multiconn):
137
- // swarm.StreamSwarm().NewStreamWithGroup(remotePeer)
138
- psConn.AddGroup(sc.RemotePeer())
139
-
140
- return sc, nil
141
-}
p2p/net2/swarm/swarm_dial.go
deleted
-104
@@ -1,104 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "errors"
5
- "fmt"
6
-
7
- conn "github.com/jbenet/go-ipfs/p2p/net/conn"
8
- peer "github.com/jbenet/go-ipfs/p2p/peer"
9
- lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
10
-
11
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12
-)
13
-
14
-// Dial connects to a peer.
15
-//
16
-// The idea is that the client of Swarm does not need to know what network
17
-// the connection will happen over. Swarm can use whichever it choses.
18
-// This allows us to use various transport protocols, do NAT traversal/relay,
19
-// etc. to achive connection.
20
-func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
21
-
22
- if p == s.local {
23
- return nil, errors.New("Attempted connection to self!")
24
- }
25
-
26
- // check if we already have an open connection first
27
- cs := s.ConnectionsToPeer(p)
28
- for _, c := range cs {
29
- if c != nil { // dump out the first one we find
30
- return c, nil
31
- }
32
- }
33
-
34
- sk := s.peers.PrivKey(s.local)
35
- if sk == nil {
36
- // may be fine for sk to be nil, just log a warning.
37
- log.Warning("Dial not given PrivateKey, so WILL NOT SECURE conn.")
38
- }
39
-
40
- remoteAddrs := s.peers.Addresses(p)
41
- if len(remoteAddrs) == 0 {
42
- return nil, errors.New("peer has no addresses")
43
- }
44
- localAddrs := s.peers.Addresses(s.local)
45
- if len(localAddrs) == 0 {
46
- log.Debug("Dialing out with no local addresses.")
47
- }
48
-
49
- // open connection to peer
50
- d := &conn.Dialer{
51
- LocalPeer: s.local,
52
- LocalAddrs: localAddrs,
53
- PrivateKey: sk,
54
- }
55
-
56
- // try to connect to one of the peer's known addresses.
57
- // for simplicity, we do this sequentially.
58
- // A future commit will do this asynchronously.
59
- var connC conn.Conn
60
- var err error
61
- for _, addr := range remoteAddrs {
62
- connC, err = d.Dial(ctx, addr, p)
63
- if err == nil {
64
- break
65
- }
66
- }
67
- if err != nil {
68
- return nil, err
69
- }
70
-
71
- // ok try to setup the new connection.
72
- swarmC, err := dialConnSetup(ctx, s, connC)
73
- if err != nil {
74
- log.Error("Dial newConnSetup failed. disconnecting.")
75
- log.Event(ctx, "dialFailureDisconnect", lgbl.NetConn(connC), lgbl.Error(err))
76
- swarmC.Close() // close the connection. didn't work out :(
77
- return nil, err
78
- }
79
-
80
- log.Event(ctx, "dial", p)
81
- return swarmC, nil
82
-}
83
-
84
-// dialConnSetup is the setup logic for a connection from the dial side. it
85
-// needs to add the Conn to the StreamSwarm, then run newConnSetup
86
-func dialConnSetup(ctx context.Context, s *Swarm, connC conn.Conn) (*Conn, error) {
87
-
88
- psC, err := s.swarm.AddConn(connC)
89
- if err != nil {
90
- // connC is closed by caller if we fail.
91
- return nil, fmt.Errorf("failed to add conn to ps.Swarm: %s", err)
92
- }
93
-
94
- // ok try to setup the new connection. (newConnSetup will add to group)
95
- swarmC, err := s.newConnSetup(ctx, psC)
96
- if err != nil {
97
- log.Error("Dial newConnSetup failed. disconnecting.")
98
- log.Event(ctx, "dialFailureDisconnect", lgbl.NetConn(connC), lgbl.Error(err))
99
- swarmC.Close() // we need to call this to make sure psC is Closed.
100
- return nil, err
101
- }
102
-
103
- return swarmC, err
104
-}
p2p/net2/swarm/swarm_listen.go
deleted
-86
@@ -1,86 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- conn "github.com/jbenet/go-ipfs/p2p/net/conn"
5
- lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
6
-
7
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9
- ps "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
10
- multierr "github.com/jbenet/go-ipfs/util/multierr"
11
-)
12
-
13
-// Open listeners for each network the swarm should listen on
14
-func (s *Swarm) listen(addrs []ma.Multiaddr) error {
15
- retErr := multierr.New()
16
-
17
- // listen on every address
18
- for i, addr := range addrs {
19
- err := s.setupListener(addr)
20
- if err != nil {
21
- if retErr.Errors == nil {
22
- retErr.Errors = make([]error, len(addrs))
23
- }
24
- retErr.Errors[i] = err
25
- log.Errorf("Failed to listen on: %s - %s", addr, err)
26
- }
27
- }
28
-
29
- if retErr.Errors != nil {
30
- return retErr
31
- }
32
- return nil
33
-}
34
-
35
-// Listen for new connections on the given multiaddr
36
-func (s *Swarm) setupListener(maddr ma.Multiaddr) error {
37
-
38
- // TODO rethink how this has to work. (jbenet)
39
- //
40
- // resolved, err := resolveUnspecifiedAddresses([]ma.Multiaddr{maddr})
41
- // if err != nil {
42
- // return err
43
- // }
44
- // for _, a := range resolved {
45
- // s.peers.AddAddress(s.local, a)
46
- // }
47
-
48
- sk := s.peers.PrivKey(s.local)
49
- if sk == nil {
50
- // may be fine for sk to be nil, just log a warning.
51
- log.Warning("Listener not given PrivateKey, so WILL NOT SECURE conns.")
52
- }
53
- list, err := conn.Listen(s.cg.Context(), maddr, s.local, sk)
54
- if err != nil {
55
- return err
56
- }
57
-
58
- // AddListener to the peerstream Listener. this will begin accepting connections
59
- // and streams!
60
- _, err = s.swarm.AddListener(list)
61
- return err
62
-}
63
-
64
-// connHandler is called by the StreamSwarm whenever a new connection is added
65
-// here we configure it slightly. Note that this is sequential, so if anything
66
-// will take a while do it in a goroutine.
67
-// See https://godoc.org/github.com/jbenet/go-peerstream for more information
68
-func (s *Swarm) connHandler(c *ps.Conn) *Conn {
69
- ctx := context.Background()
70
- // this context is for running the handshake, which -- when receiveing connections
71
- // -- we have no bound on beyond what the transport protocol bounds it at.
72
- // note that setup + the handshake are bounded by underlying io.
73
- // (i.e. if TCP or UDP disconnects (or the swarm closes), we're done.
74
- // Q: why not have a shorter handshake? think about an HTTP server on really slow conns.
75
- // as long as the conn is live (TCP says its online), it tries its best. we follow suit.)
76
-
77
- sc, err := s.newConnSetup(ctx, c)
78
- if err != nil {
79
- log.Error(err)
80
- log.Event(ctx, "newConnHandlerDisconnect", lgbl.NetConn(c.NetConn()), lgbl.Error(err))
81
- c.Close() // boom. close it.
82
- return nil
83
- }
84
-
85
- return sc
86
-}
p2p/net2/swarm/swarm_stream.go
deleted
-59
@@ -1,59 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- inet "github.com/jbenet/go-ipfs/p2p/net2"
5
-
6
- ps "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
7
-)
8
-
9
-// a Stream is a wrapper around a ps.Stream that exposes a way to get
10
-// our Conn and Swarm (instead of just the ps.Conn and ps.Swarm)
11
-type Stream ps.Stream
12
-
13
-// Stream returns the underlying peerstream.Stream
14
-func (s *Stream) Stream() *ps.Stream {
15
- return (*ps.Stream)(s)
16
-}
17
-
18
-// Conn returns the Conn associated with this Stream, as an inet.Conn
19
-func (s *Stream) Conn() inet.Conn {
20
- return s.SwarmConn()
21
-}
22
-
23
-// SwarmConn returns the Conn associated with this Stream, as a *Conn
24
-func (s *Stream) SwarmConn() *Conn {
25
- return (*Conn)(s.Stream().Conn())
26
-}
27
-
28
-// Wait waits for the stream to receive a reply.
29
-func (s *Stream) Wait() error {
30
- return s.Stream().Wait()
31
-}
32
-
33
-// Read reads bytes from a stream.
34
-func (s *Stream) Read(p []byte) (n int, err error) {
35
- return s.Stream().Read(p)
36
-}
37
-
38
-// Write writes bytes to a stream, flushing for each call.
39
-func (s *Stream) Write(p []byte) (n int, err error) {
40
- return s.Stream().Write(p)
41
-}
42
-
43
-// Close closes the stream, indicating this side is finished
44
-// with the stream.
45
-func (s *Stream) Close() error {
46
- return s.Stream().Close()
47
-}
48
-
49
-func wrapStream(pss *ps.Stream) *Stream {
50
- return (*Stream)(pss)
51
-}
52
-
53
-func wrapStreams(st []*ps.Stream) []*Stream {
54
- out := make([]*Stream, len(st))
55
- for i, s := range st {
56
- out[i] = wrapStream(s)
57
- }
58
- return out
59
-}
p2p/net2/swarm/swarm_test.go
deleted
-269
@@ -1,269 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "bytes"
5
- "io"
6
- "sync"
7
- "testing"
8
- "time"
9
-
10
- inet "github.com/jbenet/go-ipfs/p2p/net2"
11
- peer "github.com/jbenet/go-ipfs/p2p/peer"
12
- errors "github.com/jbenet/go-ipfs/util/debugerror"
13
- testutil "github.com/jbenet/go-ipfs/util/testutil"
14
-
15
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
16
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
17
-)
18
-
19
-func EchoStreamHandler(stream inet.Stream) {
20
- go func() {
21
- defer stream.Close()
22
-
23
- // pull out the ipfs conn
24
- c := stream.Conn()
25
- log.Debugf("%s ponging to %s", c.LocalPeer(), c.RemotePeer())
26
-
27
- buf := make([]byte, 4)
28
-
29
- for {
30
- if _, err := stream.Read(buf); err != nil {
31
- if err != io.EOF {
32
- log.Error("ping receive error:", err)
33
- }
34
- return
35
- }
36
-
37
- if !bytes.Equal(buf, []byte("ping")) {
38
- log.Errorf("ping receive error: ping != %s %v", buf, buf)
39
- return
40
- }
41
-
42
- if _, err := stream.Write([]byte("pong")); err != nil {
43
- log.Error("pond send error:", err)
44
- return
45
- }
46
- }
47
- }()
48
-}
49
-
50
-func makeSwarms(ctx context.Context, t *testing.T, num int) ([]*Swarm, []testutil.PeerNetParams) {
51
- swarms := make([]*Swarm, 0, num)
52
- peersnp := make([]testutil.PeerNetParams, 0, num)
53
-
54
- for i := 0; i < num; i++ {
55
- localnp := testutil.RandPeerNetParamsOrFatal(t)
56
- peersnp = append(peersnp, localnp)
57
-
58
- peerstore := peer.NewPeerstore()
59
- peerstore.AddAddress(localnp.ID, localnp.Addr)
60
- peerstore.AddPubKey(localnp.ID, localnp.PubKey)
61
- peerstore.AddPrivKey(localnp.ID, localnp.PrivKey)
62
-
63
- addrs := peerstore.Addresses(localnp.ID)
64
- swarm, err := NewSwarm(ctx, addrs, localnp.ID, peerstore)
65
- if err != nil {
66
- t.Fatal(err)
67
- }
68
-
69
- swarm.SetStreamHandler(EchoStreamHandler)
70
- swarms = append(swarms, swarm)
71
- }
72
-
73
- return swarms, peersnp
74
-}
75
-
76
-func connectSwarms(t *testing.T, ctx context.Context, swarms []*Swarm, peersnp []testutil.PeerNetParams) {
77
-
78
- var wg sync.WaitGroup
79
- connect := func(s *Swarm, dst peer.ID, addr ma.Multiaddr) {
80
- // TODO: make a DialAddr func.
81
- s.peers.AddAddress(dst, addr)
82
- if _, err := s.Dial(ctx, dst); err != nil {
83
- t.Fatal("error swarm dialing to peer", err)
84
- }
85
- wg.Done()
86
- }
87
-
88
- log.Info("Connecting swarms simultaneously.")
89
- for _, s := range swarms {
90
- for _, p := range peersnp {
91
- if p.ID != s.local { // don't connect to self.
92
- wg.Add(1)
93
- connect(s, p.ID, p.Addr)
94
- }
95
- }
96
- }
97
- wg.Wait()
98
-
99
- for _, s := range swarms {
100
- log.Infof("%s swarm routing table: %s", s.local, s.Peers())
101
- }
102
-}
103
-
104
-func SubtestSwarm(t *testing.T, SwarmNum int, MsgNum int) {
105
- // t.Skip("skipping for another test")
106
-
107
- ctx := context.Background()
108
- swarms, peersnp := makeSwarms(ctx, t, SwarmNum)
109
-
110
- // connect everyone
111
- connectSwarms(t, ctx, swarms, peersnp)
112
-
113
- // ping/pong
114
- for _, s1 := range swarms {
115
- log.Debugf("-------------------------------------------------------")
116
- log.Debugf("%s ping pong round", s1.local)
117
- log.Debugf("-------------------------------------------------------")
118
-
119
- _, cancel := context.WithCancel(ctx)
120
- got := map[peer.ID]int{}
121
- errChan := make(chan error, MsgNum*len(peersnp))
122
- streamChan := make(chan *Stream, MsgNum)
123
-
124
- // send out "ping" x MsgNum to every peer
125
- go func() {
126
- defer close(streamChan)
127
-
128
- var wg sync.WaitGroup
129
- send := func(p peer.ID) {
130
- defer wg.Done()
131
-
132
- // first, one stream per peer (nice)
133
- stream, err := s1.NewStreamWithPeer(p)
134
- if err != nil {
135
- errChan <- errors.Wrap(err)
136
- return
137
- }
138
-
139
- // send out ping!
140
- for k := 0; k < MsgNum; k++ { // with k messages
141
- msg := "ping"
142
- log.Debugf("%s %s %s (%d)", s1.local, msg, p, k)
143
- stream.Write([]byte(msg))
144
- }
145
-
146
- // read it later
147
- streamChan <- stream
148
- }
149
-
150
- for _, p := range peersnp {
151
- if p.ID == s1.local {
152
- continue // dont send to self...
153
- }
154
-
155
- wg.Add(1)
156
- go send(p.ID)
157
- }
158
- wg.Wait()
159
- }()
160
-
161
- // receive "pong" x MsgNum from every peer
162
- go func() {
163
- defer close(errChan)
164
- count := 0
165
- countShouldBe := MsgNum * (len(peersnp) - 1)
166
- for stream := range streamChan { // one per peer
167
- defer stream.Close()
168
-
169
- // get peer on the other side
170
- p := stream.Conn().RemotePeer()
171
-
172
- // receive pings
173
- msgCount := 0
174
- msg := make([]byte, 4)
175
- for k := 0; k < MsgNum; k++ { // with k messages
176
-
177
- // read from the stream
178
- if _, err := stream.Read(msg); err != nil {
179
- errChan <- errors.Wrap(err)
180
- continue
181
- }
182
-
183
- if string(msg) != "pong" {
184
- errChan <- errors.Errorf("unexpected message: %s", msg)
185
- continue
186
- }
187
-
188
- log.Debugf("%s %s %s (%d)", s1.local, msg, p, k)
189
- msgCount++
190
- }
191
-
192
- got[p] = msgCount
193
- count += msgCount
194
- }
195
-
196
- if count != countShouldBe {
197
- errChan <- errors.Errorf("count mismatch: %d != %d", count, countShouldBe)
198
- }
199
- }()
200
-
201
- // check any errors (blocks till consumer is done)
202
- for err := range errChan {
203
- if err != nil {
204
- t.Fatal(err.Error())
205
- }
206
- }
207
-
208
- log.Debugf("%s got pongs", s1.local)
209
- if (len(peersnp) - 1) != len(got) {
210
- t.Errorf("got (%d) less messages than sent (%d).", len(got), len(peersnp))
211
- }
212
-
213
- for p, n := range got {
214
- if n != MsgNum {
215
- t.Error("peer did not get all msgs", p, n, "/", MsgNum)
216
- }
217
- }
218
-
219
- cancel()
220
- <-time.After(10 * time.Millisecond)
221
- }
222
-
223
- for _, s := range swarms {
224
- s.Close()
225
- }
226
-}
227
-
228
-func TestSwarm(t *testing.T) {
229
- // t.Skip("skipping for another test")
230
-
231
- // msgs := 1000
232
- msgs := 100
233
- swarms := 5
234
- SubtestSwarm(t, swarms, msgs)
235
-}
236
-
237
-func TestConnHandler(t *testing.T) {
238
- // t.Skip("skipping for another test")
239
-
240
- ctx := context.Background()
241
- swarms, peersnp := makeSwarms(ctx, t, 5)
242
-
243
- gotconn := make(chan struct{}, 10)
244
- swarms[0].SetConnHandler(func(conn *Conn) {
245
- gotconn <- struct{}{}
246
- })
247
-
248
- connectSwarms(t, ctx, swarms, peersnp)
249
-
250
- <-time.After(time.Millisecond)
251
- // should've gotten 5 by now.
252
-
253
- swarms[0].SetConnHandler(nil)
254
-
255
- expect := 4
256
- for i := 0; i < expect; i++ {
257
- select {
258
- case <-time.After(time.Second):
259
- t.Fatal("failed to get connections")
260
- case <-gotconn:
261
- }
262
- }
263
-
264
- select {
265
- case <-gotconn:
266
- t.Fatalf("should have connected to %d swarms", expect)
267
- default:
268
- }
269
-}
p2p/protocol/identify/id.go
+1
-1
@@ -13,7 +13,7 @@ import (
13
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
14
15
host "github.com/jbenet/go-ipfs/p2p/host"
16
- inet "github.com/jbenet/go-ipfs/p2p/net2"
16
+ inet "github.com/jbenet/go-ipfs/p2p/net"
17
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
18
19
pb "github.com/jbenet/go-ipfs/p2p/protocol/identify/pb"
p2p/protocol/mux.go
+1
-1
@@ -7,7 +7,7 @@ import (
7
8
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
9
10
- inet "github.com/jbenet/go-ipfs/p2p/net2"
10
+ inet "github.com/jbenet/go-ipfs/p2p/net"
11
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
12
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
13
)
p2p/protocol/mux_test.go
+1
-1
@@ -4,7 +4,7 @@ import (
4
"bytes"
5
"testing"
6
7
- inet "github.com/jbenet/go-ipfs/p2p/net2"
7
+ inet "github.com/jbenet/go-ipfs/p2p/net"
8
)
9
10
var testCases = map[string]string{
p2p/protocol/relay/relay.go
+1
-1
@@ -7,7 +7,7 @@ import (
7
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
8
9
host "github.com/jbenet/go-ipfs/p2p/host"
10
- inet "github.com/jbenet/go-ipfs/p2p/net2"
10
+ inet "github.com/jbenet/go-ipfs/p2p/net"
11
peer "github.com/jbenet/go-ipfs/p2p/peer"
12
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
13
eventlog "github.com/jbenet/go-ipfs/util/eventlog"
p2p/protocol/relay/relay_test.go
+1
-1
@@ -4,7 +4,7 @@ import (
4
"io"
5
"testing"
6
7
- inet "github.com/jbenet/go-ipfs/p2p/net2"
7
+ inet "github.com/jbenet/go-ipfs/p2p/net"
8
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
9
relay "github.com/jbenet/go-ipfs/p2p/protocol/relay"
10
testutil "github.com/jbenet/go-ipfs/p2p/test/util"
p2p/test/backpressure/backpressure_test.go
+1
-1
@@ -8,7 +8,7 @@ import (
8
"time"
9
10
host "github.com/jbenet/go-ipfs/p2p/host"
11
- inet "github.com/jbenet/go-ipfs/p2p/net2"
11
+ inet "github.com/jbenet/go-ipfs/p2p/net"
12
peer "github.com/jbenet/go-ipfs/p2p/peer"
13
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
14
testutil "github.com/jbenet/go-ipfs/p2p/test/util"
p2p/test/util/util.go
+2
-2
@@ -4,8 +4,8 @@ import (
4
"testing"
5
6
bhost "github.com/jbenet/go-ipfs/p2p/host/basic"
7
- inet "github.com/jbenet/go-ipfs/p2p/net2"
8
- swarm "github.com/jbenet/go-ipfs/p2p/net2/swarm"
7
+ inet "github.com/jbenet/go-ipfs/p2p/net"
8
+ swarm "github.com/jbenet/go-ipfs/p2p/net/swarm"
9
peer "github.com/jbenet/go-ipfs/p2p/peer"
10
tu "github.com/jbenet/go-ipfs/util/testutil"
11
routing/dht/dht.go
+16
-12
@@ -10,8 +10,9 @@ import (
10
"sync"
11
"time"
12
13
- inet "github.com/jbenet/go-ipfs/p2p/net"
13
+ host "github.com/jbenet/go-ipfs/p2p/host"
14
peer "github.com/jbenet/go-ipfs/p2p/peer"
15
+ protocol "github.com/jbenet/go-ipfs/p2p/protocol"
16
routing "github.com/jbenet/go-ipfs/routing"
17
pb "github.com/jbenet/go-ipfs/routing/dht/pb"
18
kb "github.com/jbenet/go-ipfs/routing/kbucket"
@@ -26,6 +27,8 @@ import (
27
28
var log = eventlog.Logger("dht")
29
30
+var ProtocolDHT protocol.ID = "/ipfs/dht"
31
+
32
const doPinging = false
33
34
// NumBootstrapQueries defines the number of random dht queries to do to
@@ -37,7 +40,7 @@ const NumBootstrapQueries = 5
40
// IpfsDHT is an implementation of Kademlia with Coral and S/Kademlia modifications.
41
// It is used to implement the base IpfsRouting module.
42
type IpfsDHT struct {
40
- network inet.Network // the network services we need
43
+ host host.Host // the network services we need
44
self peer.ID // Local peer (yourself)
45
peerstore peer.Peerstore // Peer Registry
46
@@ -56,19 +59,19 @@ type IpfsDHT struct {
59
}
60
61
// NewDHT creates a new DHT object with the given peer as the 'local' host
59
-func NewDHT(ctx context.Context, p peer.ID, n inet.Network, dstore ds.ThreadSafeDatastore) *IpfsDHT {
62
+func NewDHT(ctx context.Context, h host.Host, dstore ds.ThreadSafeDatastore) *IpfsDHT {
63
dht := new(IpfsDHT)
64
dht.datastore = dstore
62
- dht.self = p
63
- dht.peerstore = n.Peerstore()
65
+ dht.self = h.ID()
66
+ dht.peerstore = h.Peerstore()
67
dht.ContextGroup = ctxgroup.WithContext(ctx)
65
- dht.network = n
66
- n.SetHandler(inet.ProtocolDHT, dht.handleNewStream)
68
+ dht.host = h
69
+ h.SetStreamHandler(ProtocolDHT, dht.handleNewStream)
70
68
- dht.providers = NewProviderManager(dht.Context(), p)
71
+ dht.providers = NewProviderManager(dht.Context(), dht.self)
72
dht.AddChildGroup(dht.providers)
73
71
- dht.routingTable = kb.NewRoutingTable(20, kb.ConvertPeerID(p), time.Minute, dht.peerstore)
74
+ dht.routingTable = kb.NewRoutingTable(20, kb.ConvertPeerID(dht.self), time.Minute, dht.peerstore)
75
dht.birth = time.Now()
76
77
dht.Validators = make(map[string]ValidatorFunc)
@@ -88,7 +91,8 @@ func (dht *IpfsDHT) LocalPeer() peer.ID {
91
92
// Connect to a new peer at the given address, ping and add to the routing table
93
func (dht *IpfsDHT) Connect(ctx context.Context, npeer peer.ID) error {
91
- if err := dht.network.DialPeer(ctx, npeer); err != nil {
94
+ // TODO: change interface to accept a PeerInfo as well.
95
+ if err := dht.host.Connect(ctx, peer.PeerInfo{ID: npeer}); err != nil {
96
return err
97
}
98
@@ -127,7 +131,7 @@ func (dht *IpfsDHT) putProvider(ctx context.Context, p peer.ID, key string) erro
131
132
// add self as the provider
133
pi := dht.peerstore.PeerInfo(dht.self)
130
- pmes.ProviderPeers = pb.PeerInfosToPBPeers(dht.network, []peer.PeerInfo{pi})
134
+ pmes.ProviderPeers = pb.PeerInfosToPBPeers(dht.host.Network(), []peer.PeerInfo{pi})
135
136
err := dht.sendMessage(ctx, p, pmes)
137
if err != nil {
@@ -304,7 +308,7 @@ func (dht *IpfsDHT) ensureConnectedToPeer(ctx context.Context, p peer.ID) error
308
}
309
310
// dial connection
307
- return dht.network.DialPeer(ctx, p)
311
+ return dht.host.Connect(ctx, peer.PeerInfo{ID: p})
312
}
313
314
// PingRoutine periodically pings nearest neighbors.
routing/dht/dht_net.go
+2
-2
@@ -74,7 +74,7 @@ func (dht *IpfsDHT) handleNewMessage(s inet.Stream) {
74
func (dht *IpfsDHT) sendRequest(ctx context.Context, p peer.ID, pmes *pb.Message) (*pb.Message, error) {
75
76
log.Debugf("%s dht starting stream", dht.self)
77
- s, err := dht.network.NewStream(inet.ProtocolDHT, p)
77
+ s, err := dht.host.NewStream(ProtocolDHT, p)
78
if err != nil {
79
return nil, err
80
}
@@ -116,7 +116,7 @@ func (dht *IpfsDHT) sendRequest(ctx context.Context, p peer.ID, pmes *pb.Message
116
func (dht *IpfsDHT) sendMessage(ctx context.Context, p peer.ID, pmes *pb.Message) error {
117
118
log.Debugf("%s dht starting stream", dht.self)
119
- s, err := dht.network.NewStream(inet.ProtocolDHT, p)
119
+ s, err := dht.host.NewStream(ProtocolDHT, p)
120
if err != nil {
121
return err
122
}
routing/dht/dht_test.go
+27
-53
@@ -14,11 +14,10 @@ import (
14
dssync "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
15
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
16
17
- swarmnet "github.com/jbenet/go-ipfs/p2p/net/swarmnet"
17
peer "github.com/jbenet/go-ipfs/p2p/peer"
18
+ netutil "github.com/jbenet/go-ipfs/p2p/test/util"
19
routing "github.com/jbenet/go-ipfs/routing"
20
u "github.com/jbenet/go-ipfs/util"
21
- testutil "github.com/jbenet/go-ipfs/util/testutil"
21
)
22
23
var testCaseValues = map[u.Key][]byte{}
@@ -32,30 +31,11 @@ func init() {
31
}
32
}
33
35
-func setupDHT(ctx context.Context, t *testing.T, addr ma.Multiaddr) *IpfsDHT {
36
-
37
- sk, pk, err := testutil.SeededKeyPair(time.Now().UnixNano())
38
- if err != nil {
39
- t.Fatal(err)
40
- }
41
-
42
- p, err := peer.IDFromPublicKey(pk)
43
- if err != nil {
44
- t.Fatal(err)
45
- }
46
-
47
- peerstore := peer.NewPeerstore()
48
- peerstore.AddPrivKey(p, sk)
49
- peerstore.AddPubKey(p, pk)
50
- peerstore.AddAddress(p, addr)
51
-
52
- n, err := swarmnet.NewNetwork(ctx, []ma.Multiaddr{addr}, p, peerstore)
53
- if err != nil {
54
- t.Fatal(err)
55
- }
34
+func setupDHT(ctx context.Context, t *testing.T) *IpfsDHT {
35
+ h := netutil.GenHostSwarm(t, ctx)
36
37
dss := dssync.MutexWrap(ds.NewMapDatastore())
58
- d := NewDHT(ctx, p, n, dss)
38
+ d := NewDHT(ctx, h, dss)
39
40
d.Validators["v"] = func(u.Key, []byte) error {
41
return nil
@@ -69,9 +49,9 @@ func setupDHTS(ctx context.Context, n int, t *testing.T) ([]ma.Multiaddr, []peer
49
peers := make([]peer.ID, n)
50
51
for i := 0; i < n; i++ {
72
- addrs[i] = testutil.RandLocalTCPAddress()
73
- dhts[i] = setupDHT(ctx, t, addrs[i])
52
+ dhts[i] = setupDHT(ctx, t)
53
peers[i] = dhts[i].self
54
+ addrs[i] = dhts[i].peerstore.Addresses(dhts[i].self)[0]
55
}
56
57
return addrs, peers, dhts
@@ -116,19 +96,16 @@ func TestPing(t *testing.T) {
96
// t.Skip("skipping test to debug another")
97
ctx := context.Background()
98
119
- addrA := testutil.RandLocalTCPAddress()
120
- addrB := testutil.RandLocalTCPAddress()
121
-
122
- dhtA := setupDHT(ctx, t, addrA)
123
- dhtB := setupDHT(ctx, t, addrB)
99
+ dhtA := setupDHT(ctx, t)
100
+ dhtB := setupDHT(ctx, t)
101
102
peerA := dhtA.self
103
peerB := dhtB.self
104
105
defer dhtA.Close()
106
defer dhtB.Close()
130
- defer dhtA.network.Close()
131
- defer dhtB.network.Close()
107
+ defer dhtA.host.Close()
108
+ defer dhtB.host.Close()
109
110
connect(t, ctx, dhtA, dhtB)
111
@@ -149,16 +126,13 @@ func TestValueGetSet(t *testing.T) {
126
127
ctx := context.Background()
128
152
- addrA := testutil.RandLocalTCPAddress()
153
- addrB := testutil.RandLocalTCPAddress()
154
-
155
- dhtA := setupDHT(ctx, t, addrA)
156
- dhtB := setupDHT(ctx, t, addrB)
129
+ dhtA := setupDHT(ctx, t)
130
+ dhtB := setupDHT(ctx, t)
131
132
defer dhtA.Close()
133
defer dhtB.Close()
160
- defer dhtA.network.Close()
161
- defer dhtB.network.Close()
134
+ defer dhtA.host.Close()
135
+ defer dhtB.host.Close()
136
137
vf := func(u.Key, []byte) error {
138
return nil
@@ -200,7 +174,7 @@ func TestProvides(t *testing.T) {
174
defer func() {
175
for i := 0; i < 4; i++ {
176
dhts[i].Close()
203
- defer dhts[i].network.Close()
177
+ defer dhts[i].host.Close()
178
}
179
}()
180
@@ -268,7 +242,7 @@ func TestBootstrap(t *testing.T) {
242
defer func() {
243
for i := 0; i < nDHTs; i++ {
244
dhts[i].Close()
271
- defer dhts[i].network.Close()
245
+ defer dhts[i].host.Close()
246
}
247
}()
248
@@ -312,7 +286,7 @@ func TestProvidesMany(t *testing.T) {
286
defer func() {
287
for i := 0; i < nDHTs; i++ {
288
dhts[i].Close()
315
- defer dhts[i].network.Close()
289
+ defer dhts[i].host.Close()
290
}
291
}()
292
@@ -424,7 +398,7 @@ func TestProvidesAsync(t *testing.T) {
398
defer func() {
399
for i := 0; i < 4; i++ {
400
dhts[i].Close()
427
- defer dhts[i].network.Close()
401
+ defer dhts[i].host.Close()
402
}
403
}()
404
@@ -478,7 +452,7 @@ func TestLayeredGet(t *testing.T) {
452
defer func() {
453
for i := 0; i < 4; i++ {
454
dhts[i].Close()
481
- defer dhts[i].network.Close()
455
+ defer dhts[i].host.Close()
456
}
457
}()
458
@@ -518,7 +492,7 @@ func TestFindPeer(t *testing.T) {
492
defer func() {
493
for i := 0; i < 4; i++ {
494
dhts[i].Close()
521
- dhts[i].network.Close()
495
+ dhts[i].host.Close()
496
}
497
}()
498
@@ -554,7 +528,7 @@ func TestFindPeersConnectedToPeer(t *testing.T) {
528
defer func() {
529
for i := 0; i < 4; i++ {
530
dhts[i].Close()
557
- dhts[i].network.Close()
531
+ dhts[i].host.Close()
532
}
533
}()
534
@@ -633,11 +607,11 @@ func TestConnectCollision(t *testing.T) {
607
608
ctx := context.Background()
609
636
- addrA := testutil.RandLocalTCPAddress()
637
- addrB := testutil.RandLocalTCPAddress()
610
+ dhtA := setupDHT(ctx, t)
611
+ dhtB := setupDHT(ctx, t)
612
639
- dhtA := setupDHT(ctx, t, addrA)
640
- dhtB := setupDHT(ctx, t, addrB)
613
+ addrA := dhtA.peerstore.Addresses(dhtA.self)[0]
614
+ addrB := dhtB.peerstore.Addresses(dhtB.self)[0]
615
616
peerA := dhtA.self
617
peerB := dhtB.self
@@ -674,7 +648,7 @@ func TestConnectCollision(t *testing.T) {
648
649
dhtA.Close()
650
dhtB.Close()
677
- dhtA.network.Close()
678
- dhtB.network.Close()
651
+ dhtA.host.Close()
652
+ dhtB.host.Close()
653
}
654
}
routing/dht/ext_test.go
+27
-18
@@ -1,6 +1,8 @@
1
package dht
2
3
import (
4
+ "io"
5
+ "io/ioutil"
6
"math/rand"
7
"testing"
8
@@ -29,13 +31,20 @@ func TestGetFailures(t *testing.T) {
31
if err != nil {
32
t.Fatal(err)
33
}
32
- nets := mn.Nets()
34
+ hosts := mn.Hosts()
35
peers := mn.Peers()
36
37
tsds := dssync.MutexWrap(ds.NewMapDatastore())
36
- d := NewDHT(ctx, peers[0], nets[0], tsds)
38
+ d := NewDHT(ctx, hosts[0], tsds)
39
d.Update(ctx, peers[1])
40
41
+ // u.POut("NotFound Test\n")
42
+ // Reply with failures to every message
43
+ hosts[1].SetStreamHandler(ProtocolDHT, func(s inet.Stream) {
44
+ defer s.Close()
45
+ io.Copy(ioutil.Discard, s)
46
+ })
47
+
48
// This one should time out
49
// u.POut("Timout Test\n")
50
ctx1, _ := context.WithTimeout(context.Background(), time.Second)
@@ -50,7 +59,7 @@ func TestGetFailures(t *testing.T) {
59
t.Log("Timeout test passed.")
60
61
// Reply with failures to every message
53
- nets[1].SetHandler(inet.ProtocolDHT, func(s inet.Stream) {
62
+ hosts[1].SetStreamHandler(ProtocolDHT, func(s inet.Stream) {
63
defer s.Close()
64
65
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
@@ -97,7 +106,7 @@ func TestGetFailures(t *testing.T) {
106
}
107
108
// u.POut("handleGetValue Test\n")
100
- s, err := nets[1].NewStream(inet.ProtocolDHT, peers[0])
109
+ s, err := hosts[1].NewStream(ProtocolDHT, hosts[0].ID())
110
if err != nil {
111
t.Fatal(err)
112
}
@@ -133,19 +142,19 @@ func TestNotFound(t *testing.T) {
142
if err != nil {
143
t.Fatal(err)
144
}
136
- nets := mn.Nets()
145
+ hosts := mn.Hosts()
146
peers := mn.Peers()
147
tsds := dssync.MutexWrap(ds.NewMapDatastore())
139
- d := NewDHT(ctx, peers[0], nets[0], tsds)
148
+ d := NewDHT(ctx, hosts[0], tsds)
149
150
for _, p := range peers {
151
d.Update(ctx, p)
152
}
153
154
// Reply with random peers to every message
146
- for _, neti := range nets {
147
- neti := neti // shadow loop var
148
- neti.SetHandler(inet.ProtocolDHT, func(s inet.Stream) {
155
+ for _, host := range hosts {
156
+ host := host // shadow loop var
157
+ host.SetStreamHandler(ProtocolDHT, func(s inet.Stream) {
158
defer s.Close()
159
160
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
@@ -163,11 +172,11 @@ func TestNotFound(t *testing.T) {
172
ps := []peer.PeerInfo{}
173
for i := 0; i < 7; i++ {
174
p := peers[rand.Intn(len(peers))]
166
- pi := neti.Peerstore().PeerInfo(p)
175
+ pi := host.Peerstore().PeerInfo(p)
176
ps = append(ps, pi)
177
}
178
170
- resp.CloserPeers = pb.PeerInfosToPBPeers(d.network, ps)
179
+ resp.CloserPeers = pb.PeerInfosToPBPeers(d.host.Network(), ps)
180
if err := pbw.WriteMsg(resp); err != nil {
181
panic(err)
182
}
@@ -205,20 +214,20 @@ func TestLessThanKResponses(t *testing.T) {
214
if err != nil {
215
t.Fatal(err)
216
}
208
- nets := mn.Nets()
217
+ hosts := mn.Hosts()
218
peers := mn.Peers()
219
220
tsds := dssync.MutexWrap(ds.NewMapDatastore())
212
- d := NewDHT(ctx, peers[0], nets[0], tsds)
221
+ d := NewDHT(ctx, hosts[0], tsds)
222
223
for i := 1; i < 5; i++ {
224
d.Update(ctx, peers[i])
225
}
226
227
// Reply with random peers to every message
219
- for _, neti := range nets {
220
- neti := neti // shadow loop var
221
- neti.SetHandler(inet.ProtocolDHT, func(s inet.Stream) {
228
+ for _, host := range hosts {
229
+ host := host // shadow loop var
230
+ host.SetStreamHandler(ProtocolDHT, func(s inet.Stream) {
231
defer s.Close()
232
233
pbr := ggio.NewDelimitedReader(s, inet.MessageSizeMax)
@@ -231,10 +240,10 @@ func TestLessThanKResponses(t *testing.T) {
240
241
switch pmes.GetType() {
242
case pb.Message_GET_VALUE:
234
- pi := neti.Peerstore().PeerInfo(peers[1])
243
+ pi := host.Peerstore().PeerInfo(peers[1])
244
resp := &pb.Message{
245
Type: pmes.Type,
237
- CloserPeers: pb.PeerInfosToPBPeers(d.network, []peer.PeerInfo{pi}),
246
+ CloserPeers: pb.PeerInfosToPBPeers(d.host.Network(), []peer.PeerInfo{pi}),
247
}
248
249
if err := pbw.WriteMsg(resp); err != nil {
routing/dht/handlers.go
+5
-5
@@ -89,7 +89,7 @@ func (dht *IpfsDHT) handleGetValue(ctx context.Context, p peer.ID, pmes *pb.Mess
89
provinfos := peer.PeerInfos(dht.peerstore, provs)
90
if len(provs) > 0 {
91
log.Debugf("handleGetValue returning %d provider[s]", len(provs))
92
- resp.ProviderPeers = pb.PeerInfosToPBPeers(dht.network, provinfos)
92
+ resp.ProviderPeers = pb.PeerInfosToPBPeers(dht.host.Network(), provinfos)
93
}
94
95
// Find closest peer on given cluster to desired key and reply with that info
@@ -106,7 +106,7 @@ func (dht *IpfsDHT) handleGetValue(ctx context.Context, p peer.ID, pmes *pb.Mess
106
}
107
}
108
109
- resp.CloserPeers = pb.PeerInfosToPBPeers(dht.network, closerinfos)
109
+ resp.CloserPeers = pb.PeerInfosToPBPeers(dht.host.Network(), closerinfos)
110
}
111
112
return resp, nil
@@ -161,7 +161,7 @@ func (dht *IpfsDHT) handleFindPeer(ctx context.Context, p peer.ID, pmes *pb.Mess
161
}
162
}
163
164
- resp.CloserPeers = pb.PeerInfosToPBPeers(dht.network, withAddresses)
164
+ resp.CloserPeers = pb.PeerInfosToPBPeers(dht.host.Network(), withAddresses)
165
return resp, nil
166
}
167
@@ -185,14 +185,14 @@ func (dht *IpfsDHT) handleGetProviders(ctx context.Context, p peer.ID, pmes *pb.
185
186
if providers != nil && len(providers) > 0 {
187
infos := peer.PeerInfos(dht.peerstore, providers)
188
- resp.ProviderPeers = pb.PeerInfosToPBPeers(dht.network, infos)
188
+ resp.ProviderPeers = pb.PeerInfosToPBPeers(dht.host.Network(), infos)
189
}
190
191
// Also send closer peers.
192
closer := dht.betterPeersToQuery(pmes, p, CloserPeerCount)
193
if closer != nil {
194
infos := peer.PeerInfos(dht.peerstore, providers)
195
- resp.CloserPeers = pb.PeerInfosToPBPeers(dht.network, infos)
195
+ resp.CloserPeers = pb.PeerInfosToPBPeers(dht.host.Network(), infos)
196
}
197
198
return resp, nil
routing/dht/query.go
+11
-23
@@ -3,7 +3,6 @@ package dht
3
import (
4
"sync"
5
6
- inet "github.com/jbenet/go-ipfs/p2p/net"
6
peer "github.com/jbenet/go-ipfs/p2p/peer"
7
queue "github.com/jbenet/go-ipfs/p2p/peer/queue"
8
"github.com/jbenet/go-ipfs/routing"
@@ -18,17 +17,10 @@ import (
17
var maxQueryConcurrency = AlphaValue
18
19
type dhtQuery struct {
21
- // the key we're querying for
22
- key u.Key
23
-
24
- // dialer used to ensure we're connected to peers
25
- dialer inet.Dialer
26
-
27
- // the function to execute per peer
28
- qfunc queryFunc
29
-
30
- // the concurrency parameter
31
- concurrency int
20
+ dht *IpfsDHT
21
+ key u.Key // the key we're querying for
22
+ qfunc queryFunc // the function to execute per peer
23
+ concurrency int // the concurrency parameter
24
}
25
26
type dhtQueryResult struct {
@@ -40,10 +32,10 @@ type dhtQueryResult struct {
32
}
33
34
// constructs query
43
-func newQuery(k u.Key, d inet.Dialer, f queryFunc) *dhtQuery {
35
+func (dht *IpfsDHT) newQuery(k u.Key, f queryFunc) *dhtQuery {
36
return &dhtQuery{
37
key: k,
46
- dialer: d,
38
+ dht: dht,
39
qfunc: f,
40
concurrency: maxQueryConcurrency,
41
}
@@ -155,7 +147,7 @@ func (r *dhtQueryRunner) Run(peers []peer.ID) (*dhtQueryResult, error) {
147
148
func (r *dhtQueryRunner) addPeerToQuery(ctx context.Context, next peer.ID) {
149
// if new peer is ourselves...
158
- if next == r.query.dialer.LocalPeer() {
150
+ if next == r.query.dht.self {
151
return
152
}
153
@@ -222,10 +214,11 @@ func (r *dhtQueryRunner) queryPeer(cg ctxgroup.ContextGroup, p peer.ID) {
214
}()
215
216
// make sure we're connected to the peer.
225
- if conns := r.query.dialer.ConnsToPeer(p); len(conns) == 0 {
217
+ if conns := r.query.dht.host.Network().ConnsToPeer(p); len(conns) == 0 {
218
log.Infof("worker for: %v -- not connected. dial start", p)
219
228
- if err := r.query.dialer.DialPeer(cg.Context(), p); err != nil {
220
+ pi := peer.PeerInfo{ID: p}
221
+ if err := r.query.dht.host.Connect(cg.Context(), pi); err != nil {
222
log.Debugf("ERROR worker for: %v -- err connecting: %v", p, err)
223
r.Lock()
224
r.errs = append(r.errs, err)
@@ -257,12 +250,7 @@ func (r *dhtQueryRunner) queryPeer(cg ctxgroup.ContextGroup, p peer.ID) {
250
log.Debugf("PEERS CLOSER -- worker for: %v (%d closer peers)", p, len(res.closerPeers))
251
for _, next := range res.closerPeers {
252
// add their addresses to the dialer's peerstore
260
- conns := r.query.dialer.ConnsToPeer(next.ID)
261
- if len(conns) == 0 {
262
- log.Infof("PEERS CLOSER -- worker for %v FOUND NEW PEER: %s %s", p, next.ID, next.Addrs)
263
- }
264
-
265
- r.query.dialer.Peerstore().AddAddresses(next.ID, next.Addrs)
253
+ r.query.dht.peerstore.AddPeerInfo(next)
254
r.addPeerToQuery(cg.Context(), next.ID)
255
log.Debugf("PEERS CLOSER -- worker for: %v added %v (%v)", p, next.ID, next.Addrs)
256
}
routing/dht/routing.go
+5
-5
@@ -82,7 +82,7 @@ func (dht *IpfsDHT) GetValue(ctx context.Context, key u.Key) ([]byte, error) {
82
}
83
84
// setup the Query
85
- query := newQuery(key, dht.network, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
85
+ query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
86
87
val, peers, err := dht.getValueOrPeers(ctx, p, key)
88
if err != nil {
@@ -170,7 +170,7 @@ func (dht *IpfsDHT) getClosestPeers(ctx context.Context, key u.Key) (<-chan peer
170
peerset.Add(p)
171
}
172
173
- query := newQuery(key, dht.network, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
173
+ query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
174
closer, err := dht.closerPeersSingle(ctx, key, p)
175
if err != nil {
176
log.Errorf("error getting closer peers: %s", err)
@@ -253,7 +253,7 @@ func (dht *IpfsDHT) findProvidersAsyncRoutine(ctx context.Context, key u.Key, co
253
}
254
255
// setup the Query
256
- query := newQuery(key, dht.network, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
256
+ query := dht.newQuery(key, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
257
258
pmes, err := dht.findProvidersSingle(ctx, p, key)
259
if err != nil {
@@ -312,7 +312,7 @@ func (dht *IpfsDHT) FindPeer(ctx context.Context, id peer.ID) (peer.PeerInfo, er
312
}
313
314
// setup the Query
315
- query := newQuery(u.Key(id), dht.network, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
315
+ query := dht.newQuery(u.Key(id), func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
316
317
pmes, err := dht.findPeerSingle(ctx, p, id)
318
if err != nil {
@@ -361,7 +361,7 @@ func (dht *IpfsDHT) FindPeersConnectedToPeer(ctx context.Context, id peer.ID) (<
361
}
362
363
// setup the Query
364
- query := newQuery(u.Key(id), dht.network, func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
364
+ query := dht.newQuery(u.Key(id), func(ctx context.Context, p peer.ID) (*dhtQueryResult, error) {
365
366
pmes, err := dht.findPeerSingle(ctx, p, id)
367
if err != nil {
routing/mock/dht.go
+2
-2
@@ -27,12 +27,12 @@ func (rs *mocknetserver) ClientWithDatastore(ctx context.Context, p testutil.Ide
27
28
// FIXME AddPeer doesn't appear to be idempotent
29
30
- net, err := rs.mn.AddPeer(p.PrivateKey(), p.Address())
30
+ host, err := rs.mn.AddPeer(p.PrivateKey(), p.Address())
31
if err != nil {
32
panic("FIXME")
33
// return nil, debugerror.Wrap(err)
34
}
35
- return dht.NewDHT(ctx, p.ID(), net, sync.MutexWrap(ds))
35
+ return dht.NewDHT(ctx, host, sync.MutexWrap(ds))
36
}
37
38
var _ Server = &mocknetserver{}