removed old network
Juan Batiz-Benet committed
Dec 16, 2014 at 04:46 UTC
c63ffdd0ae0208302194d2d74197a52c8a315806
20 files changed
-2371
net/message/message.go
deleted
-90
@@ -1,90 +0,0 @@
1
-package message
2
-
3
-import (
4
- "errors"
5
-
6
- peer "github.com/jbenet/go-ipfs/peer"
7
-
8
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
9
- proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
10
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
11
-)
12
-
13
-// ErrInvalidPayload is an error used in the router.HandlePacket implementations
14
-var ErrInvalidPayload = errors.New("invalid packet: non-[]byte payload")
15
-
16
-// Packet is used inside the network package to represent a message
17
-// flowing across the subsystems (Conn, Swarm, Mux, Service).
18
-// implements router.Packet
19
-type Packet struct {
20
- Src router.Address // peer.ID or service string
21
- Dst router.Address // peer.ID or service string
22
- Data []byte // raw data
23
- Context context.Context // context of the Packet.
24
-}
25
-
26
-func (p *Packet) Destination() router.Address {
27
- return p.Dst
28
-}
29
-
30
-func (p *Packet) Payload() interface{} {
31
- return p.Data
32
-}
33
-
34
-func (p *Packet) Response(data []byte) Packet {
35
- return Packet{
36
- Src: p.Dst,
37
- Dst: p.Src,
38
- Data: data,
39
- Context: p.Context,
40
- }
41
-}
42
-
43
-// NetMessage is the interface for the message
44
-type NetMessage interface {
45
- Peer() peer.Peer
46
- Data() []byte
47
- Loggable() map[string]interface{}
48
-}
49
-
50
-// New is the interface for constructing a new message.
51
-func New(p peer.Peer, data []byte) NetMessage {
52
- return &message{peer: p, data: data}
53
-}
54
-
55
-// message represents a packet of information sent to or received from a
56
-// particular Peer.
57
-type message struct {
58
- // To or from, depending on direction.
59
- peer peer.Peer
60
-
61
- // Opaque data
62
- data []byte
63
-}
64
-
65
-func (m *message) Peer() peer.Peer {
66
- return m.peer
67
-}
68
-
69
-func (m *message) Data() []byte {
70
- return m.data
71
-}
72
-
73
-func (m *message) Loggable() map[string]interface{} {
74
- return map[string]interface{}{
75
- "netMessage": map[string]interface{}{
76
- "recipient": m.Peer().Loggable(),
77
- // TODO sizeBytes? bytes? lenBytes?
78
- "size": len(m.Data()),
79
- },
80
- }
81
-}
82
-
83
-// FromObject creates a message from a protobuf-marshallable message.
84
-func FromObject(p peer.Peer, data proto.Message) (NetMessage, error) {
85
- bytes, err := proto.Marshal(data)
86
- if err != nil {
87
- return nil, err
88
- }
89
- return New(p, bytes), nil
90
-}
net/mux/internal/pb/Makefile
deleted
-10
@@ -1,10 +0,0 @@
1
-PB = $(wildcard *.proto)
2
-GO = $(PB:.proto=.pb.go)
3
-
4
-all: $(GO)
5
-
6
-%.pb.go: %.proto
7
- protoc --gogo_out=. --proto_path=../../../../../../:/usr/local/opt/protobuf/include:. $<
8
-
9
-clean:
10
- rm *.pb.go
net/mux/internal/pb/mux.pb.go
deleted
-91
@@ -1,91 +0,0 @@
1
-// Code generated by protoc-gen-gogo.
2
-// source: mux.proto
3
-// DO NOT EDIT!
4
-
5
-/*
6
-Package mux_pb is a generated protocol buffer package.
7
-
8
-It is generated from these files:
9
- mux.proto
10
-
11
-It has these top-level messages:
12
- PBProtocolMessage
13
-*/
14
-package mux_pb
15
-
16
-import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto"
17
-import math "math"
18
-
19
-// Reference imports to suppress errors if they are not otherwise used.
20
-var _ = proto.Marshal
21
-var _ = math.Inf
22
-
23
-type ProtocolID int32
24
-
25
-const (
26
- ProtocolID_Test ProtocolID = 0
27
- ProtocolID_Identify ProtocolID = 1
28
- ProtocolID_Routing ProtocolID = 2
29
- ProtocolID_Exchange ProtocolID = 3
30
- ProtocolID_Diagnostic ProtocolID = 4
31
-)
32
-
33
-var ProtocolID_name = map[int32]string{
34
- 0: "Test",
35
- 1: "Identify",
36
- 2: "Routing",
37
- 3: "Exchange",
38
- 4: "Diagnostic",
39
-}
40
-var ProtocolID_value = map[string]int32{
41
- "Test": 0,
42
- "Identify": 1,
43
- "Routing": 2,
44
- "Exchange": 3,
45
- "Diagnostic": 4,
46
-}
47
-
48
-func (x ProtocolID) Enum() *ProtocolID {
49
- p := new(ProtocolID)
50
- *p = x
51
- return p
52
-}
53
-func (x ProtocolID) String() string {
54
- return proto.EnumName(ProtocolID_name, int32(x))
55
-}
56
-func (x *ProtocolID) UnmarshalJSON(data []byte) error {
57
- value, err := proto.UnmarshalJSONEnum(ProtocolID_value, data, "ProtocolID")
58
- if err != nil {
59
- return err
60
- }
61
- *x = ProtocolID(value)
62
- return nil
63
-}
64
-
65
-type PBProtocolMessage struct {
66
- ProtocolID *ProtocolID `protobuf:"varint,1,req,enum=mux.pb.ProtocolID" json:"ProtocolID,omitempty"`
67
- Data []byte `protobuf:"bytes,2,req" json:"Data,omitempty"`
68
- XXX_unrecognized []byte `json:"-"`
69
-}
70
-
71
-func (m *PBProtocolMessage) Reset() { *m = PBProtocolMessage{} }
72
-func (m *PBProtocolMessage) String() string { return proto.CompactTextString(m) }
73
-func (*PBProtocolMessage) ProtoMessage() {}
74
-
75
-func (m *PBProtocolMessage) GetProtocolID() ProtocolID {
76
- if m != nil && m.ProtocolID != nil {
77
- return *m.ProtocolID
78
- }
79
- return ProtocolID_Test
80
-}
81
-
82
-func (m *PBProtocolMessage) GetData() []byte {
83
- if m != nil {
84
- return m.Data
85
- }
86
- return nil
87
-}
88
-
89
-func init() {
90
- proto.RegisterEnum("mux.pb.ProtocolID", ProtocolID_name, ProtocolID_value)
91
-}
net/mux/internal/pb/mux.proto
deleted
-14
@@ -1,14 +0,0 @@
1
-package mux.pb;
2
-
3
-enum ProtocolID {
4
- Test = 0;
5
- Identify = 1; // setup
6
- Routing = 2; // dht
7
- Exchange = 3; // bitswap
8
- Diagnostic = 4;
9
-}
10
-
11
-message PBProtocolMessage {
12
- required ProtocolID ProtocolID = 1;
13
- required bytes Data = 2;
14
-}
net/mux/mux.go
deleted
-217
@@ -1,217 +0,0 @@
1
-// package mux implements a protocol muxer.
2
-package mux
3
-
4
-import (
5
- "errors"
6
- "fmt"
7
- "sync"
8
-
9
- msg "github.com/jbenet/go-ipfs/net/message"
10
- pb "github.com/jbenet/go-ipfs/net/mux/internal/pb"
11
- u "github.com/jbenet/go-ipfs/util"
12
-
13
- proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
14
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
15
-)
16
-
17
-var log = u.Logger("muxer")
18
-
19
-// ProtocolIDs used to identify each protocol.
20
-// These should probably be defined elsewhere.
21
-var (
22
- ProtocolID_Routing = pb.ProtocolID_Routing
23
- ProtocolID_Exchange = pb.ProtocolID_Exchange
24
- ProtocolID_Diagnostic = pb.ProtocolID_Diagnostic
25
-)
26
-
27
-// Protocol objects produce + consume raw data. They are added to the Muxer
28
-// with a ProtocolID, which is added to outgoing payloads. Muxer properly
29
-// encapsulates and decapsulates when interfacing with its Protocols. The
30
-// Protocols do not encounter their ProtocolID.
31
-type Protocol interface {
32
- ProtocolID() pb.ProtocolID
33
-
34
- // Node is a router.Node, for message connectivity.
35
- router.Node
36
-}
37
-
38
-// ProtocolMap maps ProtocolIDs to Protocols.
39
-type ProtocolMap map[pb.ProtocolID]Protocol
40
-
41
-// Muxer is a simple multiplexor that reads + writes to Incoming and Outgoing
42
-// channels. It multiplexes various protocols, wrapping and unwrapping data
43
-// with a ProtocolID.
44
-//
45
-// implements router.Node and router.Route
46
-type Muxer struct {
47
- local router.Address
48
- uplink router.Node
49
-
50
- // Protocols are the multiplexed services.
51
- Protocols ProtocolMap
52
- mapLock sync.Mutex
53
-
54
- bwiLock sync.Mutex
55
- bwIn uint64
56
- msgIn uint64
57
-
58
- bwoLock sync.Mutex
59
- bwOut uint64
60
- msgOut uint64
61
-}
62
-
63
-// NewMuxer constructs a muxer given a protocol map.
64
-// uplink is a Node to send all outgoing traffic to.
65
-func NewMuxer(local router.Address, uplink router.Node) *Muxer {
66
- return &Muxer{
67
- local: local,
68
- uplink: uplink,
69
- Protocols: ProtocolMap{},
70
- }
71
-}
72
-
73
-// GetMessageCounts return the in/out message count measured over this muxer.
74
-func (m *Muxer) GetMessageCounts() (in uint64, out uint64) {
75
- m.bwiLock.Lock()
76
- in = m.msgIn
77
- m.bwiLock.Unlock()
78
-
79
- m.bwoLock.Lock()
80
- out = m.msgOut
81
- m.bwoLock.Unlock()
82
- return
83
-}
84
-
85
-// GetBandwidthTotals return the in/out bandwidth measured over this muxer.
86
-func (m *Muxer) GetBandwidthTotals() (in uint64, out uint64) {
87
- m.bwiLock.Lock()
88
- in = m.bwIn
89
- m.bwiLock.Unlock()
90
-
91
- m.bwoLock.Lock()
92
- out = m.bwOut
93
- m.bwoLock.Unlock()
94
- return
95
-}
96
-
97
-// AddProtocol adds a Protocol with given ProtocolID to the Muxer.
98
-func (m *Muxer) AddProtocol(p Protocol, pid pb.ProtocolID) error {
99
- m.mapLock.Lock()
100
- defer m.mapLock.Unlock()
101
-
102
- if _, found := m.Protocols[pid]; found {
103
- return errors.New("Another protocol already using this ProtocolID")
104
- }
105
-
106
- m.Protocols[pid] = p
107
- return nil
108
-}
109
-
110
-func (m *Muxer) Address() router.Address {
111
- return m.local
112
-}
113
-
114
-func (m *Muxer) HandlePacket(p router.Packet, from router.Node) error {
115
- pkt, ok := p.(*msg.Packet)
116
- if !ok {
117
- return msg.ErrInvalidPayload
118
- }
119
-
120
- if from == m.uplink {
121
- return m.handleIncomingPacket(pkt, from)
122
- } else {
123
- return m.handleOutgoingPacket(pkt, from)
124
- }
125
-}
126
-
127
-// handleIncomingPacket routes message to the appropriate protocol.
128
-func (m *Muxer) handleIncomingPacket(p *msg.Packet, _ router.Node) error {
129
-
130
- m.bwiLock.Lock()
131
- // TODO: compensate for overhead
132
- m.bwIn += uint64(len(p.Data))
133
- m.msgIn++
134
- m.bwiLock.Unlock()
135
-
136
- data, pid, err := unwrapData(p.Data)
137
- if err != nil {
138
- return fmt.Errorf("muxer de-serializing error: %v", err)
139
- }
140
-
141
- // TODO: fix this when mpool is fixed.
142
- // conn.ReleaseBuffer(m1.Data())
143
-
144
- p.Data = data
145
-
146
- m.mapLock.Lock()
147
- proto, found := m.Protocols[pid]
148
- m.mapLock.Unlock()
149
-
150
- if !found {
151
- return fmt.Errorf("muxer: unknown protocol %v", pid)
152
- }
153
-
154
- log.Debugf("muxer: outgoing packet %d -> %s", proto.ProtocolID(), m.uplink.Address())
155
- return proto.HandlePacket(p, m)
156
-}
157
-
158
-// handleOutgoingMessages sends out messages to the outside world
159
-func (m *Muxer) handleOutgoingPacket(p *msg.Packet, from router.Node) error {
160
-
161
- var pid pb.ProtocolID
162
- var proto Protocol
163
- m.mapLock.Lock()
164
- for pid2, proto2 := range m.Protocols {
165
- if proto2 == from {
166
- pid = pid2
167
- proto = proto2
168
- break
169
- }
170
- }
171
- m.mapLock.Unlock()
172
-
173
- if proto == nil {
174
- return errors.New("muxer: packet sent from unknown protocol")
175
- }
176
-
177
- var err error
178
- p.Data, err = wrapData(p.Data, pid)
179
- if err != nil {
180
- return fmt.Errorf("muxer serializing error: %v", err)
181
- }
182
-
183
- m.bwoLock.Lock()
184
- // TODO: compensate for overhead
185
- // TODO(jbenet): switch this to a goroutine to prevent sync waiting.
186
- m.bwOut += uint64(len(p.Data))
187
- m.msgOut++
188
- m.bwoLock.Unlock()
189
-
190
- // TODO: add multiple uplinks
191
- log.Debugf("muxer: incoming packet %s -> %d", m.uplink.Address(), proto.ProtocolID())
192
- return m.uplink.HandlePacket(p, m)
193
-}
194
-
195
-func wrapData(data []byte, pid pb.ProtocolID) ([]byte, error) {
196
- // Marshal
197
- pbm := new(pb.PBProtocolMessage)
198
- pbm.ProtocolID = &pid
199
- pbm.Data = data
200
- b, err := proto.Marshal(pbm)
201
- if err != nil {
202
- return nil, err
203
- }
204
-
205
- return b, nil
206
-}
207
-
208
-func unwrapData(data []byte) ([]byte, pb.ProtocolID, error) {
209
- // Unmarshal
210
- pbm := new(pb.PBProtocolMessage)
211
- err := proto.Unmarshal(data, pbm)
212
- if err != nil {
213
- return nil, 0, err
214
- }
215
-
216
- return pbm.GetData(), pbm.GetProtocolID(), nil
217
-}
net/mux/mux_test.go
deleted
-137
@@ -1,137 +0,0 @@
1
-package mux
2
-
3
-import (
4
- "bytes"
5
- "testing"
6
-
7
- mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
8
- msg "github.com/jbenet/go-ipfs/net/message"
9
- pb "github.com/jbenet/go-ipfs/net/mux/internal/pb"
10
- peer "github.com/jbenet/go-ipfs/peer"
11
- testutil "github.com/jbenet/go-ipfs/util/testutil"
12
-
13
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
14
-)
15
-
16
-type TestProtocol struct {
17
- mux *Muxer
18
- pid pb.ProtocolID
19
- msg []*msg.Packet
20
-}
21
-
22
-func (t *TestProtocol) ProtocolID() pb.ProtocolID {
23
- return t.pid
24
-}
25
-
26
-func (t *TestProtocol) Address() router.Address {
27
- return t.pid
28
-}
29
-
30
-func (t *TestProtocol) HandlePacket(p router.Packet, from router.Node) error {
31
- pkt, ok := p.(*msg.Packet)
32
- if !ok {
33
- return msg.ErrInvalidPayload
34
- }
35
-
36
- log.Debugf("TestProtocol %d got: %v", t, p)
37
- if from == t.mux {
38
- t.msg = append(t.msg, pkt)
39
- return nil
40
- }
41
- return t.mux.HandlePacket(p, t)
42
-}
43
-
44
-func newPeer(t *testing.T, id string) peer.Peer {
45
- mh, err := mh.FromHexString(id)
46
- if err != nil {
47
- t.Error(err)
48
- return nil
49
- }
50
-
51
- return testutil.NewPeerWithID(peer.ID(mh))
52
-}
53
-
54
-func testMsg(t *testing.T, m *msg.Packet, data []byte) {
55
- if !bytes.Equal(data, m.Data) {
56
- t.Errorf("Data does not match: %v != %v", data, m.Data)
57
- }
58
-}
59
-
60
-func testWrappedMsg(t *testing.T, m *msg.Packet, pid pb.ProtocolID, data []byte) {
61
- data2, pid2, err := unwrapData(m.Data)
62
- if err != nil {
63
- t.Error(err)
64
- }
65
-
66
- if pid != pid2 {
67
- t.Errorf("ProtocolIDs do not match: %v != %v", pid, pid2)
68
- }
69
-
70
- if !bytes.Equal(data, data2) {
71
- t.Errorf("Data does not match: %v != %v", data, data2)
72
- }
73
-}
74
-
75
-func TestSimpleMuxer(t *testing.T) {
76
- // setup
77
- peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa")
78
- peer2 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275bbbbbb")
79
-
80
- uplink := router.NewQueueNode("queue", make(chan router.Packet, 10))
81
- mux1 := NewMuxer(string(peer1.ID()), uplink)
82
-
83
- pid1 := pb.ProtocolID_Test
84
- pid2 := pb.ProtocolID_Routing
85
- p1 := &TestProtocol{mux1, pid1, nil}
86
- p2 := &TestProtocol{mux1, pid2, nil}
87
- mux1.AddProtocol(p1, pid1)
88
- mux1.AddProtocol(p2, pid2)
89
-
90
- // test outgoing p1
91
- for _, s := range []string{"foo", "bar", "baz"} {
92
-
93
- pkt := msg.Packet{Src: peer1, Dst: peer2, Data: []byte(s)}
94
- if err := p1.HandlePacket(&pkt, nil); err != nil {
95
- t.Fatal(err)
96
- }
97
- testWrappedMsg(t, (<-uplink.Queue()).(*msg.Packet), pid1, []byte(s))
98
- }
99
-
100
- // test incoming p1
101
- for i, s := range []string{"foo", "bar", "baz"} {
102
- d, err := wrapData([]byte(s), pid1)
103
- if err != nil {
104
- t.Error(err)
105
- }
106
-
107
- pkt := msg.Packet{Src: peer1, Dst: peer2, Data: d}
108
- if err := mux1.HandlePacket(&pkt, uplink); err != nil {
109
- t.Fatal(err)
110
- }
111
- testMsg(t, p1.msg[i], []byte(s))
112
- }
113
-
114
- // test outgoing p2
115
- for _, s := range []string{"foo", "bar", "baz"} {
116
-
117
- pkt := msg.Packet{Src: peer1, Dst: peer2, Data: []byte(s)}
118
- if err := p2.HandlePacket(&pkt, nil); err != nil {
119
- t.Fatal(err)
120
- }
121
- testWrappedMsg(t, (<-uplink.Queue()).(*msg.Packet), pid2, []byte(s))
122
- }
123
-
124
- // test incoming p2
125
- for i, s := range []string{"foo", "bar", "baz"} {
126
- d, err := wrapData([]byte(s), pid2)
127
- if err != nil {
128
- t.Fatal(err)
129
- }
130
-
131
- pkt := msg.Packet{Src: peer1, Dst: peer2, Data: d}
132
- if err := mux1.HandlePacket(&pkt, uplink); err != nil {
133
- t.Fatal(err)
134
- }
135
- testMsg(t, p2.msg[i], []byte(s))
136
- }
137
-}
net/service/internal/pb/Makefile
deleted
-11
@@ -1,11 +0,0 @@
1
-PB = $(wildcard *.proto)
2
-GO = $(PB:.proto=.pb.go)
3
-
4
-all: $(GO)
5
-
6
-%.pb.go: %.proto
7
- protoc --gogo_out=. --proto_path=../../../../../../:/usr/local/opt/protobuf/include:. $<
8
-
9
-clean:
10
- rm -f *.pb.go
11
- rm -f *.go
net/service/internal/pb/service.pb.go
deleted
-48
@@ -1,48 +0,0 @@
1
-// Code generated by protoc-gen-gogo.
2
-// source: service.proto
3
-// DO NOT EDIT!
4
-
5
-/*
6
-Package service_pb is a generated protocol buffer package.
7
-
8
-It is generated from these files:
9
- service.proto
10
-
11
-It has these top-level messages:
12
- PBRequest
13
-*/
14
-package service_pb
15
-
16
-import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto"
17
-import math "math"
18
-
19
-// Reference imports to suppress errors if they are not otherwise used.
20
-var _ = proto.Marshal
21
-var _ = math.Inf
22
-
23
-type PBRequest struct {
24
- Data []byte `protobuf:"bytes,1,req" json:"Data,omitempty"`
25
- Tag []byte `protobuf:"bytes,3,opt" json:"Tag,omitempty"`
26
- XXX_unrecognized []byte `json:"-"`
27
-}
28
-
29
-func (m *PBRequest) Reset() { *m = PBRequest{} }
30
-func (m *PBRequest) String() string { return proto.CompactTextString(m) }
31
-func (*PBRequest) ProtoMessage() {}
32
-
33
-func (m *PBRequest) GetData() []byte {
34
- if m != nil {
35
- return m.Data
36
- }
37
- return nil
38
-}
39
-
40
-func (m *PBRequest) GetTag() []byte {
41
- if m != nil {
42
- return m.Tag
43
- }
44
- return nil
45
-}
46
-
47
-func init() {
48
-}
net/service/internal/pb/service.proto
deleted
-6
@@ -1,6 +0,0 @@
1
-package service.pb;
2
-
3
-message PBRequest {
4
- required bytes Data = 1;
5
- optional bytes Tag = 3;
6
-}
net/service/request.go
deleted
-128
@@ -1,128 +0,0 @@
1
-package service
2
-
3
-import (
4
- crand "crypto/rand"
5
-
6
- msg "github.com/jbenet/go-ipfs/net/message"
7
- pb "github.com/jbenet/go-ipfs/net/service/internal/pb"
8
- peer "github.com/jbenet/go-ipfs/peer"
9
-
10
- proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
11
-)
12
-
13
-const (
14
- // IDSize is the size of the ID in bytes.
15
- IDSize int = 4
16
-)
17
-
18
-// RequestID is a field that identifies request-response flows.
19
-type RequestID []byte
20
-
21
-// Request turns a RequestID into a Request (unsetting first bit)
22
-func (r RequestID) Request() RequestID {
23
- if r == nil {
24
- return nil
25
- }
26
- r2 := make([]byte, len(r))
27
- copy(r2, r)
28
- r2[0] = r[0] & 0x7F // unset first bit for request
29
- return RequestID(r2)
30
-}
31
-
32
-// Response turns a RequestID into a Response (setting first bit)
33
-func (r RequestID) Response() RequestID {
34
- if r == nil {
35
- return nil
36
- }
37
- r2 := make([]byte, len(r))
38
- copy(r2, r)
39
- r2[0] = r[0] | 0x80 // set first bit for response
40
- return RequestID(r2)
41
-}
42
-
43
-// IsRequest returns whether a RequestID identifies a request
44
-func (r RequestID) IsRequest() bool {
45
- if r == nil {
46
- return false
47
- }
48
- return !r.IsResponse()
49
-}
50
-
51
-// IsResponse returns whether a RequestID identifies a response
52
-func (r RequestID) IsResponse() bool {
53
- if r == nil {
54
- return false
55
- }
56
- return bool(r[0]&0x80 == 0x80)
57
-}
58
-
59
-// RandomRequestID creates and returns a new random request ID
60
-func RandomRequestID() (RequestID, error) {
61
- buf := make([]byte, IDSize)
62
- _, err := crand.Read(buf)
63
- return RequestID(buf).Request(), err
64
-}
65
-
66
-// RequestMap is a map of Requests. the key = (peer.ID concat RequestID).
67
-type RequestMap map[string]*Request
68
-
69
-// Request objects are used to multiplex request-response flows.
70
-type Request struct {
71
-
72
- // ID is the RequestID identifying this Request-Response Flow.
73
- ID RequestID
74
-
75
- // PeerID identifies the peer from whom to expect the response.
76
- PeerID peer.ID
77
-
78
- // Response is the channel of incoming responses.
79
- Response chan msg.NetMessage
80
-}
81
-
82
-// NewRequest creates a request for given peer.ID
83
-func NewRequest(pid peer.ID) (*Request, error) {
84
- id, err := RandomRequestID()
85
- if err != nil {
86
- return nil, err
87
- }
88
-
89
- return &Request{
90
- ID: id,
91
- PeerID: pid,
92
- Response: make(chan msg.NetMessage, 1),
93
- }, nil
94
-}
95
-
96
-// Key returns the RequestKey for this request. Use with maps.
97
-func (r *Request) Key() string {
98
- return RequestKey(r.PeerID, r.ID)
99
-}
100
-
101
-// RequestKey is the peer.ID concatenated with the RequestID. Use with maps.
102
-func RequestKey(pid peer.ID, rid RequestID) string {
103
- return string(pid) + string(rid.Request()[:])
104
-}
105
-
106
-func wrapData(data []byte, rid RequestID) ([]byte, error) {
107
- // Marshal
108
- pbm := new(pb.PBRequest)
109
- pbm.Data = data
110
- pbm.Tag = rid
111
- b, err := proto.Marshal(pbm)
112
- if err != nil {
113
- return nil, err
114
- }
115
-
116
- return b, nil
117
-}
118
-
119
-func unwrapData(data []byte) ([]byte, RequestID, error) {
120
- // Unmarshal
121
- pbm := new(pb.PBRequest)
122
- err := proto.Unmarshal(data, pbm)
123
- if err != nil {
124
- return nil, nil, err
125
- }
126
-
127
- return pbm.GetData(), pbm.GetTag(), nil
128
-}
net/service/request_test.go
deleted
-41
@@ -1,41 +0,0 @@
1
-package service
2
-
3
-import (
4
- "bytes"
5
- "testing"
6
-)
7
-
8
-func TestMarshaling(t *testing.T) {
9
-
10
- test := func(d1 []byte, rid1 RequestID) {
11
- d2, err := wrapData(d1, rid1)
12
- if err != nil {
13
- t.Error(err)
14
- }
15
-
16
- d3, rid2, err := unwrapData(d2)
17
- if err != nil {
18
- t.Error(err)
19
- }
20
-
21
- d4, err := wrapData(d3, rid1)
22
- if err != nil {
23
- t.Error(err)
24
- }
25
-
26
- if !bytes.Equal(rid2, rid1) {
27
- t.Error("RequestID fail")
28
- }
29
-
30
- if !bytes.Equal(d1, d3) {
31
- t.Error("unmarshalled data should be the same")
32
- }
33
-
34
- if !bytes.Equal(d2, d4) {
35
- t.Error("marshalled data should be the same")
36
- }
37
- }
38
-
39
- test([]byte("foo"), []byte{1, 2, 3, 4})
40
- test([]byte("bar"), nil)
41
-}
net/service/service.go
deleted
-304
@@ -1,304 +0,0 @@
1
-package service
2
-
3
-import (
4
- "errors"
5
- "fmt"
6
- "sync"
7
-
8
- msg "github.com/jbenet/go-ipfs/net/message"
9
- u "github.com/jbenet/go-ipfs/util"
10
-
11
- ctxgroup "github.com/jbenet/go-ctxgroup"
12
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
13
- router "github.com/jbenet/go-router"
14
-)
15
-
16
-var log = u.Logger("service")
17
-
18
-// ErrNoResponse is returned by Service when a Request did not get a response,
19
-// and no other error happened
20
-var ErrNoResponse = errors.New("no response to request")
21
-
22
-// Handler is an interface that objects must implement in order to handle
23
-// a service's requests.
24
-type Handler interface {
25
-
26
- // HandleMessage receives an incoming message, and potentially returns
27
- // a response message to send back.
28
- HandleMessage(context.Context, msg.NetMessage) msg.NetMessage
29
-}
30
-
31
-// Sender interface for network services.
32
-type Sender interface {
33
- // SendMessage sends out a given message, without expecting a response.
34
- SendMessage(ctx context.Context, m msg.NetMessage) error
35
-
36
- // SendRequest sends out a given message, and awaits a response.
37
- // Set Deadlines or cancellations in the context.Context you pass in.
38
- SendRequest(ctx context.Context, m msg.NetMessage) (msg.NetMessage, error)
39
-}
40
-
41
-// Service is an interface for a net resource with both outgoing (sender) and
42
-// incomig (SetHandler) requests.
43
-type Service interface {
44
- Sender // can use it to send out msgs
45
- router.Node // it is a Node in the net topology.
46
-
47
- // SetUplink assigns the Node to send packets out
48
- SetUplink(router.Node)
49
- Uplink() router.Node
50
-
51
- // SetHandler assigns the request Handler for this service.
52
- SetHandler(Handler)
53
- GetHandler() Handler
54
-}
55
-
56
-// Service is a networking component that protocols can use to multiplex
57
-// messages over the same channel, and to issue + handle requests.
58
-type service struct {
59
- // Handler is the object registered to handle incoming requests.
60
- Handler Handler
61
- HandlerLock sync.RWMutex
62
-
63
- // Requests are all the pending requests on this service.
64
- Requests RequestMap
65
- RequestsLock sync.RWMutex
66
-
67
- // the connection to the outside world
68
- uplink router.Node
69
- uplinkLock sync.RWMutex
70
- addr router.Address
71
-}
72
-
73
-// NewService creates a service object with given type ID and Handler
74
-func NewService(addr router.Address, uplink router.Node, h Handler) Service {
75
- s := &service{
76
- Handler: h,
77
- Requests: RequestMap{},
78
- uplink: uplink,
79
- addr: addr,
80
- }
81
- return s
82
-}
83
-
84
-// sendMessage sends a message out (actual leg work. SendMessage is to export w/o rid)
85
-func (s *service) sendMessage(ctx context.Context, m msg.NetMessage, rid RequestID) error {
86
-
87
- // serialize ServiceMessage wrapper
88
- data, err := wrapData(m.Data(), rid)
89
- if err != nil {
90
- return err
91
- }
92
-
93
- // log.Debug("Service send message [to = %s]", m.Peer())
94
-
95
- // send message
96
- m2 := msg.New(m.Peer(), data)
97
-
98
- pkt := msg.Packet{
99
- Src:
100
- }
101
-
102
- select {
103
- case s.Outgoing <- m2:
104
- case <-ctx.Done():
105
- return ctx.Err()
106
- }
107
-
108
- pkt := msg.Packet{
109
- Src: m.
110
- }
111
-
112
- return nil
113
-}
114
-
115
-// SendMessage sends a message out
116
-func (s *service) SendMessage(ctx context.Context, m msg.NetMessage) error {
117
- return s.sendMessage(ctx, m, nil)
118
-}
119
-
120
-// SendRequest sends a request message out and awaits a response.
121
-func (s *service) SendRequest(ctx context.Context, m msg.NetMessage) (msg.NetMessage, error) {
122
-
123
- // check if we should bail given our contexts
124
- select {
125
- default:
126
- case <-s.Closing():
127
- return nil, fmt.Errorf("service closed: %s", s.Context().Err())
128
- case <-ctx.Done():
129
- return nil, ctx.Err()
130
- }
131
-
132
- // create a request
133
- r, err := NewRequest(m.Peer().ID())
134
- if err != nil {
135
- return nil, err
136
- }
137
-
138
- // register Request
139
- s.RequestsLock.Lock()
140
- s.Requests[r.Key()] = r
141
- s.RequestsLock.Unlock()
142
-
143
- // defer deleting this request
144
- defer func() {
145
- s.RequestsLock.Lock()
146
- delete(s.Requests, r.Key())
147
- s.RequestsLock.Unlock()
148
- }()
149
-
150
- // check if we should bail after waiting for mutex
151
- select {
152
- default:
153
- case <-s.Closing():
154
- return nil, fmt.Errorf("service closed: %s", s.Context().Err())
155
- case <-ctx.Done():
156
- return nil, ctx.Err()
157
- }
158
-
159
- // Send message
160
- s.sendMessage(ctx, m, r.ID)
161
-
162
- // wait for response
163
- m = nil
164
- err = nil
165
- select {
166
- case m = <-r.Response:
167
- case <-s.Closed():
168
- err = fmt.Errorf("service closed: %s", s.Context().Err())
169
- case <-ctx.Done():
170
- err = ctx.Err()
171
- }
172
-
173
- if m == nil {
174
- return nil, ErrNoResponse
175
- }
176
-
177
- return m, err
178
-}
179
-
180
-// handleIncoming consumes the messages on the s.Incoming channel and
181
-// routes them appropriately (to requests, or handler).
182
-func (s *service) handleIncomingMessages() {
183
- defer s.Children().Done()
184
-
185
- for {
186
- select {
187
- case m, more := <-s.Incoming:
188
- if !more {
189
- return
190
- }
191
- s.Children().Add(1)
192
- go s.handleIncomingMessage(m)
193
-
194
- case <-s.Closing():
195
- return
196
- }
197
- }
198
-}
199
-
200
-func (s *service) handleIncomingMessage(pkt *msg.Packet) error {
201
-
202
- // check the packet has a valid Context
203
- ctx := pkt.Context
204
- if ctx == nil {
205
- return fmt.Errorf("service got pkt without valid Context")
206
- }
207
-
208
- // check the source is a peer
209
- srcPeer, ok := pkt.Src.(peer.Peer)
210
- if !ok {
211
- return fmt.Errorf("service got pkt from non-Peer src: %v", pkt.Src)
212
- }
213
-
214
- // unwrap the incoming message
215
- data, rid, err := unwrapData(pkt.Data)
216
- if err != nil {
217
- return fmt.Errorf("service de-serializing error: %v", err)
218
- }
219
-
220
- // convert to msg.NetMessage, which the rest of the system expects.
221
- m2 := msg.New(srcPeer, data)
222
-
223
- // if it's a request (or has no RequestID), handle it
224
- if rid == nil || rid.IsRequest() {
225
- handler := s.GetHandler()
226
- if handler == nil {
227
- log.Errorf("service dropped msg: %v", m)
228
- log.Event()
229
- return nil
230
- // no handler, drop it.
231
- }
232
-
233
- // this go routine is developer friendliness to keep their stacks
234
- // separate (and more readable) from the network goroutine. If
235
- // problems arise and you'd like to see _the full_ stack of where
236
- // this message is coming from, just remove the goroutine part.
237
- response := make(chan msg.NetMessage)
238
- go func() msg.NetMessage {
239
- return handler.HandleMessage(ctx, m2)
240
- }()
241
- r1 := <-response
242
- // Note: HandleMessage *must* respect context. We could co-opt it
243
- // and do a select {} here on the context, BUT that would just drop
244
- // a packet and free up the goroutine to return to the network. the
245
- // problem is still there: the Service handler hasn't returned yet.
246
-
247
- // if handler gave us a response, send it out!
248
- if r1 != nil {
249
- if err := s.sendMessage(ctx, r1, rid.Response()); err != nil {
250
- return fmt.Errorf("error sending response message: %v", err)
251
- }
252
- }
253
- return
254
- }
255
-
256
- // Otherwise, it is a response. handle it.
257
- if !rid.IsResponse() {
258
- log.Errorf("RequestID should identify a response here.")
259
- }
260
-
261
- key := RequestKey(m.Peer().ID(), RequestID(rid))
262
- s.RequestsLock.RLock()
263
- r, found := s.Requests[key]
264
- s.RequestsLock.RUnlock()
265
-
266
- if !found {
267
- log.Errorf("no request key %v (timeout?)", []byte(key))
268
- return
269
- }
270
-
271
- select {
272
- case r.Response <- m2:
273
- case <-s.Closing():
274
- }
275
-}
276
-
277
-
278
-// Address is the router.Node address
279
-func (s *service) Address() router.Address {
280
- return s.addr
281
-}
282
-
283
-// HandlePacket implements router.Node
284
-// service only receives packets in HandlePacket
285
-func (s *service) HandlePacket(p router.Packet, from router.Node) error {
286
- pkt, ok := p.(*msg.Packet)
287
- if !ok {
288
- return msg.ErrInvalidPayload
289
- }
290
-}
291
-
292
-// SetHandler assigns the request Handler for this service.
293
-func (s *service) SetHandler(h Handler) {
294
- s.HandlerLock.Lock()
295
- defer s.HandlerLock.Unlock()
296
- s.Handler = h
297
-}
298
-
299
-// GetHandler returns the request Handler for this service.
300
-func (s *service) GetHandler() Handler {
301
- s.HandlerLock.RLock()
302
- defer s.HandlerLock.RUnlock()
303
- return s.Handler
304
-}
net/service/service_test.go
deleted
-164
@@ -1,164 +0,0 @@
1
-package service
2
-
3
-import (
4
- "bytes"
5
- "testing"
6
- "time"
7
-
8
- msg "github.com/jbenet/go-ipfs/net/message"
9
- peer "github.com/jbenet/go-ipfs/peer"
10
- testutil "github.com/jbenet/go-ipfs/util/testutil"
11
-
12
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
13
- mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
14
-)
15
-
16
-// ReverseHandler reverses all Data it receives and sends it back.
17
-type ReverseHandler struct{}
18
-
19
-func (t *ReverseHandler) HandleMessage(ctx context.Context, m msg.NetMessage) msg.NetMessage {
20
-
21
- d := m.Data()
22
- for i, j := 0, len(d)-1; i < j; i, j = i+1, j-1 {
23
- d[i], d[j] = d[j], d[i]
24
- }
25
-
26
- return msg.New(m.Peer(), d)
27
-}
28
-
29
-func newPeer(t *testing.T, id string) peer.Peer {
30
- mh, err := mh.FromHexString(id)
31
- if err != nil {
32
- t.Error(err)
33
- return nil
34
- }
35
-
36
- return testutil.NewPeerWithID(peer.ID(mh))
37
-}
38
-
39
-func TestServiceHandler(t *testing.T) {
40
- ctx := context.Background()
41
- h := &ReverseHandler{}
42
- s := NewService(ctx, h)
43
- peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa")
44
-
45
- d, err := wrapData([]byte("beep"), nil)
46
- if err != nil {
47
- t.Error(err)
48
- }
49
-
50
- m1 := msg.New(peer1, d)
51
- s.GetPipe().Incoming <- m1
52
- m2 := <-s.GetPipe().Outgoing
53
-
54
- d, rid, err := unwrapData(m2.Data())
55
- if err != nil {
56
- t.Error(err)
57
- }
58
-
59
- if rid != nil {
60
- t.Error("RequestID should be nil")
61
- }
62
-
63
- if !bytes.Equal(d, []byte("peeb")) {
64
- t.Errorf("service handler data incorrect: %v != %v", d, "oof")
65
- }
66
-}
67
-
68
-func TestServiceRequest(t *testing.T) {
69
- ctx := context.Background()
70
- s1 := NewService(ctx, &ReverseHandler{})
71
- s2 := NewService(ctx, &ReverseHandler{})
72
-
73
- peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa")
74
-
75
- // patch services together
76
- go func() {
77
- for {
78
- select {
79
- case m := <-s1.GetPipe().Outgoing:
80
- s2.GetPipe().Incoming <- m
81
- case m := <-s2.GetPipe().Outgoing:
82
- s1.GetPipe().Incoming <- m
83
- case <-ctx.Done():
84
- return
85
- }
86
- }
87
- }()
88
-
89
- m1 := msg.New(peer1, []byte("beep"))
90
- m2, err := s1.SendRequest(ctx, m1)
91
- if err != nil {
92
- t.Error(err)
93
- }
94
-
95
- if !bytes.Equal(m2.Data(), []byte("peeb")) {
96
- t.Errorf("service handler data incorrect: %v != %v", m2.Data(), "oof")
97
- }
98
-}
99
-
100
-func TestServiceRequestTimeout(t *testing.T) {
101
- ctx, _ := context.WithTimeout(context.Background(), time.Millisecond)
102
- s1 := NewService(ctx, &ReverseHandler{})
103
- s2 := NewService(ctx, &ReverseHandler{})
104
- peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa")
105
-
106
- // patch services together
107
- go func() {
108
- for {
109
- <-time.After(time.Millisecond)
110
- select {
111
- case m := <-s1.GetPipe().Outgoing:
112
- s2.GetPipe().Incoming <- m
113
- case m := <-s2.GetPipe().Outgoing:
114
- s1.GetPipe().Incoming <- m
115
- case <-ctx.Done():
116
- return
117
- }
118
- }
119
- }()
120
-
121
- m1 := msg.New(peer1, []byte("beep"))
122
- m2, err := s1.SendRequest(ctx, m1)
123
- if err == nil || m2 != nil {
124
- t.Error("should've timed out")
125
- }
126
-}
127
-
128
-func TestServiceClose(t *testing.T) {
129
- ctx := context.Background()
130
- s1 := NewService(ctx, &ReverseHandler{})
131
- s2 := NewService(ctx, &ReverseHandler{})
132
-
133
- peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa")
134
-
135
- // patch services together
136
- go func() {
137
- for {
138
- select {
139
- case m := <-s1.GetPipe().Outgoing:
140
- s2.GetPipe().Incoming <- m
141
- case m := <-s2.GetPipe().Outgoing:
142
- s1.GetPipe().Incoming <- m
143
- case <-ctx.Done():
144
- return
145
- }
146
- }
147
- }()
148
-
149
- m1 := msg.New(peer1, []byte("beep"))
150
- m2, err := s1.SendRequest(ctx, m1)
151
- if err != nil {
152
- t.Error(err)
153
- }
154
-
155
- if !bytes.Equal(m2.Data(), []byte("peeb")) {
156
- t.Errorf("service handler data incorrect: %v != %v", m2.Data(), "oof")
157
- }
158
-
159
- s1.Close()
160
- s2.Close()
161
-
162
- <-s1.Closed()
163
- <-s2.Closed()
164
-}
net/swarm/addrs.go
deleted
-120
@@ -1,120 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5
- "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
6
- "github.com/jbenet/go-ipfs/util/eventlog"
7
-
8
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9
-)
10
-
11
-// ListenAddresses returns a list of addresses at which this swarm listens.
12
-func (s *Swarm) ListenAddresses() []ma.Multiaddr {
13
- addrs := make([]ma.Multiaddr, len(s.listeners))
14
- for i, l := range s.listeners {
15
- addrs[i] = l.Multiaddr()
16
- }
17
- return addrs
18
-}
19
-
20
-// InterfaceListenAddresses returns a list of addresses at which this swarm
21
-// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
22
-// use the known local interfaces.
23
-func (s *Swarm) InterfaceListenAddresses() ([]ma.Multiaddr, error) {
24
- return resolveUnspecifiedAddresses(s.ListenAddresses())
25
-}
26
-
27
-// resolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
28
-// use the known local interfaces.
29
-func resolveUnspecifiedAddresses(unspecifiedAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
30
- var outputAddrs []ma.Multiaddr
31
-
32
- // todo optimize: only fetch these if we have a "any" addr.
33
- ifaceAddrs, err := interfaceAddresses()
34
- if err != nil {
35
- return nil, err
36
- }
37
-
38
- for _, a := range unspecifiedAddrs {
39
-
40
- // split address into its components
41
- split := ma.Split(a)
42
-
43
- // if first component (ip) is not unspecified, use it as is.
44
- if !manet.IsIPUnspecified(split[0]) {
45
- outputAddrs = append(outputAddrs, a)
46
- continue
47
- }
48
-
49
- // unspecified? add one address per interface.
50
- for _, ia := range ifaceAddrs {
51
- split[0] = ia
52
- joined := ma.Join(split...)
53
- outputAddrs = append(outputAddrs, joined)
54
- }
55
- }
56
-
57
- log.Event(context.TODO(), "interfaceListenAddresses", func() eventlog.Loggable {
58
- var addrs []string
59
- for _, addr := range outputAddrs {
60
- addrs = append(addrs, addr.String())
61
- }
62
- return eventlog.Metadata{"addresses": addrs}
63
- }())
64
- log.Debug("InterfaceListenAddresses:", outputAddrs)
65
- return outputAddrs, nil
66
-}
67
-
68
-// interfaceAddresses returns a list of addresses associated with local machine
69
-func interfaceAddresses() ([]ma.Multiaddr, error) {
70
- maddrs, err := manet.InterfaceMultiaddrs()
71
- if err != nil {
72
- return nil, err
73
- }
74
-
75
- var nonLoopback []ma.Multiaddr
76
- for _, a := range maddrs {
77
- if !manet.IsIPLoopback(a) {
78
- nonLoopback = append(nonLoopback, a)
79
- }
80
- }
81
-
82
- return nonLoopback, nil
83
-}
84
-
85
-// addrInList returns whether or not an address is part of a list.
86
-// this is useful to check if NAT is happening (or other bugs?)
87
-func addrInList(addr ma.Multiaddr, list []ma.Multiaddr) bool {
88
- for _, addr2 := range list {
89
- if addr.Equal(addr2) {
90
- return true
91
- }
92
- }
93
- return false
94
-}
95
-
96
-// checkNATWarning checks if our observed addresses differ. if so,
97
-// informs the user that certain things might not work yet
98
-func (s *Swarm) checkNATWarning(observed ma.Multiaddr, expected ma.Multiaddr) {
99
- if observed.Equal(expected) {
100
- return
101
- }
102
-
103
- listen, err := s.InterfaceListenAddresses()
104
- if err != nil {
105
- log.Errorf("Error retrieving swarm.InterfaceListenAddresses: %s", err)
106
- return
107
- }
108
-
109
- if !addrInList(observed, listen) { // probably a nat
110
- log.Warningf(natWarning, observed, listen)
111
- }
112
-}
113
-
114
-const natWarning = `Remote peer observed our address to be: %s
115
-The local addresses are: %s
116
-Thus, connection is going through NAT, and other connections may fail.
117
-
118
-IPFS NAT traversal is still under development. Please bug us on github or irc to fix this.
119
-Baby steps: http://jbenet.static.s3.amazonaws.com/271dfcf/baby-steps.gif
120
-`
net/swarm/simul_test.go
deleted
-80
@@ -1,80 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "fmt"
5
- "sync"
6
- "testing"
7
-
8
- peer "github.com/jbenet/go-ipfs/peer"
9
- "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 TestSimultOpen(t *testing.T) {
15
- // t.Skip("skipping for another test")
16
-
17
- addrs := []string{
18
- "/ip4/127.0.0.1/tcp/1244",
19
- "/ip4/127.0.0.1/tcp/1245",
20
- }
21
-
22
- ctx := context.Background()
23
- swarms, _ := makeSwarms(ctx, t, addrs)
24
-
25
- // connect everyone
26
- {
27
- var wg sync.WaitGroup
28
- connect := func(s *Swarm, dst peer.Peer) {
29
- // copy for other peer
30
- cp := testutil.NewPeerWithID(dst.ID())
31
- cp.AddAddress(dst.Addresses()[0])
32
-
33
- if _, err := s.Dial(cp); err != nil {
34
- t.Fatal("error swarm dialing to peer", err)
35
- }
36
- wg.Done()
37
- }
38
-
39
- log.Info("Connecting swarms simultaneously.")
40
- wg.Add(2)
41
- go connect(swarms[0], swarms[1].local)
42
- go connect(swarms[1], swarms[0].local)
43
- wg.Wait()
44
- }
45
-
46
- for _, s := range swarms {
47
- s.Close()
48
- }
49
-}
50
-
51
-func TestSimultOpenMany(t *testing.T) {
52
- t.Skip("very very slow")
53
-
54
- many := 500
55
- addrs := []string{}
56
- for i := 2200; i < (2200 + many); i++ {
57
- s := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", i)
58
- addrs = append(addrs, s)
59
- }
60
-
61
- SubtestSwarm(t, addrs, 10)
62
-}
63
-
64
-func TestSimultOpenFewStress(t *testing.T) {
65
- if testing.Short() {
66
- t.SkipNow()
67
- }
68
- // t.Skip("skipping for another test")
69
-
70
- num := 10
71
- // num := 100
72
- for i := 0; i < num; i++ {
73
- addrs := []string{
74
- fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 1900+i),
75
- fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 2900+i),
76
- }
77
-
78
- SubtestSwarm(t, addrs, 10)
79
- }
80
-}
net/swarm/swarm.go
deleted
-193
@@ -1,193 +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
- "errors"
7
- "fmt"
8
-
9
- conn "github.com/jbenet/go-ipfs/net/conn"
10
- peer "github.com/jbenet/go-ipfs/peer"
11
- "github.com/jbenet/go-ipfs/util/eventlog"
12
-
13
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
14
- context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
15
- ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
16
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
17
-)
18
-
19
-var log = eventlog.Logger("swarm")
20
-
21
-// ErrAlreadyOpen signals that a connection to a peer is already open.
22
-var ErrAlreadyOpen = errors.New("Error: Connection to this peer already open.")
23
-
24
-// ListenErr contains a set of errors mapping to each of the swarms addresses.
25
-// Used to return multiple errors, as in listen.
26
-type ListenErr struct {
27
- Errors []error
28
-}
29
-
30
-func (e *ListenErr) Error() string {
31
- if e == nil {
32
- return "<nil error>"
33
- }
34
- var out string
35
- for i, v := range e.Errors {
36
- if v != nil {
37
- out += fmt.Sprintf("%d: %s\n", i, v)
38
- }
39
- }
40
- return out
41
-}
42
-
43
-// Swarm is a connection muxer, allowing connections to other peers to
44
-// be opened and closed, while still using the same Chan for all
45
-// communication. The Chan sends/receives Messages, which note the
46
-// destination or source Peer.
47
-//
48
-// Implements router.Node
49
-type Swarm struct {
50
-
51
- // local is the peer this swarm represents
52
- local peer.Peer
53
-
54
- // peers is a collection of peers for swarm to use
55
- peers peer.Peerstore
56
-
57
- // rt handles the open connections the swarm is handling.
58
- rt *swarmRoutingTable
59
-
60
- // listeners for each network address
61
- listeners []conn.Listener
62
-
63
- // ContextGroup
64
- cg ctxgroup.ContextGroup
65
-}
66
-
67
-// NewSwarm constructs a Swarm, with a Chan.
68
-func NewSwarm(ctx context.Context, listenAddrs []ma.Multiaddr,
69
- local peer.Peer, ps peer.Peerstore, client router.Node) (*Swarm, error) {
70
-
71
- s := &Swarm{
72
- local: local,
73
- peers: ps,
74
- cg: ctxgroup.WithContext(ctx),
75
- rt: newRoutingTable(local, client),
76
- }
77
-
78
- s.cg.SetTeardown(s.close)
79
- return s, s.listen(listenAddrs)
80
-}
81
-
82
-// SetClient assign's the Swarm's client node.
83
-func (s *Swarm) SetClient(n router.Node) {
84
- s.rt.client = n
85
-}
86
-
87
-// Close stops a swarm. waits till it exits
88
-func (s *Swarm) Close() error {
89
- return s.cg.Close()
90
-}
91
-
92
-// close stops a swarm. It's the underlying function called by ContextGroup
93
-func (s *Swarm) close() error {
94
- // close listeners
95
- for _, list := range s.listeners {
96
- list.Close()
97
- }
98
- // close connections
99
- conn.CloseConns(s.Connections()...)
100
- return nil
101
-}
102
-
103
-// Dial connects to a peer.
104
-//
105
-// The idea is that the client of Swarm does not need to know what network
106
-// the connection will happen over. Swarm can use whichever it choses.
107
-// This allows us to use various transport protocols, do NAT traversal/relay,
108
-// etc. to achive connection.
109
-//
110
-// For now, Dial uses only TCP. This will be extended.
111
-func (s *Swarm) Dial(peer peer.Peer) (conn.Conn, error) {
112
- if peer.ID().Equal(s.local.ID()) {
113
- return nil, errors.New("Attempted connection to self!")
114
- }
115
-
116
- // check if we already have an open connection first
117
- c := s.GetConnection(peer.ID())
118
- if c != nil {
119
- return c, nil
120
- }
121
-
122
- // check if we don't have the peer in Peerstore
123
- peer, err := s.peers.Add(peer)
124
- if err != nil {
125
- return nil, err
126
- }
127
-
128
- // open connection to peer
129
- d := &conn.Dialer{
130
- LocalPeer: s.local,
131
- Peerstore: s.peers,
132
- }
133
-
134
- if len(peer.Addresses()) == 0 {
135
- return nil, errors.New("peer has no addresses")
136
- }
137
- // try to connect to one of the peer's known addresses.
138
- // for simplicity, we do this sequentially.
139
- // A future commit will do this asynchronously.
140
- for _, addr := range peer.Addresses() {
141
- c, err = d.DialAddr(s.cg.Context(), addr, peer)
142
- if err == nil {
143
- break
144
- }
145
- }
146
- if err != nil {
147
- return nil, err
148
- }
149
-
150
- c2, err := s.connSetup(context.TODO(), c)
151
- if err != nil {
152
- c.Close()
153
- return nil, err
154
- }
155
-
156
- // TODO replace the TODO ctx with a context passed in from caller
157
- log.Event(context.TODO(), "dial", peer)
158
- return c2, nil
159
-}
160
-
161
-// GetConnection returns the connection in the swarm to given peer.ID
162
-func (s *Swarm) GetConnection(pid peer.ID) conn.Conn {
163
- sp := s.rt.getByID(pid)
164
- if sp == nil {
165
- return nil
166
- }
167
- return sp.conn
168
-}
169
-
170
-// Connections returns a slice of all connections.
171
-func (s *Swarm) Connections() []conn.Conn {
172
- return s.rt.connList()
173
-}
174
-
175
-// CloseConnection removes a given peer from swarm + closes the connection
176
-func (s *Swarm) CloseConnection(p peer.Peer) error {
177
- return s.closeConn(p)
178
-}
179
-
180
-// GetPeerList returns a copy of the set of peers swarm is connected to.
181
-func (s *Swarm) GetPeerList() []peer.Peer {
182
- return s.rt.peerList()
183
-}
184
-
185
-// LocalPeer returns the local peer swarm is associated to.
186
-func (s *Swarm) LocalPeer() peer.Peer {
187
- return s.local
188
-}
189
-
190
-// Address returns the address of *this* service.
191
-func (s *Swarm) Address() router.Address {
192
- return "/ipfs/service/swarm" // for now dont need anything more complicated.
193
-}
net/swarm/swarm_conn.go
deleted
-128
@@ -1,128 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "errors"
5
- "fmt"
6
-
7
- conn "github.com/jbenet/go-ipfs/net/conn"
8
-
9
- ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
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
-// Open listeners for each network the swarm should listen on
15
-func (s *Swarm) listen(addrs []ma.Multiaddr) error {
16
- hasErr := false
17
- retErr := &ListenErr{
18
- Errors: make([]error, len(addrs)),
19
- }
20
-
21
- // listen on every address
22
- for i, addr := range addrs {
23
- err := s.connListen(addr)
24
- if err != nil {
25
- hasErr = true
26
- retErr.Errors[i] = err
27
- log.Errorf("Failed to listen on: %s - %s", addr, err)
28
- }
29
- }
30
-
31
- if hasErr {
32
- return retErr
33
- }
34
- return nil
35
-}
36
-
37
-// Listen for new connections on the given multiaddr
38
-func (s *Swarm) connListen(maddr ma.Multiaddr) error {
39
-
40
- resolved, err := resolveUnspecifiedAddresses([]ma.Multiaddr{maddr})
41
- if err != nil {
42
- return err
43
- }
44
-
45
- list, err := conn.Listen(s.cg.Context(), maddr, s.local, s.peers)
46
- if err != nil {
47
- return err
48
- }
49
-
50
- // add resolved local addresses to peer
51
- for _, addr := range resolved {
52
- s.local.AddAddress(addr)
53
- }
54
-
55
- // make sure port can be reused. TOOD this doesn't work...
56
- // if err := setSocketReuse(list); err != nil {
57
- // return err
58
- // }
59
-
60
- // NOTE: this may require a lock around it later. currently, only run on setup
61
- s.listeners = append(s.listeners, list)
62
-
63
- // Accept and handle new connections on this listener until it errors
64
- // this listener is a child.
65
- s.cg.AddChildFunc(func(parent ctxgroup.ContextGroup) {
66
- for {
67
- select {
68
- case <-parent.Closing():
69
- return
70
-
71
- case conn := <-list.Accept():
72
- s.handleIncomingConn(parent.Context(), conn)
73
- }
74
- }
75
- })
76
-
77
- return nil
78
-}
79
-
80
-// Handle getting ID from this peer, handshake, and adding it into the map
81
-func (s *Swarm) handleIncomingConn(ctx context.Context, nconn conn.Conn) {
82
- // Setup the new connection
83
- _, err := s.connSetup(ctx, nconn)
84
- if err != nil {
85
- log.Errorf("swarm: failed to add incoming connection: %s", err)
86
- log.Event(ctx, "handleIncomingConn failed", s.LocalPeer(), nconn.RemotePeer())
87
- nconn.Close()
88
- }
89
-}
90
-
91
-// connSetup takes a new connection, performs the IPFS handshake (handshake3)
92
-// and then adds it to the appropriate MultiConn.
93
-func (s *Swarm) connSetup(ctx context.Context, c conn.Conn) (conn.Conn, error) {
94
- if c == nil {
95
- return nil, errors.New("Tried to start nil connection.")
96
- }
97
-
98
- log.Event(ctx, "connSetupBegin", c.LocalPeer(), c.RemotePeer())
99
-
100
- // add address of connection to Peer. Maybe it should happen in connSecure.
101
- // NOT adding this address here, because the incoming address in TCP
102
- // is an EPHEMERAL address, and not the address we want to keep around.
103
- // addresses should be figured out through the DHT.
104
- // c.Remote.AddAddress(c.Conn.RemoteMultiaddr())
105
-
106
- // handshake3
107
- ctxT, _ := context.WithTimeout(c.Context(), conn.HandshakeTimeout)
108
- h3result, err := conn.Handshake3(ctxT, c)
109
- if err != nil {
110
- c.Close()
111
- return nil, fmt.Errorf("Handshake3 failed: %s", err)
112
- }
113
-
114
- // check for nats. you know, just in case.
115
- if h3result.LocalObservedAddress != nil {
116
- s.checkNATWarning(h3result.LocalObservedAddress, c.LocalMultiaddr())
117
- } else {
118
- log.Warningf("Received nil observed address from %s", c.RemotePeer())
119
- }
120
-
121
- // add to conns
122
- if err := s.addConn(c); err != nil {
123
- c.Close()
124
- return nil, err
125
- }
126
- log.Event(ctx, "connSetupSuccess", c.LocalPeer(), c.RemotePeer())
127
- return c, nil
128
-}
net/swarm/swarm_peer.go
deleted
-178
@@ -1,178 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "fmt"
5
-
6
- conn "github.com/jbenet/go-ipfs/net/conn"
7
- netmsg "github.com/jbenet/go-ipfs/net/message"
8
- peer "github.com/jbenet/go-ipfs/peer"
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
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
13
-)
14
-
15
-// MaxConcurrentRequestsPerPeer defines the pipelining that we can do per-peer.
16
-// the networking layer makes sure to provide proper backpressure to the remote
17
-// side by only handling a max number of concurrent requests to completion.
18
-const MaxConcurrentRequestsPerPeer = 20
19
-
20
-// swarmPeer represents a connection to the outside world.
21
-// Implements router.Node
22
-type swarmPeer struct {
23
- swarm *Swarm
24
- conn *conn.MultiConn
25
- cg ctxgroup.ContextGroup
26
-}
27
-
28
-// newSwarmPeer constructs a new swarmPeer, and starts is worker.
29
-// this doesn't connect it, or add it to the swarm's routing table.
30
-// Implements router.Node
31
-func newSwarmPeer(s *Swarm, p peer.Peer) (*swarmPeer, error) {
32
- c, err := conn.NewMultiConn(s.cg.Context(), s.LocalPeer(), p, nil)
33
- if err != nil {
34
- return nil, fmt.Errorf("Error creating MultiConn: %s", err)
35
- }
36
-
37
- sp := &swarmPeer{
38
- swarm: s,
39
- conn: c,
40
- cg: ctxgroup.WithParent(s.cg), // swarmPeer closes when swarm closes.
41
- }
42
-
43
- // kicks off the worker.
44
- // ctggroup makes sure swarmPeer doesn't close until this func returns
45
- sp.cg.AddChildFunc(sp.listen)
46
- return sp, nil
47
-}
48
-
49
-// LocalPeer returns the local peer
50
-func (sp *swarmPeer) LocalPeer() peer.Peer {
51
- return sp.conn.LocalPeer()
52
-}
53
-
54
-// RemotePeer returns the peer we're connected to.
55
-func (sp *swarmPeer) RemotePeer() peer.Peer {
56
- return sp.conn.RemotePeer()
57
-}
58
-
59
-// Address is the peer's ID
60
-func (sp *swarmPeer) Address() router.Address {
61
- return sp.RemotePeer()
62
-}
63
-
64
-// Close closes the swarmPeer service
65
-func (sp *swarmPeer) Close() error {
66
- return sp.cg.Close()
67
-}
68
-
69
-// list to the multiconn and route packets in.
70
-func (sp *swarmPeer) listen(parent ctxgroup.ContextGroup) {
71
-
72
- // we listen and pipeline using:
73
- // - 1x listener (this function, the for loop below)
74
- // - 1x pipelining semaphore
75
- // - up to Nx goroutine pipeline workers
76
- // this approach is chosen over N persistent goroutines because
77
- // spawning a goroutine every time is cheaper than keeping N
78
- // additional goroutines all the time, for inactive connections
79
-
80
- pipelineSema := make(chan struct{}, MaxConcurrentRequestsPerPeer)
81
- for i := 0; i < MaxConcurrentRequestsPerPeer; i++ {
82
- pipelineSema <- struct{}{}
83
- }
84
-
85
- // the sad part of using io is we still need to consume msgs
86
- // using a context-less api, which means we need to use an
87
- // extra goroutine, to make sure we close the connection and
88
- // unlock our blocked listener.
89
- // (the Context just does not mix well with io.ReadWriters)
90
- // - conn.SetDeadline could be explored
91
- go func() {
92
- <-parent.Closing()
93
- sp.conn.Close()
94
- }()
95
-
96
- listener := func() {
97
- for {
98
- msg, err := sp.conn.ReadMsg()
99
- // we want this to happen before checking the error, as we may
100
- // be closing (which is not an error). any last message is dropped.
101
- select {
102
- case <-parent.Closing():
103
- return
104
- case <-sp.conn.Closing():
105
- return
106
- default:
107
- }
108
-
109
- if err != nil {
110
- log.Errorf("error receiving message from multiconn: %s", err)
111
- continue
112
- }
113
-
114
- select {
115
- case <-parent.Closing():
116
- return
117
- case <-pipelineSema: // acquire pipelining resource
118
- go func(m []byte) {
119
- sp.handleIncomingMessage(parent.Context(), m)
120
- pipelineSema <- struct{}{}
121
- }(msg)
122
- }
123
- }
124
- }
125
-
126
- // function call so that we can isolate the functionality,
127
- // and so we can call return in loops above and not confuse flow.
128
- listener()
129
-}
130
-
131
-func (sp *swarmPeer) handleIncomingMessage(ctx context.Context, msg []byte) {
132
- // handle incoming message message.
133
- // we derive a new context for this incoming request.
134
- ctx, _ = context.WithCancel(ctx)
135
-
136
- p := netmsg.Packet{
137
- Src: sp.RemotePeer(),
138
- Dst: sp.swarm.client().Address(),
139
- Data: msg,
140
- Context: ctx,
141
- }
142
-
143
- // We also can't yet pass unread io.RW to the clients directly.
144
- // muxado, SPDY, QUIC, and other stream multiplexors could
145
- // make this a breeze.
146
-
147
- // this runs the entire request. it should not return until ALL action
148
- // is done. this is so that we rate limit and respond to backpressure well.
149
- // TODO: pipelining (handle up to N concurrent requests).
150
- // doing pipelining with SPDY or muxado is probably TRTTD.
151
- if err := sp.HandlePacket(&p, nil); err != nil {
152
- log.Errorf("error handling incoming request: %v", err)
153
- }
154
-
155
- // should be done with the underlying bytes. release (the kraken)!
156
- // TODO: enable this. there is a bug relating to mpool or something. swarm_tests fail.
157
- // sp.conn.ReleaseMsg(msg)
158
-}
159
-
160
-func (sp *swarmPeer) HandlePacket(p router.Packet, n router.Node) error {
161
- switch p.Destination() {
162
- case sp.swarm.client().Address(): // incoming
163
- return sp.swarm.HandlePacket(p, sp)
164
-
165
- case sp.RemotePeer(): // outgoing
166
- buf, ok := p.Payload().([]byte)
167
- if !ok {
168
- return netmsg.ErrInvalidPayload
169
- }
170
- if err := sp.conn.WriteMsg(buf); err != nil {
171
- return fmt.Errorf("swarmPeer error sending: %s", err)
172
- }
173
- return nil
174
-
175
- default: // problem
176
- return fmt.Errorf("swarmPeer routing error: %v got %v", sp, p)
177
- }
178
-}
net/swarm/swarm_rt.go
deleted
-159
@@ -1,159 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "sync"
5
-
6
- conn "github.com/jbenet/go-ipfs/net/conn"
7
- netmsg "github.com/jbenet/go-ipfs/net/message"
8
- peer "github.com/jbenet/go-ipfs/peer"
9
- u "github.com/jbenet/go-ipfs/util"
10
-
11
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
12
-)
13
-
14
-// swarmRoutingTable collects the peers
15
-type swarmRoutingTable struct {
16
- local peer.Peer
17
- client router.Node
18
- peers map[u.Key]*swarmPeer
19
- sync.RWMutex
20
-}
21
-
22
-func newRoutingTable(local peer.Peer, client router.Node) *swarmRoutingTable {
23
- return &swarmRoutingTable{
24
- local: local,
25
- client: client,
26
- peers: map[u.Key]*swarmPeer{},
27
- }
28
-}
29
-
30
-func (rt *swarmRoutingTable) getOrAdd(s *Swarm, p peer.Peer) (*swarmPeer, error) {
31
- rt.Lock()
32
- defer rt.Unlock()
33
-
34
- sp, ok := rt.peers[p.Key()]
35
- if ok {
36
- return sp, nil
37
- }
38
-
39
- // newSwarmPeer is what kicks off the reader goroutines.
40
- sp, err := newSwarmPeer(s, p)
41
- if err != nil {
42
- return nil, err
43
- }
44
- rt.peers[p.Key()] = sp
45
- return sp, nil
46
-}
47
-
48
-func (rt *swarmRoutingTable) remove(p peer.Peer) *swarmPeer {
49
- rt.Lock()
50
- defer rt.Unlock()
51
- sp, ok := rt.peers[p.Key()]
52
- if ok {
53
- delete(rt.peers, p.Key())
54
- }
55
- return sp
56
-}
57
-
58
-func (rt *swarmRoutingTable) getByID(pid peer.ID) *swarmPeer {
59
- rt.RLock()
60
- defer rt.RUnlock()
61
- return rt.peers[u.Key(pid)]
62
-}
63
-
64
-func (rt *swarmRoutingTable) get(p peer.Peer) *swarmPeer {
65
- rt.RLock()
66
- defer rt.RUnlock()
67
- return rt.peers[p.Key()]
68
-}
69
-
70
-func (rt *swarmRoutingTable) connList() []conn.Conn {
71
- rt.RLock()
72
- defer rt.RUnlock()
73
-
74
- var out []conn.Conn
75
- for _, sp := range rt.peers {
76
- out = append(out, sp.conn)
77
- }
78
- return out
79
-}
80
-
81
-func (rt *swarmRoutingTable) peerList() []peer.Peer {
82
- rt.RLock()
83
- defer rt.RUnlock()
84
-
85
- var out []peer.Peer
86
- for _, sp := range rt.peers {
87
- out = append(out, sp.RemotePeer())
88
- }
89
- return out
90
-}
91
-
92
-// Route implements routing.Route
93
-func (rt *swarmRoutingTable) Route(p router.Packet) router.Node {
94
-
95
- // no need to lock :)
96
- if p.Destination() == rt.client.Address() {
97
- // log.Debugf("%s swarmRoutingTable route %s to client %s ? ", p.Destination(), rt.client.Address(), p.Payload())
98
- return rt.client
99
- }
100
-
101
- rt.RLock()
102
- defer rt.RUnlock()
103
-
104
- for _, sp := range rt.peers {
105
- if sp.RemotePeer() == p.Destination() {
106
- // log.Debugf("%s swarmRoutingTable route %s to peer %s ? ", p.Destination(), sp.RemotePeer(), p.Payload())
107
- return sp
108
- }
109
- }
110
-
111
- return nil // no route
112
-}
113
-
114
-func (s *Swarm) client() router.Node {
115
- return s.rt.client
116
-}
117
-
118
-func (s *Swarm) addConn(c conn.Conn) error {
119
- sp, err := s.rt.getOrAdd(s, c.RemotePeer())
120
- if err != nil {
121
- return err
122
- }
123
-
124
- sp.conn.Add(c)
125
- return nil
126
-}
127
-
128
-func (s *Swarm) closeConn(p peer.Peer) error {
129
- sp := s.rt.remove(p)
130
- if sp == nil {
131
- return nil
132
- }
133
-
134
- return sp.Close()
135
-}
136
-
137
-// HandlePacket routes messages out through connections, or to the client
138
-func (s *Swarm) HandlePacket(p router.Packet, from router.Node) error {
139
- msg, ok := p.Payload().([]byte)
140
- if !ok {
141
- return netmsg.ErrInvalidPayload
142
- }
143
-
144
- if len(msg) >= conn.MaxMessageSize {
145
- log.Criticalf("Attempted to send message bigger than max size. (%d)", len(msg))
146
- }
147
-
148
- next := s.rt.Route(p)
149
- if next == nil {
150
- // log.Debugf("%s swarm HandlePacket %s -> %s -> %s -> %s: %s",
151
- // s.local, from.Address(), s.Address(), "????", p.Destination(), p.Payload())
152
- return router.ErrNoRoute
153
- }
154
-
155
- // log.Debugf("%s swarm HandlePacket %s -> %s -> %s -> %s: %s",
156
- // s.local, from.Address(), s.Address(), next.Address(), p.Destination(), p.Payload())
157
-
158
- return next.HandlePacket(p, s)
159
-}
net/swarm/swarm_test.go
deleted
-252
@@ -1,252 +0,0 @@
1
-package swarm
2
-
3
-import (
4
- "bytes"
5
- "sync"
6
- "testing"
7
- "time"
8
-
9
- ci "github.com/jbenet/go-ipfs/crypto"
10
- netmsg "github.com/jbenet/go-ipfs/net/message"
11
- peer "github.com/jbenet/go-ipfs/peer"
12
- u "github.com/jbenet/go-ipfs/util"
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
- router "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-router"
18
-)
19
-
20
-// needed to copy the data. otherwise gets reused... :/
21
-type queueClient struct {
22
- addr router.Address
23
- queue chan *netmsg.Packet
24
-}
25
-
26
-func newQueueClient(addr router.Address) *queueClient {
27
- return &queueClient{addr, make(chan *netmsg.Packet, 20)}
28
-}
29
-
30
-func (qc *queueClient) Address() router.Address {
31
- return qc.addr
32
-}
33
-
34
-func (qc *queueClient) HandlePacket(p router.Packet, n router.Node) error {
35
-
36
- pkt1 := p.(*netmsg.Packet)
37
- pkt2 := netmsg.Packet{}
38
- pkt2 = *pkt1
39
- pkt2.Data = make([]byte, len(pkt1.Data))
40
- copy(pkt2.Data, pkt1.Data)
41
-
42
- qc.queue <- &pkt2
43
- return nil
44
-}
45
-
46
-type pongClient struct {
47
- peer peer.Peer
48
- count int
49
- queue chan pongPkt
50
-}
51
-
52
-type pongPkt struct {
53
- msg netmsg.Packet
54
- dst router.Node
55
-}
56
-
57
-func newPongClient(ctx context.Context, peer peer.Peer) *pongClient {
58
- pc := &pongClient{peer: peer, queue: make(chan pongPkt, 10)}
59
- go pc.echo(ctx)
60
- return pc
61
-}
62
-
63
-func (pc *pongClient) Address() router.Address {
64
- return pc.peer.ID().Pretty() + "/pong"
65
-}
66
-
67
-func (pc *pongClient) HandlePacket(p router.Packet, n router.Node) error {
68
- pkt1 := p.(*netmsg.Packet)
69
- if !bytes.Equal(pkt1.Data, []byte("ping")) {
70
- log.Debugf("%s pong dropped pkt: %s (%s -> %s)", pc.Address(), pkt1.Data, pkt1.Src, pkt1.Dst)
71
- panic("why")
72
- return nil // drop
73
- }
74
-
75
- pc.queue <- pongPkt{pkt1.Response([]byte("pong")), n}
76
- return nil
77
-}
78
-
79
-func (pc *pongClient) echo(ctx context.Context) {
80
- for {
81
- select {
82
- case <-ctx.Done():
83
- return
84
-
85
- case pkt := <-pc.queue:
86
- pc.count++
87
- log.Debugf("%s pong %s (%d)", pkt.msg.Src, pkt.msg.Dst, pc.count)
88
- if err := pkt.dst.HandlePacket(&pkt.msg, pc); err != nil {
89
- log.Errorf("pong error sending: %s", err)
90
- }
91
- }
92
- }
93
-}
94
-
95
-func setupPeer(t *testing.T, addr string) peer.Peer {
96
- tcp, err := ma.NewMultiaddr(addr)
97
- if err != nil {
98
- t.Fatal(err)
99
- }
100
-
101
- sk, pk, err := ci.GenerateKeyPair(ci.RSA, 512)
102
- if err != nil {
103
- t.Fatal(err)
104
- }
105
-
106
- p, err := testutil.NewPeerWithKeyPair(sk, pk)
107
- if err != nil {
108
- t.Fatal(err)
109
- }
110
- p.AddAddress(tcp)
111
- return p
112
-}
113
-
114
-func makeSwarms(ctx context.Context, t *testing.T, addrs []string) ([]*Swarm, []peer.Peer) {
115
- swarms := []*Swarm{}
116
-
117
- for _, addr := range addrs {
118
- local := setupPeer(t, addr)
119
- peerstore := peer.NewPeerstore()
120
- pong := newPongClient(ctx, local)
121
- swarm, err := NewSwarm(ctx, local.Addresses(), local, peerstore, pong)
122
- if err != nil {
123
- t.Fatal(err)
124
- }
125
- swarms = append(swarms, swarm)
126
- }
127
-
128
- peers := make([]peer.Peer, len(swarms))
129
- for i, s := range swarms {
130
- peers[i] = s.local
131
- }
132
-
133
- return swarms, peers
134
-}
135
-
136
-func SubtestSwarm(t *testing.T, addrs []string, MsgNum int) {
137
- // t.Skip("skipping for another test")
138
-
139
- ctx := context.Background()
140
- swarms, peers := makeSwarms(ctx, t, addrs)
141
-
142
- // connect everyone
143
- {
144
- var wg sync.WaitGroup
145
- connect := func(s *Swarm, dst peer.Peer) {
146
- // copy for other peer
147
-
148
- cp, err := s.peers.FindOrCreate(dst.ID())
149
- if err != nil {
150
- t.Fatal(err)
151
- }
152
- cp.AddAddress(dst.Addresses()[0])
153
-
154
- log.Infof("SWARM TEST: %s dialing %s", s.local, dst)
155
- if _, err := s.Dial(cp); err != nil {
156
- t.Fatal("error swarm dialing to peer", err)
157
- }
158
- log.Infof("SWARM TEST: %s connected to %s", s.local, dst)
159
- wg.Done()
160
- }
161
-
162
- log.Info("Connecting swarms simultaneously.")
163
- for _, s := range swarms {
164
- for _, p := range peers {
165
- if p != s.local { // don't connect to self.
166
- wg.Add(1)
167
- connect(s, p)
168
- }
169
- }
170
- }
171
- wg.Wait()
172
-
173
- for _, s := range swarms {
174
- log.Infof("%s swarm routing table: %s", s.local, s.GetPeerList())
175
- }
176
- }
177
-
178
- // ping/pong
179
- for _, s1 := range swarms {
180
- log.Debugf("-------------------------------------------------------")
181
- log.Debugf("%s ping pong round", s1.local)
182
- log.Debugf("-------------------------------------------------------")
183
-
184
- // for this test, we'll listen on s1.
185
- queue := newQueueClient(s1.client().Address())
186
- pong := s1.client() // set it back at the end.
187
- s1.SetClient(queue)
188
-
189
- ctx, cancel := context.WithCancel(ctx)
190
- peers, err := s1.peers.All()
191
- if err != nil {
192
- t.Fatal(err)
193
- }
194
-
195
- for k := 0; k < MsgNum; k++ {
196
- for _, p := range *peers {
197
- log.Debugf("%s ping %s (%d)", s1.local, p, k)
198
- pkt := netmsg.Packet{Src: s1.local, Dst: p, Data: []byte("ping"), Context: ctx}
199
- s1.HandlePacket(&pkt, queue)
200
- }
201
- }
202
-
203
- got := map[u.Key]int{}
204
- for k := 0; k < (MsgNum * len(*peers)); k++ {
205
- log.Debugf("%s waiting for pong (%d)", s1.local, k)
206
-
207
- msg := <-queue.queue
208
- if string(msg.Data) != "pong" {
209
- t.Error("unexpected conn output", string(msg.Data), msg.Data)
210
- }
211
-
212
- p := msg.Src.(peer.Peer)
213
- n, _ := got[p.Key()]
214
- got[p.Key()] = n + 1
215
- }
216
-
217
- log.Debugf("%s got pongs", s1.local)
218
- if len(*peers) != len(got) {
219
- t.Error("got less messages than sent")
220
- }
221
-
222
- for p, n := range got {
223
- if n != MsgNum {
224
- t.Error("peer did not get all msgs", p, n, "/", MsgNum)
225
- }
226
- }
227
-
228
- cancel()
229
- <-time.After(10 * time.Millisecond)
230
- s1.SetClient(pong)
231
- }
232
-
233
- for _, s := range swarms {
234
- s.Close()
235
- }
236
-}
237
-
238
-func TestSwarm(t *testing.T) {
239
- // t.Skip("skipping for another test")
240
-
241
- addrs := []string{
242
- "/ip4/127.0.0.1/tcp/10234",
243
- "/ip4/127.0.0.1/tcp/10235",
244
- "/ip4/127.0.0.1/tcp/10236",
245
- "/ip4/127.0.0.1/tcp/10237",
246
- "/ip4/127.0.0.1/tcp/10238",
247
- }
248
-
249
- // msgs := 1000
250
- msgs := 100
251
- SubtestSwarm(t, addrs, msgs)
252
-}