@@ -3,9 +3,12 @@ package dht
3
3
import (
4
4
"sync"
5
5
6
- peer "github.com/jbenet/go-ipfs/peer"
7
- swarm "github.com/jbenet/go-ipfs/swarm"
8
- u "github.com/jbenet/go-ipfs/util"
6
+ peer "github.com/jbenet/go-ipfs/peer"
7
+ swarm "github.com/jbenet/go-ipfs/swarm"
8
+ u "github.com/jbenet/go-ipfs/util"
9
+
10
+ ds "github.com/jbenet/datastore.go"
11
+
9
12
"code.google.com/p/goprotobuf/proto"
10
13
)
11
14
@@ -18,8 +21,11 @@ type IpfsDHT struct {
18
21
19
22
network * swarm.Swarm
20
23
21
- // local data (TEMPORARY: until we formalize data storage with datastore)
22
- data map [string ][]byte
24
+ // Local peer (yourself)
25
+ self * peer.Peer
26
+
27
+ // Local data
28
+ datastore ds.Datastore
23
29
24
30
// map of channels waiting for reply messages
25
31
listeners map [uint64 ]chan * swarm.Message
@@ -29,6 +35,15 @@ type IpfsDHT struct {
29
35
shutdown chan struct {}
30
36
}
31
37
38
+ func NewDHT (p * peer.Peer ) * IpfsDHT {
39
+ dht := new (IpfsDHT )
40
+ dht .self = p
41
+ dht .network = swarm .NewSwarm (p )
42
+ dht .listeners = make (map [uint64 ]chan * swarm.Message )
43
+ dht .shutdown = make (chan struct {})
44
+ return dht
45
+ }
46
+
32
47
// Read in all messages from swarm and handle them appropriately
33
48
// NOTE: this function is just a quick sketch
34
49
func (dht * IpfsDHT ) handleMessages () {
@@ -61,10 +76,13 @@ func (dht *IpfsDHT) handleMessages() {
61
76
case DHTMessage_GET_VALUE :
62
77
dht .handleGetValue (mes .Peer , pmes )
63
78
case DHTMessage_PUT_VALUE :
79
+ dht .handlePutValue (mes .Peer , pmes )
64
80
case DHTMessage_FIND_NODE :
81
+ dht .handleFindNode (mes .Peer , pmes )
65
82
case DHTMessage_ADD_PROVIDER :
66
83
case DHTMessage_GET_PROVIDERS :
67
84
case DHTMessage_PING :
85
+ dht .handleFindNode (mes .Peer , pmes )
68
86
}
69
87
70
88
case <- dht .shutdown :
@@ -74,24 +92,37 @@ func (dht *IpfsDHT) handleMessages() {
74
92
}
75
93
76
94
func (dht * IpfsDHT ) handleGetValue (p * peer.Peer , pmes * DHTMessage ) {
77
- val , found := dht .data [pmes .GetKey ()]
78
- if found {
95
+ dskey := ds .NewKey (pmes .GetKey ())
96
+ i_val , err := dht .datastore .Get (dskey )
97
+ if err == nil {
79
98
isResponse := true
80
99
resp := new (DHTMessage )
81
100
resp .Response = & isResponse
82
101
resp .Id = pmes .Id
83
102
resp .Key = pmes .Key
103
+
104
+ val := i_val .([]byte )
84
105
resp .Value = val
85
- } else {
106
+
107
+ mes := new (swarm.Message )
108
+ mes .Peer = p
109
+ mes .Data = []byte (resp .String ())
110
+ } else if err == ds .ErrNotFound {
86
111
// Find closest node(s) to desired key and reply with that info
87
112
// TODO: this will need some other metadata in the protobuf message
88
113
// to signal to the querying node that the data its receiving
89
114
// is actually a list of other nodes
90
115
}
91
116
}
92
117
118
+ // Store a value in this nodes local storage
93
119
func (dht * IpfsDHT ) handlePutValue (p * peer.Peer , pmes * DHTMessage ) {
94
- panic ("Not implemented." )
120
+ dskey := ds .NewKey (pmes .GetKey ())
121
+ err := dht .datastore .Put (dskey , pmes .GetValue ())
122
+ if err != nil {
123
+ // For now, just panic, handle this better later maybe
124
+ panic (err )
125
+ }
95
126
}
96
127
97
128
func (dht * IpfsDHT ) handleFindNode (p * peer.Peer , pmes * DHTMessage ) {
@@ -121,6 +152,17 @@ func (dht *IpfsDHT) ListenFor(mesid uint64) <-chan *swarm.Message {
121
152
return lchan
122
153
}
123
154
155
+ func (dht * IpfsDHT ) Unlisten (mesid uint64 ) {
156
+ dht .listenLock .Lock ()
157
+ ch , ok := dht .listeners [mesid ]
158
+ if ok {
159
+ delete (dht .listeners , mesid )
160
+ }
161
+ dht .listenLock .Unlock ()
162
+ close (ch )
163
+ }
164
+
165
+
124
166
// Stop all communications from this node and shut down
125
167
func (dht * IpfsDHT ) Halt () {
126
168
dht .shutdown <- struct {}{}
0 commit comments