@cryptotaxi247 / kubo / commits / c63ffdd0a

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 -}