@cryptotaxi247 / kubo / commits / 8fb5cf957

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 -![](https://docs.google.com/drawings/d/1FvU7GImRsb9GvAWDDo1le85jIrnFJNVB_OTPXC15WwM/pub?h=480)
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{}