1
1
package dht
2
2
3
3
import (
4
+ "sync"
5
+
6
+ peer "github.com/jbenet/go-ipfs/peer"
4
7
swarm "github.com/jbenet/go-ipfs/swarm"
5
8
u "github.com/jbenet/go-ipfs/util"
6
9
"code.google.com/p/goprotobuf/proto"
7
- "sync"
8
10
)
9
11
10
12
// TODO. SEE https://github.com/jbenet/node-ipfs/blob/master/submodules/ipfs-dht/index.js
@@ -16,6 +18,9 @@ type IpfsDHT struct {
16
18
17
19
network * swarm.Swarm
18
20
21
+ // local data (TEMPORARY: until we formalize data storage with datastore)
22
+ data map [string ][]byte
23
+
19
24
// map of channels waiting for reply messages
20
25
listeners map [uint64 ]chan * swarm.Message
21
26
listenLock sync.RWMutex
@@ -38,22 +43,28 @@ func (dht *IpfsDHT) handleMessages() {
38
43
}
39
44
40
45
// Note: not sure if this is the correct place for this
41
- dht .listenLock .RLock ()
42
- ch , ok := dht .listeners [pmes .GetId ()]
43
- dht .listenLock .RUnlock ()
44
- if ok {
45
- ch <- mes
46
+ if pmes .GetResponse () {
47
+ dht .listenLock .RLock ()
48
+ ch , ok := dht .listeners [pmes .GetId ()]
49
+ dht .listenLock .RUnlock ()
50
+ if ok {
51
+ ch <- mes
52
+ }
53
+
54
+ // this is expected behaviour during a timeout
55
+ u .DOut ("Received response with nobody listening..." )
56
+ continue
46
57
}
47
58
//
48
59
49
- // Do something else with the messages?
50
60
switch pmes .GetType () {
51
- case DHTMessage_ADD_PROVIDER :
61
+ case DHTMessage_GET_VALUE :
62
+ dht .handleGetValue (mes .Peer , pmes )
63
+ case DHTMessage_PUT_VALUE :
52
64
case DHTMessage_FIND_NODE :
65
+ case DHTMessage_ADD_PROVIDER :
53
66
case DHTMessage_GET_PROVIDERS :
54
- case DHTMessage_GET_VALUE :
55
67
case DHTMessage_PING :
56
- case DHTMessage_PUT_VALUE :
57
68
}
58
69
59
70
case <- dht .shutdown :
@@ -62,6 +73,44 @@ func (dht *IpfsDHT) handleMessages() {
62
73
}
63
74
}
64
75
76
+ func (dht * IpfsDHT ) handleGetValue (p * peer.Peer , pmes * DHTMessage ) {
77
+ val , found := dht .data [pmes .GetKey ()]
78
+ if found {
79
+ isResponse := true
80
+ resp := new (DHTMessage )
81
+ resp .Response = & isResponse
82
+ resp .Id = pmes .Id
83
+ resp .Key = pmes .Key
84
+ resp .Value = val
85
+ } else {
86
+ // Find closest node(s) to desired key and reply with that info
87
+ // TODO: this will need some other metadata in the protobuf message
88
+ // to signal to the querying node that the data its receiving
89
+ // is actually a list of other nodes
90
+ }
91
+ }
92
+
93
+ func (dht * IpfsDHT ) handlePutValue (p * peer.Peer , pmes * DHTMessage ) {
94
+ panic ("Not implemented." )
95
+ }
96
+
97
+ func (dht * IpfsDHT ) handleFindNode (p * peer.Peer , pmes * DHTMessage ) {
98
+ panic ("Not implemented." )
99
+ }
100
+
101
+ func (dht * IpfsDHT ) handlePing (p * peer.Peer , pmes * DHTMessage ) {
102
+ isResponse := true
103
+ resp := new (DHTMessage )
104
+ resp .Id = pmes .Id
105
+ resp .Response = & isResponse
106
+
107
+ mes := new (swarm.Message )
108
+ mes .Peer = p
109
+ mes .Data = []byte (resp .String ())
110
+ dht .network .Chan .Outgoing <- mes
111
+ }
112
+
113
+
65
114
// Register a handler for a specific message ID, used for getting replies
66
115
// to certain messages (i.e. response to a GET_VALUE message)
67
116
func (dht * IpfsDHT ) ListenFor (mesid uint64 ) <- chan * swarm.Message {
@@ -71,3 +120,9 @@ func (dht *IpfsDHT) ListenFor(mesid uint64) <-chan *swarm.Message {
71
120
dht .listenLock .Unlock ()
72
121
return lchan
73
122
}
123
+
124
+ // Stop all communications from this node and shut down
125
+ func (dht * IpfsDHT ) Halt () {
126
+ dht .shutdown <- struct {}{}
127
+ dht .network .Close ()
128
+ }
0 commit comments