aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-09-26 21:24:03 +0000
committerChristian Grothoff <christian@grothoff.org>2016-09-26 21:24:03 +0000
commit7b00dd51218edbd9182caa664cfce185edc2cc45 (patch)
tree2cea8a9d7085aa6e3d16256f18f7c77f3320bb75 /src/dht
parent60ff113fe4e7bb71d5696063b9a9b81eba60a108 (diff)
downloadgnunet-7b00dd51218edbd9182caa664cfce185edc2cc45.tar.gz
gnunet-7b00dd51218edbd9182caa664cfce185edc2cc45.zip
porting xdht to new service API, major code de-duplication effort
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/Makefile.am11
-rw-r--r--src/dht/gnunet-service-dht.c23
-rw-r--r--src/dht/gnunet-service-dht.h3
-rw-r--r--src/dht/gnunet-service-dht_clients.c67
-rw-r--r--src/dht/gnunet-service-dht_datacache.c193
-rw-r--r--src/dht/gnunet-service-dht_datacache.h95
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c59
-rw-r--r--src/dht/gnunet-service-dht_neighbours.h6
-rw-r--r--src/dht/gnunet-service-dht_routing.c9
-rw-r--r--src/dht/gnunet-service-dht_routing.h10
-rw-r--r--src/dht/gnunet-service-wdht.c6
-rw-r--r--src/dht/gnunet-service-wdht_clients.c2
-rw-r--r--src/dht/gnunet-service-wdht_datacache.c459
-rw-r--r--src/dht/gnunet-service-wdht_datacache.h123
-rw-r--r--src/dht/gnunet-service-wdht_neighbours.c27
-rw-r--r--src/dht/gnunet-service-wdht_neighbours.h7
-rw-r--r--src/dht/gnunet-service-wdht_nse.c116
-rw-r--r--src/dht/gnunet-service-wdht_nse.h52
-rw-r--r--src/dht/gnunet-service-xdht.c75
-rw-r--r--src/dht/gnunet-service-xdht_clients.c1417
-rw-r--r--src/dht/gnunet-service-xdht_clients.h149
-rw-r--r--src/dht/gnunet-service-xdht_datacache.c401
-rw-r--r--src/dht/gnunet-service-xdht_datacache.h90
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.c313
-rw-r--r--src/dht/gnunet-service-xdht_neighbours.h86
-rw-r--r--src/dht/gnunet-service-xdht_nse.c116
-rw-r--r--src/dht/gnunet-service-xdht_nse.h52
-rw-r--r--src/dht/gnunet-service-xdht_routing.c9
28 files changed, 642 insertions, 3334 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
index f7dc5df6d..10aeae175 100644
--- a/src/dht/Makefile.am
+++ b/src/dht/Makefile.am
@@ -82,10 +82,9 @@ gnunet_service_dht_LDADD = \
82 -lm 82 -lm
83 83
84gnunet_service_dht_xvine_SOURCES = \ 84gnunet_service_dht_xvine_SOURCES = \
85 gnunet-service-xdht.c gnunet-service-xdht.h \ 85 gnunet-service-xdht.c gnunet-service-dht.h \
86 gnunet-service-xdht_clients.c gnunet-service-xdht_clients.h \ 86 gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \
87 gnunet-service-xdht_datacache.c gnunet-service-xdht_datacache.h \ 87 gnunet-service-dht_nse.c gnunet-service-dht_nse.h \
88 gnunet-service-xdht_nse.c gnunet-service-xdht_nse.h \
89 gnunet-service-xdht_neighbours.c gnunet-service-xdht_neighbours.h \ 88 gnunet-service-xdht_neighbours.c gnunet-service-xdht_neighbours.h \
90 gnunet-service-xdht_routing.c gnunet-service-xdht_routing.h 89 gnunet-service-xdht_routing.c gnunet-service-xdht_routing.h
91 90
@@ -105,8 +104,8 @@ gnunet_service_dht_xvine_LDADD = \
105gnunet_service_dht_whanau_SOURCES = \ 104gnunet_service_dht_whanau_SOURCES = \
106 gnunet-service-wdht.c gnunet-service-wdht.h \ 105 gnunet-service-wdht.c gnunet-service-wdht.h \
107 gnunet-service-wdht_clients.c gnunet-service-wdht_clients.h \ 106 gnunet-service-wdht_clients.c gnunet-service-wdht_clients.h \
108 gnunet-service-wdht_datacache.c gnunet-service-wdht_datacache.h \ 107 gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \
109 gnunet-service-wdht_nse.c gnunet-service-wdht_nse.h \ 108 gnunet-service-dht_nse.c gnunet-service-dht_nse.h \
110 gnunet-service-wdht_neighbours.c gnunet-service-wdht_neighbours.h 109 gnunet-service-wdht_neighbours.c gnunet-service-wdht_neighbours.h
111gnunet_service_dht_whanau_LDADD = \ 110gnunet_service_dht_whanau_LDADD = \
112 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 111 $(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index a2ba2e8b0..f2b922dc4 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -39,27 +39,6 @@
39#include "gnunet-service-dht_nse.h" 39#include "gnunet-service-dht_nse.h"
40#include "gnunet-service-dht_routing.h" 40#include "gnunet-service-dht_routing.h"
41 41
42
43/**
44 * Handle for the statistics service.
45 */
46struct GNUNET_STATISTICS_Handle *GDS_stats;
47
48/**
49 * Handle for the service.
50 */
51struct GNUNET_SERVICE_Handle *GDS_service;
52
53/**
54 * Our handle to the BLOCK library.
55 */
56struct GNUNET_BLOCK_Context *GDS_block_context;
57
58/**
59 * The configuration the DHT service is running with
60 */
61const struct GNUNET_CONFIGURATION_Handle *GDS_cfg;
62
63/** 42/**
64 * Our HELLO 43 * Our HELLO
65 */ 44 */
@@ -180,7 +159,7 @@ run (void *cls,
180 159
181 160
182/* Finally, define the main method */ 161/* Finally, define the main method */
183GDS_DHT_SERVICE_INIT(&run); 162GDS_DHT_SERVICE_INIT("dht", &run);
184 163
185 164
186 165
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index bc7a48b5a..493c3b961 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -82,7 +82,8 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
82 const struct GNUNET_PeerIdentity *get_path, 82 const struct GNUNET_PeerIdentity *get_path,
83 unsigned int put_path_length, 83 unsigned int put_path_length,
84 const struct GNUNET_PeerIdentity *put_path, 84 const struct GNUNET_PeerIdentity *put_path,
85 enum GNUNET_BLOCK_Type type, size_t data_size, 85 enum GNUNET_BLOCK_Type type,
86 size_t data_size,
86 const void *data); 87 const void *data);
87 88
88 89
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index 0e344b566..df56c010a 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -213,6 +213,25 @@ struct ClientHandle
213 213
214}; 214};
215 215
216/**
217 * Our handle to the BLOCK library.
218 */
219struct GNUNET_BLOCK_Context *GDS_block_context;
220
221/**
222 * Handle for the statistics service.
223 */
224struct GNUNET_STATISTICS_Handle *GDS_stats;
225
226/**
227 * Handle for the service.
228 */
229struct GNUNET_SERVICE_Handle *GDS_service;
230
231/**
232 * The configuration the DHT service is running with
233 */
234const struct GNUNET_CONFIGURATION_Handle *GDS_cfg;
216 235
217/** 236/**
218 * List of active monitoring requests. 237 * List of active monitoring requests.
@@ -496,7 +515,7 @@ handle_dht_local_put (void *cls,
496 ntohl (dht_msg->options), 515 ntohl (dht_msg->options),
497 ntohl (dht_msg->desired_replication_level), 516 ntohl (dht_msg->desired_replication_level),
498 GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 517 GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
499 0 /* hop count */ , 518 0 /* hop count */,
500 peer_bf, 519 peer_bf,
501 &dht_msg->key, 520 &dht_msg->key,
502 0, 521 0,
@@ -541,6 +560,43 @@ check_dht_local_get (void *cls,
541 560
542 561
543/** 562/**
563 * Handle a result from local datacache for a GET operation.
564 *
565 * @param cls the `struct ClientHandle` of the client doing the query
566 * @param type type of the block
567 * @param expiration_time when does the content expire
568 * @param key key for the content
569 * @param put_path_length number of entries in @a put_path
570 * @param put_path peers the original PUT traversed (if tracked)
571 * @param get_path_length number of entries in @a get_path
572 * @param get_path peers this reply has traversed so far (if tracked)
573 * @param data payload of the reply
574 * @param data_size number of bytes in @a data
575 */
576static void
577handle_local_result (void *cls,
578 enum GNUNET_BLOCK_Type type,
579 struct GNUNET_TIME_Absolute expiration_time,
580 const struct GNUNET_HashCode *key,
581 unsigned int put_path_length,
582 const struct GNUNET_PeerIdentity *put_path,
583 unsigned int get_path_length,
584 const struct GNUNET_PeerIdentity *get_path,
585 const void *data,
586 size_t data_size)
587{
588 // FIXME: this needs some clean up: inline the function,
589 // possibly avoid even looking up the client!
590 GDS_CLIENTS_handle_reply (expiration_time,
591 key,
592 0, NULL,
593 put_path_length, put_path,
594 type,
595 data_size, data);
596}
597
598
599/**
544 * Handler for DHT GET messages from the client. 600 * Handler for DHT GET messages from the client.
545 * 601 *
546 * @param cls the client we received this message from 602 * @param cls the client we received this message from
@@ -611,7 +667,9 @@ handle_dht_local_get (void *cls,
611 cqr->xquery, 667 cqr->xquery,
612 xquery_size, 668 xquery_size,
613 NULL, 669 NULL,
614 0); 670 0,
671 &handle_local_result,
672 ch);
615 GNUNET_SERVICE_client_continue (ch->client); 673 GNUNET_SERVICE_client_continue (ch->client);
616} 674}
617 675
@@ -1413,11 +1471,12 @@ GDS_CLIENTS_stop ()
1413/** 1471/**
1414 * Define "main" method using service macro. 1472 * Define "main" method using service macro.
1415 * 1473 *
1474 * @param name name of the service, i.e. "dht" or "xdht"
1416 * @param run name of the initializaton method for the service 1475 * @param run name of the initializaton method for the service
1417 */ 1476 */
1418#define GDS_DHT_SERVICE_INIT(run) \ 1477#define GDS_DHT_SERVICE_INIT(name,run) \
1419 GNUNET_SERVICE_MAIN \ 1478 GNUNET_SERVICE_MAIN \
1420 ("dht", \ 1479 (name, \
1421 GNUNET_SERVICE_OPTION_NONE, \ 1480 GNUNET_SERVICE_OPTION_NONE, \
1422 run, \ 1481 run, \
1423 &client_connect_cb, \ 1482 &client_connect_cb, \
diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c
index 12c79764d..9b4dace67 100644
--- a/src/dht/gnunet-service-dht_datacache.c
+++ b/src/dht/gnunet-service-dht_datacache.c
@@ -31,6 +31,11 @@
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "dht-dhtcache",__VA_ARGS__) 32#define LOG(kind,...) GNUNET_log_from (kind, "dht-dhtcache",__VA_ARGS__)
33 33
34/**
35 * How many "closest" results to we return for migration when
36 * asked (at most)?
37 */
38#define NUM_CLOSEST 42
34 39
35/** 40/**
36 * Handle to the datacache service (for inserting/retrieving data) 41 * Handle to the datacache service (for inserting/retrieving data)
@@ -127,6 +132,17 @@ struct GetRequestContext
127 * Return value to give back. 132 * Return value to give back.
128 */ 133 */
129 enum GNUNET_BLOCK_EvaluationResult eval; 134 enum GNUNET_BLOCK_EvaluationResult eval;
135
136 /**
137 * Function to call on results.
138 */
139 GDS_DATACACHE_GetCallback gc;
140
141 /**
142 * Closure for @e gc.
143 */
144 void *gc_cls;
145
130}; 146};
131 147
132 148
@@ -136,7 +152,7 @@ struct GetRequestContext
136 * @param cls closure for iterator, a `struct GetRequestContext` 152 * @param cls closure for iterator, a `struct GetRequestContext`
137 * @param exp when does this value expire? 153 * @param exp when does this value expire?
138 * @param key the key this data is stored under 154 * @param key the key this data is stored under
139 * @param size the size of the data identified by key 155 * @param data_size the size of the data identified by key
140 * @param data the actual data 156 * @param data the actual data
141 * @param type the type of the @a data 157 * @param type the type of the @a data
142 * @param put_path_length number of peers in @a put_path 158 * @param put_path_length number of peers in @a put_path
@@ -147,7 +163,7 @@ struct GetRequestContext
147static int 163static int
148datacache_get_iterator (void *cls, 164datacache_get_iterator (void *cls,
149 const struct GNUNET_HashCode *key, 165 const struct GNUNET_HashCode *key,
150 size_t size, 166 size_t data_size,
151 const char *data, 167 const char *data,
152 enum GNUNET_BLOCK_Type type, 168 enum GNUNET_BLOCK_Type type,
153 struct GNUNET_TIME_Absolute exp, 169 struct GNUNET_TIME_Absolute exp,
@@ -157,8 +173,8 @@ datacache_get_iterator (void *cls,
157 struct GetRequestContext *ctx = cls; 173 struct GetRequestContext *ctx = cls;
158 enum GNUNET_BLOCK_EvaluationResult eval; 174 enum GNUNET_BLOCK_EvaluationResult eval;
159 175
160 eval = 176 eval
161 GNUNET_BLOCK_evaluate (GDS_block_context, 177 = GNUNET_BLOCK_evaluate (GDS_block_context,
162 type, 178 type,
163 GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, 179 GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO,
164 key, 180 key,
@@ -167,7 +183,7 @@ datacache_get_iterator (void *cls,
167 ctx->xquery, 183 ctx->xquery,
168 ctx->xquery_size, 184 ctx->xquery_size,
169 data, 185 data,
170 size); 186 data_size);
171 LOG (GNUNET_ERROR_TYPE_DEBUG, 187 LOG (GNUNET_ERROR_TYPE_DEBUG,
172 "Found reply for query %s in datacache, evaluation result is %d\n", 188 "Found reply for query %s in datacache, evaluation result is %d\n",
173 GNUNET_h2s (key), 189 GNUNET_h2s (key),
@@ -182,18 +198,13 @@ datacache_get_iterator (void *cls,
182 gettext_noop 198 gettext_noop
183 ("# Good RESULTS found in datacache"), 1, 199 ("# Good RESULTS found in datacache"), 1,
184 GNUNET_NO); 200 GNUNET_NO);
185 GDS_CLIENTS_handle_reply (exp, key, 201 ctx->gc (ctx->gc_cls,
186 0, NULL, 202 type,
187 put_path_length, put_path, 203 exp,
188 type, 204 key,
189 size, data); 205 put_path_length, put_path,
190 /* forward to other peers */ 206 0, NULL,
191 GDS_ROUTING_process (type, 207 data, data_size);
192 exp,
193 key,
194 put_path_length, put_path,
195 0, NULL,
196 data, size);
197 break; 208 break;
198 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: 209 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
199 GNUNET_STATISTICS_update (GDS_stats, 210 GNUNET_STATISTICS_update (GDS_stats,
@@ -242,6 +253,8 @@ datacache_get_iterator (void *cls,
242 * @param xquery_size number of bytes in @a xquery 253 * @param xquery_size number of bytes in @a xquery
243 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL 254 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
244 * @param reply_bf_mutator mutation value for @a reply_bf 255 * @param reply_bf_mutator mutation value for @a reply_bf
256 * @param gc function to call on the results
257 * @param gc_cls closure for @a gc
245 * @return evaluation result for the local replies 258 * @return evaluation result for the local replies
246 */ 259 */
247enum GNUNET_BLOCK_EvaluationResult 260enum GNUNET_BLOCK_EvaluationResult
@@ -250,7 +263,9 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
250 const void *xquery, 263 const void *xquery,
251 size_t xquery_size, 264 size_t xquery_size,
252 struct GNUNET_CONTAINER_BloomFilter **reply_bf, 265 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
253 uint32_t reply_bf_mutator) 266 uint32_t reply_bf_mutator,
267 GDS_DATACACHE_GetCallback gc,
268 void *gc_cls)
254{ 269{
255 struct GetRequestContext ctx; 270 struct GetRequestContext ctx;
256 unsigned int r; 271 unsigned int r;
@@ -267,6 +282,8 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
267 ctx.xquery_size = xquery_size; 282 ctx.xquery_size = xquery_size;
268 ctx.reply_bf = reply_bf; 283 ctx.reply_bf = reply_bf;
269 ctx.reply_bf_mutator = reply_bf_mutator; 284 ctx.reply_bf_mutator = reply_bf_mutator;
285 ctx.gc = gc;
286 ctx.gc_cls = gc_cls;
270 r = GNUNET_DATACACHE_get (datacache, 287 r = GNUNET_DATACACHE_get (datacache,
271 key, 288 key,
272 type, 289 type,
@@ -282,6 +299,146 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
282 299
283 300
284/** 301/**
302 * Function called with a random element from the datacache.
303 * Stores the key in the closure.
304 *
305 * @param cls a `struct GNUNET_HashCode *`, where to store the @a key
306 * @param key key for the content
307 * @param data_size number of bytes in @a data
308 * @param data content stored
309 * @param type type of the content
310 * @param exp when will the content expire?
311 * @param path_info_len number of entries in @a path_info
312 * @param path_info a path through the network
313 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
314 */
315static int
316datacache_random_iterator (void *cls,
317 const struct GNUNET_HashCode *key,
318 size_t data_size,
319 const char *data,
320 enum GNUNET_BLOCK_Type type,
321 struct GNUNET_TIME_Absolute exp,
322 unsigned int path_info_len,
323 const struct GNUNET_PeerIdentity *path_info)
324{
325 struct GNUNET_HashCode *dest = cls;
326
327 *dest = *key;
328 return GNUNET_OK; /* should actually not matter which we return */
329}
330
331
332/**
333 * Obtain a random key from the datacache.
334 * Used by Whanau for load-balancing.
335 *
336 * @param[out] key where to store the key of a random element,
337 * randomized by PRNG if datacache is empty
338 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
339 */
340int
341GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key)
342{
343 if (0 ==
344 GNUNET_DATACACHE_get_random (datacache,
345 &datacache_random_iterator,
346 key))
347 {
348 /* randomize key in this case */
349 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
350 key);
351 return GNUNET_SYSERR;
352 }
353 return GNUNET_OK;
354}
355
356
357/**
358 * Closure for #datacache_get_successors_iterator().
359 */
360struct SuccContext
361{
362 /**
363 * Function to call on the result
364 */
365 GDS_DATACACHE_SuccessorCallback cb;
366
367 /**
368 * Closure for @e cb.
369 */
370 void *cb_cls;
371};
372
373
374/**
375 * Iterator for local get request results,
376 *
377 * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID
378 * @param key the key this data is stored under
379 * @param size the size of the data identified by key
380 * @param data the actual data
381 * @param type the type of the data
382 * @param exp when does this value expire?
383 * @param put_path_length number of peers in @a put_path
384 * @param put_path path the reply took on put
385 * @return #GNUNET_OK to continue iteration, anything else
386 * to stop iteration.
387 */
388static int
389datacache_get_successors_iterator (void *cls,
390 const struct GNUNET_HashCode *key,
391 size_t size,
392 const char *data,
393 enum GNUNET_BLOCK_Type type,
394 struct GNUNET_TIME_Absolute exp,
395 unsigned int put_path_length,
396 const struct GNUNET_PeerIdentity *put_path)
397{
398 const struct SuccContext *sc = cls;
399
400 /* NOTE: The datacache currently does not store the RO from
401 the original 'put', so we don't know the 'correct' option
402 at this point anymore. Thus, we conservatively assume
403 that recording is desired (for now). */
404 sc->cb (sc->cb_cls,
405 GNUNET_DHT_RO_RECORD_ROUTE,
406 key,
407 type,
408 put_path_length, put_path,
409 exp,
410 data,
411 size);
412 return GNUNET_OK;
413}
414
415
416/**
417 * Handle a request for data close to a key that we have received from
418 * another peer.
419 *
420 * @param key the location at which the peer is looking for data that is close
421 * @param cb function to call with the result
422 * @param cb_cls closure for @a cb
423 */
424void
425GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key,
426 GDS_DATACACHE_SuccessorCallback cb,
427 void *cb_cls)
428{
429 struct SuccContext sc;
430
431 sc.cb = cb;
432 sc.cb_cls = cb_cls;
433 (void) GNUNET_DATACACHE_get_closest (datacache,
434 key,
435 NUM_CLOSEST,
436 &datacache_get_successors_iterator,
437 &sc);
438}
439
440
441/**
285 * Initialize datacache subsystem. 442 * Initialize datacache subsystem.
286 */ 443 */
287void 444void
diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h
index 66bfc3bbf..5069883c7 100644
--- a/src/dht/gnunet-service-dht_datacache.h
+++ b/src/dht/gnunet-service-dht_datacache.h
@@ -29,6 +29,7 @@
29 29
30#include "gnunet_util_lib.h" 30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h" 31#include "gnunet_block_lib.h"
32#include "gnunet_dht_service.h"
32 33
33/** 34/**
34 * Handle a datum we've received from another peer. Cache if 35 * Handle a datum we've received from another peer. Cache if
@@ -44,14 +45,42 @@
44 */ 45 */
45void 46void
46GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, 47GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
47 const struct GNUNET_HashCode * key, 48 const struct GNUNET_HashCode *key,
48 unsigned int put_path_length, 49 unsigned int put_path_length,
49 const struct GNUNET_PeerIdentity *put_path, 50 const struct GNUNET_PeerIdentity *put_path,
50 enum GNUNET_BLOCK_Type type, size_t data_size, 51 enum GNUNET_BLOCK_Type type,
52 size_t data_size,
51 const void *data); 53 const void *data);
52 54
53 55
54/** 56/**
57 * Handle a result for a GET operation.
58 *
59 * @param cls closure
60 * @param type type of the block
61 * @param expiration_time when does the content expire
62 * @param key key for the content
63 * @param put_path_length number of entries in @a put_path
64 * @param put_path peers the original PUT traversed (if tracked)
65 * @param get_path_length number of entries in @a get_path
66 * @param get_path peers this reply has traversed so far (if tracked)
67 * @param data payload of the reply
68 * @param data_size number of bytes in @a data
69 */
70typedef void
71(*GDS_DATACACHE_GetCallback)(void *cls,
72 enum GNUNET_BLOCK_Type type,
73 struct GNUNET_TIME_Absolute expiration_time,
74 const struct GNUNET_HashCode *key,
75 unsigned int put_path_length,
76 const struct GNUNET_PeerIdentity *put_path,
77 unsigned int get_path_length,
78 const struct GNUNET_PeerIdentity *get_path,
79 const void *data,
80 size_t data_size);
81
82
83/**
55 * Handle a GET request we've received from another peer. 84 * Handle a GET request we've received from another peer.
56 * 85 *
57 * @param key the query 86 * @param key the query
@@ -60,14 +89,70 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
60 * @param xquery_size number of bytes in xquery 89 * @param xquery_size number of bytes in xquery
61 * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL 90 * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL
62 * @param reply_bf_mutator mutation value for reply_bf 91 * @param reply_bf_mutator mutation value for reply_bf
92 * @param gc function to call on the results
93 * @param gc_cls closure for @a gc
63 * @return evaluation result for the local replies 94 * @return evaluation result for the local replies
64 */ 95 */
65enum GNUNET_BLOCK_EvaluationResult 96enum GNUNET_BLOCK_EvaluationResult
66GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, 97GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
67 enum GNUNET_BLOCK_Type type, const void *xquery, 98 enum GNUNET_BLOCK_Type type,
99 const void *xquery,
68 size_t xquery_size, 100 size_t xquery_size,
69 struct GNUNET_CONTAINER_BloomFilter **reply_bf, 101 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
70 uint32_t reply_bf_mutator); 102 uint32_t reply_bf_mutator,
103 GDS_DATACACHE_GetCallback gc,
104 void *gc_cls);
105
106
107/**
108 * Obtain a random key from the datacache.
109 * Used by Whanau for load-balancing.
110 *
111 * @param[out] key where to store the key of a random element,
112 * randomized by PRNG if datacache is empty
113 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
114 */
115int
116GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key);
117
118
119/**
120 * Send the get result to requesting client.
121 *
122 * @param cls closure
123 * @param options routing options (from GET request)
124 * @param key key of the requested data.
125 * @param type block type
126 * @param put_path_length number of peers in @a put_path
127 * @param put_path path taken to put the data at its stored location.
128 * @param expiration when will this result expire?
129 * @param data payload to store
130 * @param data_size size of the @a data
131 */
132typedef void
133(*GDS_DATACACHE_SuccessorCallback)(void *cls,
134 enum GNUNET_DHT_RouteOption options,
135 const struct GNUNET_HashCode *key,
136 enum GNUNET_BLOCK_Type type,
137 unsigned int put_path_length,
138 const struct GNUNET_PeerIdentity *put_path,
139 struct GNUNET_TIME_Absolute expiration,
140 const void *data,
141 size_t data_size);
142
143
144/**
145 * Handle a request for data close to a key that we have received from
146 * another peer.
147 *
148 * @param key the location at which the peer is looking for data that is close
149 * @param cb function to call with the result
150 * @param cb_cls closure for @a cb
151 */
152void
153GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key,
154 GDS_DATACACHE_SuccessorCallback cb,
155 void *cb_cls);
71 156
72 157
73/** 158/**
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 39fb43495..574ed9ad0 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -1255,8 +1255,8 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
1255 gettext_noop ("# PUT requests routed"), 1255 gettext_noop ("# PUT requests routed"),
1256 1, 1256 1,
1257 GNUNET_NO); 1257 GNUNET_NO);
1258 target_count = 1258 target_count
1259 get_target_peers (key, 1259 = get_target_peers (key,
1260 bf, 1260 bf,
1261 hop_count, 1261 hop_count,
1262 desired_replication_level, 1262 desired_replication_level,
@@ -1768,9 +1768,13 @@ handle_dht_p2p_put (void *cls,
1768 /* store locally */ 1768 /* store locally */
1769 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || 1769 if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
1770 (am_closest_peer (&put->key, bf))) 1770 (am_closest_peer (&put->key, bf)))
1771 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh 1771 GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time),
1772 (put->expiration_time), &put->key, putlen, pp, 1772 &put->key,
1773 ntohl (put->type), payload_size, payload); 1773 putlen,
1774 pp,
1775 ntohl (put->type),
1776 payload_size,
1777 payload);
1774 /* route to other peers */ 1778 /* route to other peers */
1775 forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type), 1779 forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type),
1776 options, 1780 options,
@@ -1913,6 +1917,44 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender,
1913 1917
1914 1918
1915/** 1919/**
1920 * Handle a result from local datacache for a GET operation.
1921 *
1922 * @param cls the `struct ClientHandle` of the client doing the query
1923 * @param type type of the block
1924 * @param expiration_time when does the content expire
1925 * @param key key for the content
1926 * @param put_path_length number of entries in @a put_path
1927 * @param put_path peers the original PUT traversed (if tracked)
1928 * @param get_path_length number of entries in @a get_path
1929 * @param get_path peers this reply has traversed so far (if tracked)
1930 * @param data payload of the reply
1931 * @param data_size number of bytes in @a data
1932 */
1933static void
1934handle_local_result (void *cls,
1935 enum GNUNET_BLOCK_Type type,
1936 struct GNUNET_TIME_Absolute expiration_time,
1937 const struct GNUNET_HashCode *key,
1938 unsigned int put_path_length,
1939 const struct GNUNET_PeerIdentity *put_path,
1940 unsigned int get_path_length,
1941 const struct GNUNET_PeerIdentity *get_path,
1942 const void *data,
1943 size_t data_size)
1944{
1945 // FIXME: we can probably do better here by
1946 // passing the peer that did the query in the closure...
1947 GDS_ROUTING_process (NULL,
1948 type,
1949 expiration_time,
1950 key,
1951 put_path_length, put_path,
1952 0, NULL,
1953 data, data_size);
1954}
1955
1956
1957/**
1916 * Check validity of p2p get request. 1958 * Check validity of p2p get request.
1917 * 1959 *
1918 * @param cls closure with the `struct PeerInfo` of the sender 1960 * @param cls closure with the `struct PeerInfo` of the sender
@@ -2067,7 +2109,9 @@ handle_dht_p2p_get (void *cls,
2067 xquery, 2109 xquery,
2068 xquery_size, 2110 xquery_size,
2069 &reply_bf, 2111 &reply_bf,
2070 get->bf_mutator); 2112 get->bf_mutator,
2113 &handle_local_result,
2114 NULL);
2071 } 2115 }
2072 } 2116 }
2073 else 2117 else
@@ -2276,7 +2320,8 @@ handle_dht_p2p_result (void *cls,
2276 data); 2320 data);
2277 } 2321 }
2278 /* forward to other peers */ 2322 /* forward to other peers */
2279 GDS_ROUTING_process (type, 2323 GDS_ROUTING_process (NULL,
2324 type,
2280 GNUNET_TIME_absolute_ntoh (prm->expiration_time), 2325 GNUNET_TIME_absolute_ntoh (prm->expiration_time),
2281 &prm->key, 2326 &prm->key,
2282 put_path_length, 2327 put_path_length,
diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h
index 856f1faae..d89e5c54f 100644
--- a/src/dht/gnunet-service-dht_neighbours.h
+++ b/src/dht/gnunet-service-dht_neighbours.h
@@ -58,7 +58,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type,
58 struct GNUNET_TIME_Absolute expiration_time, 58 struct GNUNET_TIME_Absolute expiration_time,
59 uint32_t hop_count, 59 uint32_t hop_count,
60 struct GNUNET_CONTAINER_BloomFilter *bf, 60 struct GNUNET_CONTAINER_BloomFilter *bf,
61 const struct GNUNET_HashCode * key, 61 const struct GNUNET_HashCode *key,
62 unsigned int put_path_length, 62 unsigned int put_path_length,
63 struct GNUNET_PeerIdentity *put_path, 63 struct GNUNET_PeerIdentity *put_path,
64 const void *data, size_t data_size); 64 const void *data, size_t data_size);
@@ -125,7 +125,7 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target,
125/** 125/**
126 * Initialize neighbours subsystem. 126 * Initialize neighbours subsystem.
127 * 127 *
128 * @return GNUNET_OK on success, GNUNET_SYSERR on error 128 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
129 */ 129 */
130int 130int
131GDS_NEIGHBOURS_init (void); 131GDS_NEIGHBOURS_init (void);
@@ -144,7 +144,7 @@ GDS_NEIGHBOURS_done (void);
144 * @return identity of the local node 144 * @return identity of the local node
145 */ 145 */
146struct GNUNET_PeerIdentity * 146struct GNUNET_PeerIdentity *
147GDS_NEIGHBOURS_get_id (); 147GDS_NEIGHBOURS_get_id (void);
148 148
149 149
150#endif 150#endif
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c
index d078c865d..48bece35e 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -277,13 +277,16 @@ process (void *cls, const struct GNUNET_HashCode * key, void *value)
277 * @param data_size number of bytes in data 277 * @param data_size number of bytes in data
278 */ 278 */
279void 279void
280GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, 280GDS_ROUTING_process (void *cls,
281 enum GNUNET_BLOCK_Type type,
281 struct GNUNET_TIME_Absolute expiration_time, 282 struct GNUNET_TIME_Absolute expiration_time,
282 const struct GNUNET_HashCode * key, unsigned int put_path_length, 283 const struct GNUNET_HashCode *key,
284 unsigned int put_path_length,
283 const struct GNUNET_PeerIdentity *put_path, 285 const struct GNUNET_PeerIdentity *put_path,
284 unsigned int get_path_length, 286 unsigned int get_path_length,
285 const struct GNUNET_PeerIdentity *get_path, 287 const struct GNUNET_PeerIdentity *get_path,
286 const void *data, size_t data_size) 288 const void *data,
289 size_t data_size)
287{ 290{
288 struct ProcessContext pc; 291 struct ProcessContext pc;
289 292
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h
index 1b163c25b..7c57361dc 100644
--- a/src/dht/gnunet-service-dht_routing.h
+++ b/src/dht/gnunet-service-dht_routing.h
@@ -38,6 +38,7 @@
38 * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching 38 * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching
39 * request recently. 39 * request recently.
40 * 40 *
41 * @param cls closure
41 * @param type type of the block 42 * @param type type of the block
42 * @param expiration_time when does the content expire 43 * @param expiration_time when does the content expire
43 * @param key key for the content 44 * @param key key for the content
@@ -49,13 +50,16 @@
49 * @param data_size number of bytes in @a data 50 * @param data_size number of bytes in @a data
50 */ 51 */
51void 52void
52GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, 53GDS_ROUTING_process (void *cls,
54 enum GNUNET_BLOCK_Type type,
53 struct GNUNET_TIME_Absolute expiration_time, 55 struct GNUNET_TIME_Absolute expiration_time,
54 const struct GNUNET_HashCode * key, unsigned int put_path_length, 56 const struct GNUNET_HashCode *key,
57 unsigned int put_path_length,
55 const struct GNUNET_PeerIdentity *put_path, 58 const struct GNUNET_PeerIdentity *put_path,
56 unsigned int get_path_length, 59 unsigned int get_path_length,
57 const struct GNUNET_PeerIdentity *get_path, 60 const struct GNUNET_PeerIdentity *get_path,
58 const void *data, size_t data_size); 61 const void *data,
62 size_t data_size);
59 63
60 64
61/** 65/**
diff --git a/src/dht/gnunet-service-wdht.c b/src/dht/gnunet-service-wdht.c
index b58bb729d..8be25ad5e 100644
--- a/src/dht/gnunet-service-wdht.c
+++ b/src/dht/gnunet-service-wdht.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file dht/gnunet-service-xdht.c 22 * @file dht/gnunet-service-wdht.c
23 * @brief GNUnet DHT service 23 * @brief GNUnet DHT service
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Nathan Evans 25 * @author Nathan Evans
@@ -34,9 +34,9 @@
34#include "gnunet_statistics_service.h" 34#include "gnunet_statistics_service.h"
35#include "gnunet-service-wdht.h" 35#include "gnunet-service-wdht.h"
36#include "gnunet-service-wdht_clients.h" 36#include "gnunet-service-wdht_clients.h"
37#include "gnunet-service-wdht_datacache.h" 37#include "gnunet-service-dht_datacache.h"
38#include "gnunet-service-wdht_neighbours.h" 38#include "gnunet-service-wdht_neighbours.h"
39#include "gnunet-service-wdht_nse.h" 39#include "gnunet-service-dht_nse.h"
40 40
41 41
42 42
diff --git a/src/dht/gnunet-service-wdht_clients.c b/src/dht/gnunet-service-wdht_clients.c
index 2abeea661..7ad0d2904 100644
--- a/src/dht/gnunet-service-wdht_clients.c
+++ b/src/dht/gnunet-service-wdht_clients.c
@@ -31,7 +31,7 @@
31#include "gnunet_statistics_service.h" 31#include "gnunet_statistics_service.h"
32#include "gnunet-service-wdht.h" 32#include "gnunet-service-wdht.h"
33#include "gnunet-service-wdht_clients.h" 33#include "gnunet-service-wdht_clients.h"
34#include "gnunet-service-wdht_datacache.h" 34#include "gnunet-service-dht_datacache.h"
35#include "gnunet-service-wdht_neighbours.h" 35#include "gnunet-service-wdht_neighbours.h"
36#include "dht.h" 36#include "dht.h"
37 37
diff --git a/src/dht/gnunet-service-wdht_datacache.c b/src/dht/gnunet-service-wdht_datacache.c
deleted file mode 100644
index 40d54bf5a..000000000
--- a/src/dht/gnunet-service-wdht_datacache.c
+++ /dev/null
@@ -1,459 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-wdht_datacache.c
23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#include "platform.h"
28#include "gnunet_datacache_lib.h"
29#include "gnunet-service-wdht_clients.h"
30#include "gnunet-service-wdht_datacache.h"
31#include "gnunet-service-wdht_neighbours.h"
32#include "gnunet-service-dht.h"
33
34#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__)
35
36#define DEBUG(...) \
37 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
38
39/**
40 * How many "closest" results to we return for migration when
41 * asked (at most)?
42 */
43#define NUM_CLOSEST 42
44
45/**
46 * Handle to the datacache service (for inserting/retrieving data)
47 */
48static struct GNUNET_DATACACHE_Handle *datacache;
49
50
51/**
52 * Handle a datum we've received from another peer. Cache if
53 * possible.
54 *
55 * @param expiration when will the reply expire
56 * @param key the query this reply is for
57 * @param put_path_length number of peers in @a put_path
58 * @param put_path path the reply took on put
59 * @param get_path_length number of peers in @a get_path
60 * @param get_path path the reply took on get
61 * @param type type of the reply
62 * @param data_size number of bytes in @a data
63 * @param data application payload data
64 */
65void
66GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
67 const struct GNUNET_HashCode *key,
68 unsigned int put_path_length,
69 const struct GNUNET_PeerIdentity *put_path,
70 unsigned int get_path_length,
71 const struct GNUNET_PeerIdentity *get_path,
72 enum GNUNET_BLOCK_Type type,
73 size_t data_size,
74 const void *data)
75{
76 int r;
77 struct GNUNET_PeerIdentity path[get_path_length + put_path_length];
78
79 if (NULL == datacache)
80 {
81 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
82 _("PUT request received, but have no datacache!\n"));
83 return;
84 }
85 if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
86 {
87 GNUNET_break (0);
88 return;
89 }
90 GNUNET_memcpy (path,
91 put_path,
92 put_path_length * sizeof (struct GNUNET_PeerIdentity));
93 GNUNET_memcpy (&path[put_path_length],
94 get_path,
95 get_path_length * sizeof (struct GNUNET_PeerIdentity));
96 /* Put size is actual data size plus struct overhead plus path length (if any) */
97 r = GNUNET_DATACACHE_put (datacache,
98 key,
99 data_size,
100 data,
101 type,
102 expiration,
103 get_path_length + put_path_length,
104 path);
105 if (GNUNET_OK == r)
106 GNUNET_STATISTICS_update (GDS_stats,
107 gettext_noop ("# ITEMS stored in datacache"), 1,
108 GNUNET_NO);
109 LOG (GNUNET_ERROR_TYPE_DEBUG,
110 "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n",
111 GNUNET_h2s (key),
112 data_size,
113 r,
114 put_path_length + get_path_length);
115}
116
117
118/**
119 * Context containing information about a GET request.
120 */
121struct GetRequestContext
122{
123 /**
124 * extended query (see gnunet_block_lib.h).
125 */
126 const void *xquery;
127
128 /**
129 * Bloomfilter to filter out duplicate replies (updated)
130 */
131 struct GNUNET_CONTAINER_BloomFilter **reply_bf;
132
133 /**
134 * The key this request was about
135 */
136 struct GNUNET_HashCode key;
137
138 /**
139 * The trail this request was for
140 */
141 const struct GNUNET_HashCode *trail_id;
142
143 /**
144 * Number of bytes in @e xquery.
145 */
146 size_t xquery_size;
147
148 /**
149 * Mutator value for the @e reply_bf, see gnunet_block_lib.h
150 */
151 uint32_t reply_bf_mutator;
152
153 /**
154 * Return value to give back.
155 */
156 enum GNUNET_BLOCK_EvaluationResult eval;
157
158 /**
159 * Routing options of the GET.
160 */
161 enum GNUNET_DHT_RouteOption options;
162
163};
164
165
166/**
167 * Iterator for local get request results,
168 *
169 * @param cls closure for iterator, a `struct GetRequestContext`
170 * @param key the key this data is stored under
171 * @param size the size of the data identified by key
172 * @param data the actual data
173 * @param type the type of the data
174 * @param exp when does this value expire?
175 * @param put_path_length number of peers in @a put_path
176 * @param put_path path the reply took on put
177 * @return #GNUNET_OK to continue iteration, anything else
178 * to stop iteration.
179 */
180static int
181datacache_get_iterator (void *cls,
182 const struct GNUNET_HashCode *key,
183 size_t size,
184 const char *data,
185 enum GNUNET_BLOCK_Type type,
186 struct GNUNET_TIME_Absolute exp,
187 unsigned int put_path_length,
188 const struct GNUNET_PeerIdentity *put_path)
189{
190 struct GetRequestContext *ctx = cls;
191 enum GNUNET_BLOCK_EvaluationResult eval;
192
193 eval =
194 GNUNET_BLOCK_evaluate (GDS_block_context,
195 type,
196 GNUNET_BLOCK_EO_NONE,
197 key,
198 ctx->reply_bf,
199 ctx->reply_bf_mutator,
200 ctx->xquery,
201 ctx->xquery_size,
202 data,
203 size);
204 LOG (GNUNET_ERROR_TYPE_DEBUG,
205 "Found reply for query %s in datacache, evaluation result is %d\n",
206 GNUNET_h2s (key), (int) eval);
207 ctx->eval = eval;
208
209 switch (eval)
210 {
211 case GNUNET_BLOCK_EVALUATION_OK_MORE:
212 case GNUNET_BLOCK_EVALUATION_OK_LAST:
213 /* forward to local clients */
214 GNUNET_STATISTICS_update (GDS_stats,
215 gettext_noop
216 ("# Good RESULTS found in datacache"), 1,
217 GNUNET_NO);
218 GDS_NEIGHBOURS_send_get_result (ctx->trail_id,
219 ctx->options,
220 key,
221 type,
222 put_path_length,
223 put_path,
224 exp,
225 data,
226 size);
227 break;
228 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
229 GNUNET_STATISTICS_update (GDS_stats,
230 gettext_noop
231 ("# Duplicate RESULTS found in datacache"), 1,
232 GNUNET_NO);
233 break;
234 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
235 GNUNET_STATISTICS_update (GDS_stats,
236 gettext_noop
237 ("# Invalid RESULTS found in datacache"), 1,
238 GNUNET_NO);
239 break;
240 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
241 GNUNET_STATISTICS_update (GDS_stats,
242 gettext_noop
243 ("# Irrelevant RESULTS found in datacache"), 1,
244 GNUNET_NO);
245 break;
246 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
247 GNUNET_break (0);
248 break;
249 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
250 GNUNET_break_op (0);
251 return GNUNET_SYSERR;
252 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
253 GNUNET_STATISTICS_update (GDS_stats,
254 gettext_noop
255 ("# Unsupported RESULTS found in datacache"), 1,
256 GNUNET_NO);
257 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
258 _("Unsupported block type (%u) in local response!\n"), type);
259 break;
260 }
261
262 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK;
263}
264
265
266/**
267 * Handle a GET request we've received from another peer.
268 *
269 * @param trail_id trail identifying where to send the result to, NULL for us
270 * @param options routing options (to be passed along)
271 * @param key the query
272 * @param type requested data type
273 * @param xquery extended query
274 * @param xquery_size number of bytes in @a xquery
275 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
276 * @param reply_bf_mutator mutation value for @a reply_bf
277 * @return evaluation result for the local replies
278 */
279enum GNUNET_BLOCK_EvaluationResult
280GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id,
281 enum GNUNET_DHT_RouteOption options,
282 const struct GNUNET_HashCode *key,
283 enum GNUNET_BLOCK_Type type,
284 const void *xquery,
285 size_t xquery_size,
286 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
287 uint32_t reply_bf_mutator)
288{
289 struct GetRequestContext ctx;
290 unsigned int r;
291
292 if (NULL == datacache)
293 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
294 GNUNET_STATISTICS_update (GDS_stats,
295 gettext_noop ("# GET requests given to datacache"),
296 1, GNUNET_NO);
297 ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
298 ctx.trail_id = trail_id;
299 ctx.options = options;
300 ctx.key = *key;
301 ctx.xquery = xquery;
302 ctx.xquery_size = xquery_size;
303 ctx.reply_bf = reply_bf;
304 ctx.reply_bf_mutator = reply_bf_mutator;
305 r = GNUNET_DATACACHE_get (datacache,
306 key,
307 type,
308 &datacache_get_iterator,
309 &ctx);
310 DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n",
311 GNUNET_h2s (key),
312 ctx.eval,
313 r);
314 return ctx.eval;
315}
316
317
318/**
319 * Function called with a random element from the datacache.
320 * Stores the key in the closure.
321 *
322 * @param cls a `struct GNUNET_HashCode *`, where to store the @a key
323 * @param key key for the content
324 * @param data_size number of bytes in @a data
325 * @param data content stored
326 * @param type type of the content
327 * @param exp when will the content expire?
328 * @param path_info_len number of entries in @a path_info
329 * @param path_info a path through the network
330 * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
331 */
332static int
333datacache_random_iterator (void *cls,
334 const struct GNUNET_HashCode *key,
335 size_t data_size,
336 const char *data,
337 enum GNUNET_BLOCK_Type type,
338 struct GNUNET_TIME_Absolute exp,
339 unsigned int path_info_len,
340 const struct GNUNET_PeerIdentity *path_info)
341{
342 struct GNUNET_HashCode *dest = cls;
343
344 *dest = *key;
345 return GNUNET_OK; /* should actually not matter which we return */
346}
347
348
349/**
350 * Obtain a random key from the datacache.
351 * Used by Whanau for load-balancing.
352 *
353 * @param[out] key where to store the key of a random element,
354 * randomized by PRNG if datacache is empty
355 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
356 */
357int
358GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key)
359{
360 if (0 ==
361 GNUNET_DATACACHE_get_random (datacache,
362 &datacache_random_iterator,
363 key))
364 {
365 /* randomize key in this case */
366 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE,
367 key);
368 return GNUNET_SYSERR;
369 }
370 return GNUNET_OK;
371}
372
373
374/**
375 * Iterator for local get request results,
376 *
377 * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID
378 * @param key the key this data is stored under
379 * @param size the size of the data identified by key
380 * @param data the actual data
381 * @param type the type of the data
382 * @param exp when does this value expire?
383 * @param put_path_length number of peers in @a put_path
384 * @param put_path path the reply took on put
385 * @return #GNUNET_OK to continue iteration, anything else
386 * to stop iteration.
387 */
388static int
389datacache_get_successors_iterator (void *cls,
390 const struct GNUNET_HashCode *key,
391 size_t size,
392 const char *data,
393 enum GNUNET_BLOCK_Type type,
394 struct GNUNET_TIME_Absolute exp,
395 unsigned int put_path_length,
396 const struct GNUNET_PeerIdentity *put_path)
397{
398 const struct GNUNET_HashCode *trail_id = cls;
399
400 /* NOTE: The datacache currently does not store the RO from
401 the original 'put', so we don't know the 'correct' option
402 at this point anymore. Thus, we conservatively assume
403 that recording is desired (for now). */
404 GDS_NEIGHBOURS_send_get_result (trail_id,
405 GNUNET_DHT_RO_RECORD_ROUTE,
406 key,
407 type,
408 put_path_length, put_path,
409 exp,
410 data,
411 size);
412 return GNUNET_OK;
413}
414
415
416/**
417 * Handle a request for data close to a key that we have received from
418 * another peer.
419 *
420 * @param trail_id trail where the reply needs to be send to
421 * @param key the location at which the peer is looking for data that is close
422 */
423void
424GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id,
425 const struct GNUNET_HashCode *key)
426{
427 (void) GNUNET_DATACACHE_get_closest (datacache,
428 key,
429 NUM_CLOSEST,
430 &datacache_get_successors_iterator,
431 (void *) trail_id);
432}
433
434
435/**
436 * Initialize datacache subsystem.
437 */
438void
439GDS_DATACACHE_init ()
440{
441 datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache");
442}
443
444
445/**
446 * Shutdown datacache subsystem.
447 */
448void
449GDS_DATACACHE_done ()
450{
451 if (NULL != datacache)
452 {
453 GNUNET_DATACACHE_destroy (datacache);
454 datacache = NULL;
455 }
456}
457
458
459/* end of gnunet-service-wdht_datacache.c */
diff --git a/src/dht/gnunet-service-wdht_datacache.h b/src/dht/gnunet-service-wdht_datacache.h
deleted file mode 100644
index ba9b55a0c..000000000
--- a/src/dht/gnunet-service-wdht_datacache.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-dht_datacache.h
23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#ifndef GNUNET_SERVICE_DHT_DATACACHE_H
28#define GNUNET_SERVICE_DHT_DATACACHE_H
29
30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h"
32#include "gnunet_dht_service.h"
33
34/**
35 * Handle a datum we've received from another peer. Cache if
36 * possible.
37 *
38 * @param expiration when will the reply expire
39 * @param key the query this reply is for
40 * @param put_path_length number of peers in @a put_path
41 * @param put_path path the reply took on put
42 * @param get_path_length number of peers in @a get_path
43 * @param get_path path the reply took on get
44 * @param type type of the reply
45 * @param data_size number of bytes in @a data
46 * @param data application payload data
47 */
48void
49GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
50 const struct GNUNET_HashCode *key,
51 unsigned int put_path_length,
52 const struct GNUNET_PeerIdentity *put_path,
53 unsigned int get_path_length,
54 const struct GNUNET_PeerIdentity *get_path,
55 enum GNUNET_BLOCK_Type type,
56 size_t data_size,
57 const void *data);
58
59
60/**
61 * Handle a GET request we've received from another peer.
62 *
63 * @param trail_id trail where the reply needs to be send to
64 * @param options routing options (to be passed along)
65 * @param key the query
66 * @param type requested data type
67 * @param xquery extended query
68 * @param xquery_size number of bytes in @a xquery
69 * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL
70 * @param reply_bf_mutator mutation value for @a reply_bf
71 * @return evaluation result for the local replies
72 *
73 * FIXME: also pass options, so we know to record paths or not...
74 */
75enum GNUNET_BLOCK_EvaluationResult
76GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id,
77 enum GNUNET_DHT_RouteOption options,
78 const struct GNUNET_HashCode *key,
79 enum GNUNET_BLOCK_Type type,
80 const void *xquery,
81 size_t xquery_size,
82 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
83 uint32_t reply_bf_mutator);
84
85
86/**
87 * Obtain a random key from the datacache.
88 * Used by Whanau for load-balancing.
89 *
90 * @param[out] key where to store the key of a random element,
91 * randomized by PRNG if datacache is empty
92 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty
93 */
94int
95GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key);
96
97
98/**
99 * Handle a request for data close to a key that we have received from
100 * another peer.
101 *
102 * @param trail_id trail where the reply needs to be send to
103 * @param key the location at which the peer is looking for data that is close
104 */
105void
106GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id,
107 const struct GNUNET_HashCode *key);
108
109
110/**
111 * Initialize datacache subsystem.
112 */
113void
114GDS_DATACACHE_init (void);
115
116
117/**
118 * Shutdown datacache subsystem.
119 */
120void
121GDS_DATACACHE_done (void);
122
123#endif
diff --git a/src/dht/gnunet-service-wdht_neighbours.c b/src/dht/gnunet-service-wdht_neighbours.c
index a6ebdb033..2a88ffa09 100644
--- a/src/dht/gnunet-service-wdht_neighbours.c
+++ b/src/dht/gnunet-service-wdht_neighbours.c
@@ -41,9 +41,9 @@
41#include "gnunet_statistics_service.h" 41#include "gnunet_statistics_service.h"
42#include "gnunet-service-wdht.h" 42#include "gnunet-service-wdht.h"
43#include "gnunet-service-wdht_clients.h" 43#include "gnunet-service-wdht_clients.h"
44#include "gnunet-service-wdht_datacache.h" 44#include "gnunet-service-dht_datacache.h"
45#include "gnunet-service-wdht_neighbours.h" 45#include "gnunet-service-wdht_neighbours.h"
46#include "gnunet-service-wdht_nse.h" 46#include "gnunet-service-dht_nse.h"
47#include "dht.h" 47#include "dht.h"
48 48
49#define DEBUG(...) \ 49#define DEBUG(...) \
@@ -605,7 +605,6 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
605 GDS_DATACACHE_handle_put (expiration_time, 605 GDS_DATACACHE_handle_put (expiration_time,
606 key, 606 key,
607 0, NULL, 607 0, NULL,
608 0, NULL,
609 block_type, 608 block_type,
610 data_size, 609 data_size,
611 data); 610 data);
@@ -777,7 +776,7 @@ forward_message_on_trail (struct FriendInfo *next_target,
777/** 776/**
778 * Send the get result to requesting client. 777 * Send the get result to requesting client.
779 * 778 *
780 * @param trail_id trail identifying where to send the result to, NULL for us 779 * @param cls trail identifying where to send the result to, NULL for us
781 * @param options routing options (from GET request) 780 * @param options routing options (from GET request)
782 * @param key Key of the requested data. 781 * @param key Key of the requested data.
783 * @param type Block type 782 * @param type Block type
@@ -788,7 +787,7 @@ forward_message_on_trail (struct FriendInfo *next_target,
788 * @param data_size Size of the @a data 787 * @param data_size Size of the @a data
789 */ 788 */
790void 789void
791GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, 790GDS_NEIGHBOURS_send_get_result (void *cls,
792 enum GNUNET_DHT_RouteOption options, 791 enum GNUNET_DHT_RouteOption options,
793 const struct GNUNET_HashCode *key, 792 const struct GNUNET_HashCode *key,
794 enum GNUNET_BLOCK_Type type, 793 enum GNUNET_BLOCK_Type type,
@@ -798,6 +797,7 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id,
798 const void *data, 797 const void *data,
799 size_t data_size) 798 size_t data_size)
800{ 799{
800 const struct GNUNET_HashCode *trail_id = cls;
801 struct GNUNET_MessageHeader *payload; 801 struct GNUNET_MessageHeader *payload;
802 struct Trail *trail; 802 struct Trail *trail;
803 803
@@ -1221,13 +1221,13 @@ handle_dht_p2p_random_walk (void *cls,
1221/** 1221/**
1222 * Handle a `struct RandomWalkResponseMessage`. 1222 * Handle a `struct RandomWalkResponseMessage`.
1223 * 1223 *
1224 * @param cls closure 1224 * @param cls closure
1225 * @param rwrm the setup response message 1225 * @param rwrm the setup response message
1226 */ 1226 */
1227static void 1227static void
1228handle_dht_p2p_random_walk_response (void *cls, 1228handle_dht_p2p_random_walk_response (void *cls,
1229 const struct RandomWalkResponseMessage *rwrm) 1229 const struct RandomWalkResponseMessage *rwrm)
1230{ 1230{
1231 struct Trail *trail; 1231 struct Trail *trail;
1232 struct FriendInfo *pred; 1232 struct FriendInfo *pred;
1233 struct FingerTable *ft; 1233 struct FingerTable *ft;
@@ -1298,7 +1298,7 @@ handle_dht_p2p_random_walk_response (void *cls,
1298static void 1298static void
1299handle_dht_p2p_trail_destroy (void *cls, 1299handle_dht_p2p_trail_destroy (void *cls,
1300 const struct TrailDestroyMessage *tdm) 1300 const struct TrailDestroyMessage *tdm)
1301{ 1301{
1302 struct FriendInfo *sender = cls; 1302 struct FriendInfo *sender = cls;
1303 struct Trail *trail; 1303 struct Trail *trail;
1304 1304
@@ -1340,8 +1340,9 @@ handle_dht_p2p_successor_find (void *cls,
1340 of successor finding... */ 1340 of successor finding... */
1341 GNUNET_break_op (0 == trail_path_length); 1341 GNUNET_break_op (0 == trail_path_length);
1342 fsm = (const struct FindSuccessorMessage *) message; 1342 fsm = (const struct FindSuccessorMessage *) message;
1343 GDS_DATACACHE_get_successors (trail_id, 1343 GDS_DATACACHE_get_successors (&fsm->key,
1344 &fsm->key); 1344 &GDS_NEIGHBOURS_send_get_result,
1345 (void *) trail_id);
1345 return GNUNET_OK; 1346 return GNUNET_OK;
1346} 1347}
1347 1348
@@ -1522,7 +1523,7 @@ struct TrailHandler
1522/** 1523/**
1523 * Check that a `struct TrailRouteMessage` is well-formed. 1524 * Check that a `struct TrailRouteMessage` is well-formed.
1524 * 1525 *
1525 * @param cls closure 1526 * @param cls closure
1526 * @param trm the finger destroy message 1527 * @param trm the finger destroy message
1527 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 1528 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1528 */ 1529 */
@@ -1534,7 +1535,7 @@ check_dht_p2p_trail_route (void *cls,
1534 uint16_t path_length; 1535 uint16_t path_length;
1535 const struct GNUNET_MessageHeader *payload; 1536 const struct GNUNET_MessageHeader *payload;
1536 size_t msize; 1537 size_t msize;
1537 1538
1538 msize = ntohs (trm->header.size); 1539 msize = ntohs (trm->header.size);
1539 path_length = ntohs (trm->path_length); 1540 path_length = ntohs (trm->path_length);
1540 if (msize < sizeof (struct TrailRouteMessage) + 1541 if (msize < sizeof (struct TrailRouteMessage) +
@@ -1561,7 +1562,7 @@ check_dht_p2p_trail_route (void *cls,
1561/** 1562/**
1562 * Handle a `struct TrailRouteMessage`. 1563 * Handle a `struct TrailRouteMessage`.
1563 * 1564 *
1564 * @param cls closure 1565 * @param cls closure
1565 * @param trm the finger destroy message 1566 * @param trm the finger destroy message
1566 */ 1567 */
1567static void 1568static void
diff --git a/src/dht/gnunet-service-wdht_neighbours.h b/src/dht/gnunet-service-wdht_neighbours.h
index f080258bb..8461d16e8 100644
--- a/src/dht/gnunet-service-wdht_neighbours.h
+++ b/src/dht/gnunet-service-wdht_neighbours.h
@@ -71,7 +71,7 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
71/** 71/**
72 * Send the get result to requesting client. 72 * Send the get result to requesting client.
73 * 73 *
74 * @param trail_id trail identifying where to send the result to, NULL for us 74 * @param cls a `const struct GNUNET_HashCode *` trail identifying where to send the result to, NULL for us
75 * @param options routing options (from GET request) 75 * @param options routing options (from GET request)
76 * @param key key of the requested data. 76 * @param key key of the requested data.
77 * @param type block type 77 * @param type block type
@@ -82,14 +82,15 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
82 * @param data_size size of the @a data 82 * @param data_size size of the @a data
83 */ 83 */
84void 84void
85GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, 85GDS_NEIGHBOURS_send_get_result (void *cls,
86 enum GNUNET_DHT_RouteOption options, 86 enum GNUNET_DHT_RouteOption options,
87 const struct GNUNET_HashCode *key, 87 const struct GNUNET_HashCode *key,
88 enum GNUNET_BLOCK_Type type, 88 enum GNUNET_BLOCK_Type type,
89 unsigned int put_path_length, 89 unsigned int put_path_length,
90 const struct GNUNET_PeerIdentity *put_path, 90 const struct GNUNET_PeerIdentity *put_path,
91 struct GNUNET_TIME_Absolute expiration, 91 struct GNUNET_TIME_Absolute expiration,
92 const void *data, size_t data_size); 92 const void *data,
93 size_t data_size);
93 94
94 95
95/** 96/**
diff --git a/src/dht/gnunet-service-wdht_nse.c b/src/dht/gnunet-service-wdht_nse.c
deleted file mode 100644
index 400c8242e..000000000
--- a/src/dht/gnunet-service-wdht_nse.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-xdht_nse.c
23 * @brief GNUnet DHT integration with NSE
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_nse_service.h"
28#include "gnunet-service-wdht.h"
29#include "gnunet-service-wdht_nse.h"
30
31/**
32 * log of the current network size estimate, used as the point where
33 * we switch between random and deterministic routing. Default
34 * value of 4.0 is used if NSE module is not available (i.e. not
35 * configured).
36 */
37static double log_of_network_size_estimate = 4.0;
38
39/**
40 * Network size estimation handle.
41 */
42static struct GNUNET_NSE_Handle *nse;
43
44
45/**
46 * Callback that is called when network size estimate is updated.
47 *
48 * @param cls closure
49 * @param timestamp time when the estimate was received from the server (or created by the server)
50 * @param logestimate the log(Base 2) value of the current network size estimate
51 * @param std_dev standard deviation for the estimate
52 *
53 */
54static void
55update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp,
56 double logestimate, double std_dev)
57{
58 GNUNET_STATISTICS_update (GDS_stats,
59 gettext_noop ("# Network size estimates received"),
60 1, GNUNET_NO);
61 /* do not allow estimates < 0.5 */
62 log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate);
63}
64
65
66/**
67 * Return the log of the current network size estimate.
68 *
69 * @return log of NSE
70 */
71double
72GDS_NSE_get ()
73{
74 return log_of_network_size_estimate;
75}
76
77
78/**
79 * Initialize NSE subsystem.
80 */
81void
82GDS_NSE_init ()
83{
84 unsigned long long hops;
85
86 if ( (GNUNET_YES ==
87 GNUNET_CONFIGURATION_have_value (GDS_cfg,
88 "dht",
89 "FORCE_NSE")) &&
90 (GNUNET_OK ==
91 GNUNET_CONFIGURATION_get_value_number (GDS_cfg,
92 "dht",
93 "FORCE_NSE",
94 &hops)) )
95 {
96 log_of_network_size_estimate = (double) hops;
97 return;
98 }
99 nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL);
100}
101
102
103/**
104 * Shutdown NSE subsystem.
105 */
106void
107GDS_NSE_done ()
108{
109 if (NULL != nse)
110 {
111 GNUNET_NSE_disconnect (nse);
112 nse = NULL;
113 }
114}
115
116/* end of gnunet-service-dht_nse.c */
diff --git a/src/dht/gnunet-service-wdht_nse.h b/src/dht/gnunet-service-wdht_nse.h
deleted file mode 100644
index 358c0c4bd..000000000
--- a/src/dht/gnunet-service-wdht_nse.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-xdht_nse.h
23 * @brief GNUnet DHT integration with NSE
24 * @author Christian Grothoff
25 */
26#ifndef GNUNET_SERVICE_XDHT_NSE_H
27#define GNUNET_SERVICE_XDHT_NSE_H
28
29
30/**
31 * Return the log of the current network size estimate.
32 *
33 * @return log of NSE
34 */
35double
36GDS_NSE_get (void);
37
38
39/**
40 * Initialize NSE subsystem.
41 */
42void
43GDS_NSE_init (void);
44
45
46/**
47 * Shutdown NSE subsystem.
48 */
49void
50GDS_NSE_done (void);
51
52#endif
diff --git a/src/dht/gnunet-service-xdht.c b/src/dht/gnunet-service-xdht.c
index e7b2c50c4..382a3b7c3 100644
--- a/src/dht/gnunet-service-xdht.c
+++ b/src/dht/gnunet-service-xdht.c
@@ -30,36 +30,23 @@
30#include "gnunet_hello_lib.h" 30#include "gnunet_hello_lib.h"
31#include "gnunet_dht_service.h" 31#include "gnunet_dht_service.h"
32#include "gnunet_statistics_service.h" 32#include "gnunet_statistics_service.h"
33#include "gnunet-service-xdht.h" 33#include "gnunet-service-dht.h"
34#include "gnunet-service-xdht_clients.h" 34#include "gnunet-service-dht_datacache.h"
35#include "gnunet-service-xdht_datacache.h" 35#include "gnunet-service-dht_neighbours.h"
36#include "gnunet-service-xdht_neighbours.h" 36#include "gnunet-service-dht_nse.h"
37#include "gnunet-service-xdht_nse.h"
38#include "gnunet-service-xdht_routing.h" 37#include "gnunet-service-xdht_routing.h"
39 38
40 39
41
42/**
43 * Handle for the statistics service.
44 */
45struct GNUNET_STATISTICS_Handle *GDS_stats;
46
47/**
48 * Our handle to the BLOCK library.
49 */
50struct GNUNET_BLOCK_Context *GDS_block_context;
51
52/**
53 * The configuration the DHT service is running with
54 */
55const struct GNUNET_CONFIGURATION_Handle *GDS_cfg;
56
57/** 40/**
58 * Should we store our topology predecessor and successor IDs into statistics? 41 * Should we store our topology predecessor and successor IDs into statistics?
59 */ 42 */
60extern unsigned int track_topology; 43extern unsigned int track_topology;
61 44
62 45
46/* Code shared between different DHT implementations */
47#include "gnunet-service-dht_clients.c"
48
49
63/** 50/**
64 * Task run during shutdown. 51 * Task run during shutdown.
65 * 52 *
@@ -72,16 +59,17 @@ shutdown_task (void *cls)
72 GDS_DATACACHE_done (); 59 GDS_DATACACHE_done ();
73 GDS_ROUTING_done (); 60 GDS_ROUTING_done ();
74 GDS_NSE_done (); 61 GDS_NSE_done ();
75 if (GDS_block_context != NULL) 62 if (NULL != GDS_block_context)
76 { 63 {
77 GNUNET_BLOCK_context_destroy (GDS_block_context); 64 GNUNET_BLOCK_context_destroy (GDS_block_context);
78 GDS_block_context = NULL; 65 GDS_block_context = NULL;
79 } 66 }
80 if (GDS_stats != NULL) 67 if (NULL != GDS_stats)
81 { 68 {
82 GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES); 69 GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES);
83 GDS_stats = NULL; 70 GDS_stats = NULL;
84 } 71 }
72 GDS_CLIENTS_stop ();
85} 73}
86 74
87 75
@@ -89,24 +77,29 @@ shutdown_task (void *cls)
89 * Process dht requests. 77 * Process dht requests.
90 * 78 *
91 * @param cls closure 79 * @param cls closure
92 * @param server the initialized server
93 * @param c configuration to use 80 * @param c configuration to use
81 * @param service the initialized service
94 */ 82 */
95static void 83static void
96run (void *cls, struct GNUNET_SERVER_Handle *server, 84run (void *cls,
97 const struct GNUNET_CONFIGURATION_Handle *c) 85 const struct GNUNET_CONFIGURATION_Handle *c,
86 struct GNUNET_SERVICE_Handle *service)
98{ 87{
99 unsigned long long _track_topology; 88 unsigned long long _track_topology;
100 89
101 GDS_cfg = c; 90 GDS_cfg = c;
91 GDS_service = service;
102 GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); 92 GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg);
103 GDS_stats = GNUNET_STATISTICS_create ("dht", GDS_cfg); 93 GDS_stats = GNUNET_STATISTICS_create ("dht",
94 GDS_cfg);
104 GDS_ROUTING_init (); 95 GDS_ROUTING_init ();
105 GDS_NSE_init (); 96 GDS_NSE_init ();
106 GDS_DATACACHE_init (); 97 GDS_DATACACHE_init ();
107 GDS_CLIENTS_init (server); 98 GDS_CLIENTS_init ();
108 if (GNUNET_OK == 99 if (GNUNET_OK ==
109 GNUNET_CONFIGURATION_get_value_number (c, "xdht", "track_toplogy", 100 GNUNET_CONFIGURATION_get_value_number (c,
101 "xdht",
102 "track_toplogy",
110 &_track_topology)) 103 &_track_topology))
111 { 104 {
112 track_topology = (unsigned int) _track_topology; 105 track_topology = (unsigned int) _track_topology;
@@ -121,26 +114,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
121} 114}
122 115
123 116
124/** 117/* Finally, define the main method */
125 * The main function for the dht service. 118GDS_DHT_SERVICE_INIT("xdht", &run);
126 * 119
127 * @param argc number of arguments from the command line
128 * @param argv command line arguments
129 * @return 0 ok, 1 on error
130 */
131int
132main (int argc, char *const *argv)
133{
134 int ret;
135
136 ret =
137 (GNUNET_OK ==
138 GNUNET_SERVICE_run (argc, argv,
139 "xdht",
140 GNUNET_SERVICE_OPTION_NONE, &run,
141 NULL)) ? 0 : 1;
142 GDS_CLIENTS_done ();
143 return ret;
144}
145 120
146/* end of gnunet-service-xdht.c */ 121/* end of gnunet-service-xdht.c */
diff --git a/src/dht/gnunet-service-xdht_clients.c b/src/dht/gnunet-service-xdht_clients.c
deleted file mode 100644
index 3185243b7..000000000
--- a/src/dht/gnunet-service-xdht_clients.c
+++ /dev/null
@@ -1,1417 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-dht_clients.c
23 * @brief GNUnet DHT service's client management code
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27
28#include "platform.h"
29#include "gnunet_constants.h"
30#include "gnunet_protocols.h"
31#include "gnunet_statistics_service.h"
32#include "gnunet-service-xdht.h"
33#include "gnunet-service-xdht_clients.h"
34#include "gnunet-service-xdht_datacache.h"
35#include "gnunet-service-xdht_neighbours.h"
36#include "dht.h"
37
38
39/**
40 * Should routing details be logged to stderr (for debugging)?
41 */
42#define LOG_TRAFFIC(kind,...) GNUNET_log_from (kind, "dht-traffic",__VA_ARGS__)
43
44#define LOG(kind,...) GNUNET_log_from (kind, "dht-clients",__VA_ARGS__)
45
46#define DEBUG(...) \
47 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
48
49/**
50 * Linked list of messages to send to clients.
51 */
52struct PendingMessage
53{
54 /**
55 * Pointer to next item in the list
56 */
57 struct PendingMessage *next;
58
59 /**
60 * Pointer to previous item in the list
61 */
62 struct PendingMessage *prev;
63
64 /**
65 * Actual message to be sent, allocated at the end of the struct:
66 * // msg = (cast) &pm[1];
67 * // GNUNET_memcpy (&pm[1], data, len);
68 */
69 const struct GNUNET_MessageHeader *msg;
70
71};
72
73
74/**
75 * Struct containing information about a client,
76 * handle to connect to it, and any pending messages
77 * that need to be sent to it.
78 */
79struct ClientList
80{
81 /**
82 * Linked list of active clients
83 */
84 struct ClientList *next;
85
86 /**
87 * Linked list of active clients
88 */
89 struct ClientList *prev;
90
91 /**
92 * The handle to this client
93 */
94 struct GNUNET_SERVER_Client *client_handle;
95
96 /**
97 * Handle to the current transmission request, NULL
98 * if none pending.
99 */
100 struct GNUNET_SERVER_TransmitHandle *transmit_handle;
101
102 /**
103 * Linked list of pending messages for this client
104 */
105 struct PendingMessage *pending_head;
106
107 /**
108 * Tail of linked list of pending messages for this client
109 */
110 struct PendingMessage *pending_tail;
111
112};
113
114
115/**
116 * Entry in the local forwarding map for a client's GET request.
117 */
118struct ClientQueryRecord
119{
120
121 /**
122 * The key this request was about
123 */
124 struct GNUNET_HashCode key;
125
126 /**
127 * Client responsible for the request.
128 */
129 struct ClientList *client;
130
131 /**
132 * Extended query (see gnunet_block_lib.h), allocated at the end of this struct.
133 */
134 const void *xquery;
135
136 /**
137 * Replies we have already seen for this request.
138 */
139 struct GNUNET_HashCode *seen_replies;
140
141 /**
142 * Pointer to this nodes heap location in the retry-heap (for fast removal)
143 */
144 struct GNUNET_CONTAINER_HeapNode *hnode;
145
146 /**
147 * What's the delay between re-try operations that we currently use for this
148 * request?
149 */
150 struct GNUNET_TIME_Relative retry_frequency;
151
152 /**
153 * What's the next time we should re-try this request?
154 */
155 struct GNUNET_TIME_Absolute retry_time;
156
157 /**
158 * The unique identifier of this request
159 */
160 uint64_t unique_id;
161
162 /**
163 * Number of bytes in xquery.
164 */
165 size_t xquery_size;
166
167 /**
168 * Number of entries in 'seen_replies'.
169 */
170 unsigned int seen_replies_count;
171
172 /**
173 * Desired replication level
174 */
175 uint32_t replication;
176
177 /**
178 * Any message options for this request
179 */
180 uint32_t msg_options;
181
182 /**
183 * The type for the data for the GET request.
184 */
185 enum GNUNET_BLOCK_Type type;
186
187};
188
189
190/**
191 * Struct containing paremeters of monitoring requests.
192 */
193struct ClientMonitorRecord
194{
195
196 /**
197 * Next element in DLL.
198 */
199 struct ClientMonitorRecord *next;
200
201 /**
202 * Previous element in DLL.
203 */
204 struct ClientMonitorRecord *prev;
205
206 /**
207 * Type of blocks that are of interest
208 */
209 enum GNUNET_BLOCK_Type type;
210
211 /**
212 * Key of data of interest, NULL for all.
213 */
214 struct GNUNET_HashCode *key;
215
216 /**
217 * Flag whether to notify about GET messages.
218 */
219 int16_t get;
220
221 /**
222 * Flag whether to notify about GET_REPONSE messages.
223 */
224 int16_t get_resp;
225
226 /**
227 * Flag whether to notify about PUT messages.
228 */
229 uint16_t put;
230
231 /**
232 * Client to notify of these requests.
233 */
234 struct ClientList *client;
235};
236
237
238/**
239 * List of active clients.
240 */
241static struct ClientList *client_head;
242
243/**
244 * List of active clients.
245 */
246static struct ClientList *client_tail;
247
248/**
249 * List of active monitoring requests.
250 */
251static struct ClientMonitorRecord *monitor_head;
252
253/**
254 * List of active monitoring requests.
255 */
256static struct ClientMonitorRecord *monitor_tail;
257
258/**
259 * Hashmap for fast key based lookup, maps keys to `struct ClientQueryRecord` entries.
260 */
261static struct GNUNET_CONTAINER_MultiHashMap *forward_map;
262
263/**
264 * Heap with all of our client's request, sorted by retry time (earliest on top).
265 */
266static struct GNUNET_CONTAINER_Heap *retry_heap;
267
268/**
269 * Task that re-transmits requests (using retry_heap).
270 */
271static struct GNUNET_SCHEDULER_Task * retry_task;
272
273
274/**
275 * Task run to check for messages that need to be sent to a client.
276 *
277 * @param client a ClientList, containing the client and any messages to be sent to it
278 */
279static void
280process_pending_messages (struct ClientList *client);
281
282
283/**
284 * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready
285 * request. A ClientList is passed as closure, take the head of the list
286 * and copy it into buf, which has the result of sending the message to the
287 * client.
288 *
289 * @param cls closure to this call
290 * @param size maximum number of bytes available to send
291 * @param buf where to copy the actual message to
292 *
293 * @return the number of bytes actually copied, 0 indicates failure
294 */
295static size_t
296send_reply_to_client (void *cls, size_t size, void *buf)
297{
298 struct ClientList *client = cls;
299 char *cbuf = buf;
300 struct PendingMessage *reply;
301 size_t off;
302 size_t msize;
303
304 client->transmit_handle = NULL;
305 if (buf == NULL)
306 {
307 /* client disconnected */
308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
309 "Client %p disconnected, pending messages will be discarded\n",
310 client->client_handle);
311 return 0;
312 }
313 off = 0;
314 while ((NULL != (reply = client->pending_head)) &&
315 (size >= off + (msize = ntohs (reply->msg->size))))
316 {
317 GNUNET_CONTAINER_DLL_remove (client->pending_head, client->pending_tail,
318 reply);
319 GNUNET_memcpy (&cbuf[off], reply->msg, msize);
320 GNUNET_free (reply);
321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
322 "Transmitting %u bytes to client %p\n",
323 (unsigned int) msize,
324 client->client_handle);
325 off += msize;
326 }
327 process_pending_messages (client);
328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
329 "Transmitted %u/%u bytes to client %p\n",
330 (unsigned int) off,
331 (unsigned int) size,
332 client->client_handle);
333 return off;
334}
335
336
337/**
338 * Task run to check for messages that need to be sent to a client.
339 *
340 * @param client a ClientList, containing the client and any messages to be sent to it
341 */
342static void
343process_pending_messages (struct ClientList *client)
344{
345 if ((client->pending_head == NULL) || (client->transmit_handle != NULL))
346 {
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
348 "Not asking for transmission to %p now: %s\n",
349 client->client_handle,
350 client->pending_head ==
351 NULL ? "no more messages" : "request already pending");
352 return;
353 }
354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
355 "Asking for transmission of %u bytes to client %p\n",
356 ntohs (client->pending_head->msg->size), client->client_handle);
357 client->transmit_handle =
358 GNUNET_SERVER_notify_transmit_ready (client->client_handle,
359 ntohs (client->pending_head->
360 msg->size),
361 GNUNET_TIME_UNIT_FOREVER_REL,
362 &send_reply_to_client, client);
363}
364
365
366/**
367 * Add a PendingMessage to the clients list of messages to be sent
368 *
369 * @param client the active client to send the message to
370 * @param pending_message the actual message to send
371 */
372static void
373add_pending_message (struct ClientList *client,
374 struct PendingMessage *pending_message)
375{
376 GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail,
377 pending_message);
378 process_pending_messages (client);
379}
380
381
382/**
383 * Closure for 'forward_reply'
384 */
385struct ForwardReplyContext
386{
387
388 /**
389 * Actual message to send to matching clients.
390 */
391 struct PendingMessage *pm;
392
393 /**
394 * Embedded payload.
395 */
396 const void *data;
397
398 /**
399 * Type of the data.
400 */
401 enum GNUNET_BLOCK_Type type;
402
403 /**
404 * Number of bytes in data.
405 */
406 size_t data_size;
407
408 /**
409 * Do we need to copy 'pm' because it was already used?
410 */
411 int do_copy;
412
413};
414
415
416/**
417 * Find a client if it exists, add it otherwise.
418 *
419 * @param client the server handle to the client
420 *
421 * @return the client if found, a new client otherwise
422 */
423static struct ClientList *
424find_active_client (struct GNUNET_SERVER_Client *client)
425{
426 struct ClientList *pos = client_head;
427 struct ClientList *ret;
428
429 while (pos != NULL)
430 {
431 if (pos->client_handle == client)
432 return pos;
433 pos = pos->next;
434 }
435 ret = GNUNET_new (struct ClientList);
436 ret->client_handle = client;
437 GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ret);
438 return ret;
439}
440
441
442/**
443 * Iterator over hash map entries that frees all entries
444 * associated with the given client.
445 *
446 * @param cls client to search for in source routes
447 * @param key current key code (ignored)
448 * @param value value in the hash map, a ClientQueryRecord
449 * @return #GNUNET_YES (we should continue to iterate)
450 */
451static int
452remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *value)
453{
454 struct ClientList *client = cls;
455 struct ClientQueryRecord *record = value;
456
457 if (record->client != client)
458 return GNUNET_YES;
459 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
460 "Removing client %p's record for key %s\n", client,
461 GNUNET_h2s (key));
462 GNUNET_assert (GNUNET_YES ==
463 GNUNET_CONTAINER_multihashmap_remove (forward_map, key,
464 record));
465 if (NULL != record->hnode)
466 GNUNET_CONTAINER_heap_remove_node (record->hnode);
467 GNUNET_array_grow (record->seen_replies, record->seen_replies_count, 0);
468 GNUNET_free (record);
469 return GNUNET_YES;
470}
471
472
473/**
474 * Iterator over hash map entries that send a given reply to
475 * each of the matching clients. With some tricky recycling
476 * of the buffer.
477 *
478 * @param cls the 'struct ForwardReplyContext'
479 * @param key current key
480 * @param value value in the hash map, a ClientQueryRecord
481 * @return GNUNET_YES (we should continue to iterate),
482 * if the result is mal-formed, GNUNET_NO
483 */
484static int
485forward_reply (void *cls, const struct GNUNET_HashCode * key, void *value)
486{
487 struct ForwardReplyContext *frc = cls;
488 struct ClientQueryRecord *record = value;
489 struct PendingMessage *pm;
490 struct GNUNET_DHT_ClientResultMessage *reply;
491 enum GNUNET_BLOCK_EvaluationResult eval;
492 int do_free;
493 struct GNUNET_HashCode ch;
494 unsigned int i;
495
496 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG,
497 "XVINE CLIENT-RESULT %s\n",
498 GNUNET_h2s_full (key));
499#if 0
500 if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type))
501 {
502 LOG (GNUNET_ERROR_TYPE_DEBUG,
503 "Record type missmatch, not passing request for key %s to local client\n",
504 GNUNET_h2s (key));
505
506 GNUNET_STATISTICS_update (GDS_stats,
507 gettext_noop
508 ("# Key match, type mismatches in REPLY to CLIENT"),
509 1, GNUNET_NO);
510 return GNUNET_YES; /* type mismatch */
511 }
512#endif
513 GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch);
514 for (i = 0; i < record->seen_replies_count; i++)
515 if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (struct GNUNET_HashCode)))
516 {
517 LOG (GNUNET_ERROR_TYPE_DEBUG,
518 "Duplicate reply, not passing request for key %s to local client\n",
519 GNUNET_h2s (key));
520 GNUNET_STATISTICS_update (GDS_stats,
521 gettext_noop
522 ("# Duplicate REPLIES to CLIENT request dropped"),
523 1, GNUNET_NO);
524 return GNUNET_YES; /* duplicate */
525 }
526 eval =
527 GNUNET_BLOCK_evaluate (GDS_block_context,
528 record->type,
529 GNUNET_BLOCK_EO_NONE,
530 key, NULL, 0,
531 record->xquery,
532 record->xquery_size,
533 frc->data,
534 frc->data_size);
535 LOG (GNUNET_ERROR_TYPE_DEBUG,
536 "Evaluation result is %d for key %s for local client's query\n",
537 (int) eval, GNUNET_h2s (key));
538 switch (eval)
539 {
540 case GNUNET_BLOCK_EVALUATION_OK_LAST:
541 do_free = GNUNET_YES;
542 break;
543 case GNUNET_BLOCK_EVALUATION_OK_MORE:
544 GNUNET_array_append (record->seen_replies, record->seen_replies_count, ch);
545 do_free = GNUNET_NO;
546 break;
547 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
548 /* should be impossible to encounter here */
549 GNUNET_break (0);
550 return GNUNET_YES;
551 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
552 GNUNET_break_op (0);
553 return GNUNET_NO;
554 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
555 GNUNET_break (0);
556 return GNUNET_NO;
557 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
558 GNUNET_break (0);
559 return GNUNET_NO;
560 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
561 return GNUNET_YES;
562 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
563 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
564 _("Unsupported block type (%u) in request!\n"), record->type);
565 return GNUNET_NO;
566 default:
567 GNUNET_break (0);
568 return GNUNET_NO;
569 }
570 if (GNUNET_NO == frc->do_copy)
571 {
572 /* first time, we can use the original data */
573 pm = frc->pm;
574 frc->do_copy = GNUNET_YES;
575 }
576 else
577 {
578 /* two clients waiting for same reply, must copy for queueing */
579 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
580 ntohs (frc->pm->msg->size));
581 GNUNET_memcpy (pm, frc->pm,
582 sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size));
583 pm->next = pm->prev = NULL;
584 pm->msg = (struct GNUNET_MessageHeader *) &pm[1];
585 }
586 GNUNET_STATISTICS_update (GDS_stats,
587 gettext_noop ("# RESULTS queued for clients"), 1,
588 GNUNET_NO);
589 reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1];
590 reply->unique_id = record->unique_id;
591 LOG (GNUNET_ERROR_TYPE_DEBUG,
592 "Queueing reply to query %s for client %p\n",
593 GNUNET_h2s (key),
594 record->client->client_handle);
595 add_pending_message (record->client, pm);
596 if (GNUNET_YES == do_free)
597 remove_client_records (record->client, key, record);
598 return GNUNET_YES;
599}
600
601
602/**
603 * Handle a reply we've received from another peer. If the reply
604 * matches any of our pending queries, forward it to the respective
605 * client(s).
606 *
607 * @param expiration when will the reply expire
608 * @param key the query this reply is for
609 * @param get_path_length number of peers in @a get_path
610 * @param get_path path the reply took on get
611 * @param put_path_length number of peers in @a put_path
612 * @param put_path path the reply took on put
613 * @param type type of the reply
614 * @param data_size number of bytes in @a data
615 * @param data application payload data
616 */
617void
618GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
619 const struct GNUNET_HashCode *key,
620 unsigned int get_path_length,
621 const struct GNUNET_PeerIdentity *get_path,
622 unsigned int put_path_length,
623 const struct GNUNET_PeerIdentity *put_path,
624 enum GNUNET_BLOCK_Type type, size_t data_size,
625 const void *data)
626{
627 struct ForwardReplyContext frc;
628 struct PendingMessage *pm;
629 struct GNUNET_DHT_ClientResultMessage *reply;
630 struct GNUNET_PeerIdentity *paths;
631 size_t msize;
632
633 LOG (GNUNET_ERROR_TYPE_DEBUG,
634 "reply for key %s\n",
635 GNUNET_h2s (key));
636
637 if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map, key))
638 {
639 GNUNET_STATISTICS_update (GDS_stats,
640 gettext_noop
641 ("# REPLIES ignored for CLIENTS (no match)"), 1,
642 GNUNET_NO);
643 return; /* no matching request, fast exit! */
644 }
645 msize =
646 sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size +
647 (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity);
648 if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
649 {
650 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
651 _("Could not pass reply to client, message too big!\n"));
652 return;
653 }
654 DEBUG ("reply FOR DATA_SIZE = %u\n",
655 (unsigned int) msize);
656 pm = GNUNET_malloc (msize + sizeof (struct PendingMessage));
657 reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1];
658 pm->msg = &reply->header;
659 reply->header.size = htons ((uint16_t) msize);
660 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT);
661 reply->type = htonl (type);
662 reply->get_path_length = htonl (get_path_length);
663 reply->put_path_length = htonl (put_path_length);
664 reply->unique_id = 0; /* filled in later */
665 reply->expiration = GNUNET_TIME_absolute_hton (expiration);
666 reply->key = *key;
667 paths = (struct GNUNET_PeerIdentity *) &reply[1];
668 GNUNET_memcpy (paths,
669 put_path,
670 sizeof (struct GNUNET_PeerIdentity) * put_path_length);
671 GNUNET_memcpy (&paths[put_path_length],
672 get_path,
673 sizeof (struct GNUNET_PeerIdentity) * get_path_length);
674 GNUNET_memcpy (&paths[get_path_length + put_path_length],
675 data,
676 data_size);
677 frc.do_copy = GNUNET_NO;
678 frc.pm = pm;
679 frc.data = data;
680 frc.data_size = data_size;
681 frc.type = type;
682 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
683 key,
684 &forward_reply,
685 &frc);
686 if (GNUNET_NO == frc.do_copy)
687 {
688 /* did not match any of the requests, free! */
689 GNUNET_STATISTICS_update (GDS_stats,
690 gettext_noop
691 ("# REPLIES ignored for CLIENTS (no match)"), 1,
692 GNUNET_NO);
693 GNUNET_free (pm);
694 }
695}
696
697/**
698 * Check if some client is monitoring GET messages and notify
699 * them in that case.
700 *
701 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
702 * @param type The type of data in the request.
703 * @param hop_count Hop count so far.
704 * @param path_length number of entries in path (or 0 if not recorded).
705 * @param path peers on the GET path (or NULL if not recorded).
706 * @param desired_replication_level Desired replication level.
707 * @param key Key of the requested data.
708 */
709void
710GDS_CLIENTS_process_get (uint32_t options,
711 enum GNUNET_BLOCK_Type type,
712 uint32_t hop_count,
713 uint32_t desired_replication_level,
714 unsigned int path_length,
715 const struct GNUNET_PeerIdentity *path,
716 const struct GNUNET_HashCode * key)
717{
718 struct ClientMonitorRecord *m;
719 struct ClientList **cl;
720 unsigned int cl_size;
721
722 cl = NULL;
723 cl_size = 0;
724 for (m = monitor_head; NULL != m; m = m->next)
725 {
726 if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
727 (NULL == m->key ||
728 memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
729 {
730 struct PendingMessage *pm;
731 struct GNUNET_DHT_MonitorGetMessage *mmsg;
732 struct GNUNET_PeerIdentity *msg_path;
733 size_t msize;
734 unsigned int i;
735
736 /* Don't send duplicates */
737 for (i = 0; i < cl_size; i++)
738 if (cl[i] == m->client)
739 break;
740 if (i < cl_size)
741 continue;
742 GNUNET_array_append (cl, cl_size, m->client);
743
744 msize = path_length * sizeof (struct GNUNET_PeerIdentity);
745 msize += sizeof (struct GNUNET_DHT_MonitorGetMessage);
746 msize += sizeof (struct PendingMessage);
747 pm = GNUNET_malloc (msize);
748 mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1];
749 pm->msg = &mmsg->header;
750 mmsg->header.size = htons (msize - sizeof (struct PendingMessage));
751 mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET);
752 mmsg->options = htonl(options);
753 mmsg->type = htonl(type);
754 mmsg->hop_count = htonl(hop_count);
755 mmsg->desired_replication_level = htonl(desired_replication_level);
756 mmsg->get_path_length = htonl(path_length);
757 GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode));
758 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
759 if (path_length > 0)
760 GNUNET_memcpy (msg_path, path,
761 path_length * sizeof (struct GNUNET_PeerIdentity));
762 add_pending_message (m->client, pm);
763 }
764 }
765 GNUNET_free_non_null (cl);
766}
767
768
769/**
770 * Check if some client is monitoring PUT messages and notify
771 * them in that case.
772 *
773 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
774 * @param type The type of data in the request.
775 * @param hop_count Hop count so far.
776 * @param path_length number of entries in path (or 0 if not recorded).
777 * @param path peers on the PUT path (or NULL if not recorded).
778 * @param desired_replication_level Desired replication level.
779 * @param exp Expiration time of the data.
780 * @param key Key under which data is to be stored.
781 * @param data Pointer to the data carried.
782 * @param size Number of bytes in data.
783 */
784void
785GDS_CLIENTS_process_put (uint32_t options,
786 enum GNUNET_BLOCK_Type type,
787 uint32_t hop_count,
788 uint32_t desired_replication_level,
789 unsigned int path_length,
790 const struct GNUNET_PeerIdentity *path,
791 struct GNUNET_TIME_Absolute exp,
792 const struct GNUNET_HashCode * key,
793 const void *data,
794 size_t size)
795{
796 struct ClientMonitorRecord *m;
797 struct ClientList **cl;
798 unsigned int cl_size;
799
800 cl = NULL;
801 cl_size = 0;
802 for (m = monitor_head; NULL != m; m = m->next)
803 {
804 if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) &&
805 (NULL == m->key ||
806 memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0))
807 {
808 struct PendingMessage *pm;
809 struct GNUNET_DHT_MonitorPutMessage *mmsg;
810 struct GNUNET_PeerIdentity *msg_path;
811 size_t msize;
812 unsigned int i;
813
814 /* Don't send duplicates */
815 for (i = 0; i < cl_size; i++)
816 if (cl[i] == m->client)
817 break;
818 if (i < cl_size)
819 continue;
820 GNUNET_array_append (cl, cl_size, m->client);
821
822 msize = size;
823 msize += path_length * sizeof (struct GNUNET_PeerIdentity);
824 msize += sizeof (struct GNUNET_DHT_MonitorPutMessage);
825 msize += sizeof (struct PendingMessage);
826 pm = GNUNET_malloc (msize);
827 mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1];
828 pm->msg = (struct GNUNET_MessageHeader *) mmsg;
829 mmsg->header.size = htons (msize - sizeof (struct PendingMessage));
830 mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT);
831 mmsg->options = htonl(options);
832 mmsg->type = htonl(type);
833 mmsg->hop_count = htonl(hop_count);
834 mmsg->desired_replication_level = htonl(desired_replication_level);
835 mmsg->put_path_length = htonl(path_length);
836 msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
837 if (path_length > 0)
838 {
839 GNUNET_memcpy (msg_path, path,
840 path_length * sizeof (struct GNUNET_PeerIdentity));
841 }
842 mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp);
843 GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode));
844 if (size > 0)
845 GNUNET_memcpy (&msg_path[path_length], data, size);
846 add_pending_message (m->client, pm);
847 }
848 }
849 GNUNET_free_non_null (cl);
850}
851
852
853/**
854 * Route the given request via the DHT.
855 */
856static void
857transmit_request (struct ClientQueryRecord *cqr)
858{
859 GNUNET_STATISTICS_update (GDS_stats,
860 gettext_noop
861 ("# GET requests from clients injected"), 1,
862 GNUNET_NO);
863
864 LOG (GNUNET_ERROR_TYPE_DEBUG,
865 "Initiating GET for %s, replication %u, already have %u replies\n",
866 GNUNET_h2s (&cqr->key),
867 cqr->replication,
868 cqr->seen_replies_count);
869
870 GDS_NEIGHBOURS_handle_get (&cqr->key, cqr->type, cqr->msg_options,
871 cqr->replication);
872
873 /* exponential back-off for retries.
874 * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
875 cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency);
876 cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency);
877}
878
879
880/**
881 * Task that looks at the 'retry_heap' and transmits all of the requests
882 * on the heap that are ready for transmission. Then re-schedules
883 * itself (unless the heap is empty).
884 *
885 * @param cls unused
886 */
887static void
888transmit_next_request_task (void *cls)
889{
890 struct ClientQueryRecord *cqr;
891 struct GNUNET_TIME_Relative delay;
892
893 retry_task = NULL;
894 while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
895 {
896 cqr->hnode = NULL;
897 delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time);
898 if (delay.rel_value_us > 0)
899 {
900 cqr->hnode =
901 GNUNET_CONTAINER_heap_insert (retry_heap, cqr,
902 cqr->retry_time.abs_value_us);
903 retry_task =
904 GNUNET_SCHEDULER_add_delayed (delay, &transmit_next_request_task,
905 NULL);
906 return;
907 }
908 transmit_request (cqr);
909 cqr->hnode =
910 GNUNET_CONTAINER_heap_insert (retry_heap, cqr,
911 cqr->retry_time.abs_value_us);
912 }
913}
914
915
916/**
917 * Handler for PUT messages.
918 *
919 * @param cls closure for the service
920 * @param client the client we received this message from
921 * @param message the actual message received
922 */
923static void
924handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
925 const struct GNUNET_MessageHeader *message)
926{
927 const struct GNUNET_DHT_ClientPutMessage *put_msg;
928 struct PendingMessage *pm;
929 struct GNUNET_DHT_ClientPutConfirmationMessage *conf;
930 uint16_t size;
931
932 size = ntohs (message->size);
933 if (size < sizeof (struct GNUNET_DHT_ClientPutMessage))
934 {
935 GNUNET_break (0);
936 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
937 return;
938 }
939 GNUNET_STATISTICS_update (GDS_stats,
940 gettext_noop
941 ("# PUT requests received from clients"), 1,
942 GNUNET_NO);
943 put_msg = (const struct GNUNET_DHT_ClientPutMessage *) message;
944 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE DHT CLIENT-PUT %s\n",
945 GNUNET_h2s_full (&put_msg->key));
946 /* give to local clients */
947 LOG (GNUNET_ERROR_TYPE_DEBUG,
948 "Handling local PUT of %u-bytes for query %s\n",
949 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
950 GNUNET_h2s (&put_msg->key));
951 DEBUG("PUT doing put i = %s\n",GNUNET_h2s(&(put_msg->key)));
952 GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (put_msg->expiration),
953 &put_msg->key, 0, NULL, 0, NULL,
954 ntohl (put_msg->type),
955 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
956 &put_msg[1]);
957
958 GDS_NEIGHBOURS_handle_put (&put_msg->key,
959 ntohl (put_msg->type), ntohl (put_msg->options),
960 ntohl (put_msg->desired_replication_level),
961 GNUNET_TIME_absolute_ntoh (put_msg->expiration),
962 &put_msg[1],
963 size - sizeof (struct GNUNET_DHT_ClientPutMessage));
964 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
965 sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
966 conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1];
967 conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
968 conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK);
969 conf->reserved = htonl (0);
970 conf->unique_id = put_msg->unique_id;
971 pm->msg = &conf->header;
972 add_pending_message (find_active_client (client), pm);
973 GNUNET_SERVER_receive_done (client, GNUNET_OK);
974}
975
976
977/**
978 * Handler for DHT GET messages from the client.
979 *
980 * @param cls closure for the service
981 * @param client the client we received this message from
982 * @param message the actual message received
983 */
984static void
985handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
986 const struct GNUNET_MessageHeader *message)
987{
988 const struct GNUNET_DHT_ClientGetMessage *get;
989 struct ClientQueryRecord *cqr;
990 size_t xquery_size;
991 const char *xquery;
992 uint16_t size;
993
994 size = ntohs (message->size);
995 if (size < sizeof (struct GNUNET_DHT_ClientGetMessage))
996 {
997 GNUNET_break (0);
998 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
999 return;
1000 }
1001 xquery_size = size - sizeof (struct GNUNET_DHT_ClientGetMessage);
1002 get = (const struct GNUNET_DHT_ClientGetMessage *) message;
1003 xquery = (const char *) &get[1];
1004 GNUNET_STATISTICS_update (GDS_stats,
1005 gettext_noop
1006 ("# GET requests received from clients"), 1,
1007 GNUNET_NO);
1008 LOG (GNUNET_ERROR_TYPE_DEBUG,
1009 "Received GET request for %s from local client %p, xq: %.*s\n",
1010 GNUNET_h2s (&get->key), client, xquery_size, xquery);
1011
1012 LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE CLIENT-GET %s\n",
1013 GNUNET_h2s_full (&get->key));
1014
1015
1016 cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size);
1017 cqr->key = get->key;
1018 cqr->client = find_active_client (client);
1019 cqr->xquery = (void *) &cqr[1];
1020 GNUNET_memcpy (&cqr[1], xquery, xquery_size);
1021 cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0);
1022 cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS;
1023 cqr->retry_time = GNUNET_TIME_absolute_get ();
1024 cqr->unique_id = get->unique_id;
1025 cqr->xquery_size = xquery_size;
1026 cqr->replication = ntohl (get->desired_replication_level);
1027 cqr->msg_options = ntohl (get->options);
1028 cqr->type = ntohl (get->type);
1029
1030 // FIXME use cqr->key, set multihashmap create to GNUNET_YES
1031 GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr,
1032 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1033
1034 struct GNUNET_PeerIdentity my_identity;
1035 my_identity = GDS_NEIGHBOURS_get_my_id();
1036 GDS_CLIENTS_process_get (ntohl (get->options),
1037 ntohl (get->type),
1038 0,
1039 ntohl (get->desired_replication_level),
1040 1,
1041 &my_identity,
1042 &get->key);
1043 /* start remote requests */
1044 if (NULL != retry_task)
1045 GNUNET_SCHEDULER_cancel (retry_task);
1046 retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL);
1047 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1048}
1049
1050
1051/**
1052 * Closure for 'find_by_unique_id'.
1053 */
1054struct FindByUniqueIdContext
1055{
1056 /**
1057 * Where to store the result, if found.
1058 */
1059 struct ClientQueryRecord *cqr;
1060
1061 uint64_t unique_id;
1062};
1063
1064
1065/**
1066 * Function called for each existing DHT record for the given
1067 * query. Checks if it matches the UID given in the closure
1068 * and if so returns the entry as a result.
1069 *
1070 * @param cls the search context
1071 * @param key query for the lookup (not used)
1072 * @param value the 'struct ClientQueryRecord'
1073 * @return GNUNET_YES to continue iteration (result not yet found)
1074 */
1075static int
1076find_by_unique_id (void *cls,
1077 const struct GNUNET_HashCode *key,
1078 void *value)
1079{
1080 struct FindByUniqueIdContext *fui_ctx = cls;
1081 struct ClientQueryRecord *cqr = value;
1082
1083 if (cqr->unique_id != fui_ctx->unique_id)
1084 return GNUNET_YES;
1085 fui_ctx->cqr = cqr;
1086 return GNUNET_NO;
1087}
1088
1089
1090/**
1091 * Handler for "GET result seen" messages from the client.
1092 *
1093 * @param cls closure for the service
1094 * @param client the client we received this message from
1095 * @param message the actual message received
1096 */
1097static void
1098handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client,
1099 const struct GNUNET_MessageHeader *message)
1100{
1101 const struct GNUNET_DHT_ClientGetResultSeenMessage *seen;
1102 uint16_t size;
1103 unsigned int hash_count;
1104 unsigned int old_count;
1105 const struct GNUNET_HashCode *hc;
1106 struct FindByUniqueIdContext fui_ctx;
1107 struct ClientQueryRecord *cqr;
1108
1109 size = ntohs (message->size);
1110 if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage))
1111 {
1112 GNUNET_break (0);
1113 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1114 return;
1115 }
1116 seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message;
1117 hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode);
1118 if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode))
1119 {
1120 GNUNET_break (0);
1121 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1122 return;
1123 }
1124 hc = (const struct GNUNET_HashCode*) &seen[1];
1125 fui_ctx.unique_id = seen->unique_id;
1126 fui_ctx.cqr = NULL;
1127 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
1128 &seen->key,
1129 &find_by_unique_id,
1130 &fui_ctx);
1131 if (NULL == (cqr = fui_ctx.cqr))
1132 {
1133 GNUNET_break (0);
1134 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1135 return;
1136 }
1137 /* finally, update 'seen' list */
1138 old_count = cqr->seen_replies_count;
1139 GNUNET_array_grow (cqr->seen_replies,
1140 cqr->seen_replies_count,
1141 cqr->seen_replies_count + hash_count);
1142 GNUNET_memcpy (&cqr->seen_replies[old_count],
1143 hc,
1144 sizeof (struct GNUNET_HashCode) * hash_count);
1145}
1146
1147
1148/**
1149 * Closure for 'remove_by_unique_id'.
1150 */
1151struct RemoveByUniqueIdContext
1152{
1153 /**
1154 * Client that issued the removal request.
1155 */
1156 struct ClientList *client;
1157
1158 /**
1159 * Unique ID of the request.
1160 */
1161 uint64_t unique_id;
1162};
1163
1164
1165/**
1166 * Iterator over hash map entries that frees all entries
1167 * that match the given client and unique ID.
1168 *
1169 * @param cls unique ID and client to search for in source routes
1170 * @param key current key code
1171 * @param value value in the hash map, a ClientQueryRecord
1172 * @return GNUNET_YES (we should continue to iterate)
1173 */
1174static int
1175remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value)
1176{
1177 const struct RemoveByUniqueIdContext *ctx = cls;
1178 struct ClientQueryRecord *record = value;
1179
1180 if (record->unique_id != ctx->unique_id)
1181 return GNUNET_YES;
1182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1183 "Removing client %p's record for key %s (by unique id)\n",
1184 ctx->client->client_handle, GNUNET_h2s (key));
1185 return remove_client_records (ctx->client, key, record);
1186}
1187
1188
1189/**
1190 * Handler for any generic DHT stop messages, calls the appropriate handler
1191 * depending on message type (if processed locally)
1192 *
1193 * @param cls closure for the service
1194 * @param client the client we received this message from
1195 * @param message the actual message received
1196 *
1197 */
1198static void
1199handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client,
1200 const struct GNUNET_MessageHeader *message)
1201{
1202 const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg =
1203 (const struct GNUNET_DHT_ClientGetStopMessage *) message;
1204 struct RemoveByUniqueIdContext ctx;
1205
1206 GNUNET_STATISTICS_update (GDS_stats,
1207 gettext_noop
1208 ("# GET STOP requests received from clients"), 1,
1209 GNUNET_NO);
1210 LOG (GNUNET_ERROR_TYPE_DEBUG,
1211 "Received GET STOP request for %s from local client %p\n",
1212 GNUNET_h2s (&dht_stop_msg->key),
1213 client);
1214 ctx.client = find_active_client (client);
1215 ctx.unique_id = dht_stop_msg->unique_id;
1216 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key,
1217 &remove_by_unique_id, &ctx);
1218 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1219}
1220
1221
1222/**
1223 * Handler for monitor start messages
1224 *
1225 * @param cls closure for the service
1226 * @param client the client we received this message from
1227 * @param message the actual message received
1228 *
1229 */
1230static void
1231handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client,
1232 const struct GNUNET_MessageHeader *message)
1233{
1234 struct ClientMonitorRecord *r;
1235 const struct GNUNET_DHT_MonitorStartStopMessage *msg;
1236
1237 msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message;
1238 r = GNUNET_new (struct ClientMonitorRecord);
1239
1240 r->client = find_active_client(client);
1241 r->type = ntohl(msg->type);
1242 r->get = ntohs(msg->get);
1243 r->get_resp = ntohs(msg->get_resp);
1244 r->put = ntohs(msg->put);
1245 if (0 == ntohs(msg->filter_key))
1246 r->key = NULL;
1247 else
1248 {
1249 r->key = GNUNET_new (struct GNUNET_HashCode);
1250 GNUNET_memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode));
1251 }
1252 GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r);
1253 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1254}
1255
1256
1257/**
1258 * Handler for monitor stop messages
1259 *
1260 * @param cls closure for the service
1261 * @param client the client we received this message from
1262 * @param message the actual message received
1263 *
1264 */
1265static void
1266handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client,
1267 const struct GNUNET_MessageHeader *message)
1268{
1269 struct ClientMonitorRecord *r;
1270 const struct GNUNET_DHT_MonitorStartStopMessage *msg;
1271 int keys_match;
1272
1273 msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message;
1274 r = monitor_head;
1275
1276 while (NULL != r)
1277 {
1278 if (NULL == r->key)
1279 keys_match = (0 == ntohs(msg->filter_key));
1280 else
1281 {
1282 keys_match = (0 != ntohs(msg->filter_key)
1283 && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode)));
1284 }
1285 if (find_active_client(client) == r->client
1286 && ntohl(msg->type) == r->type
1287 && r->get == msg->get
1288 && r->get_resp == msg->get_resp
1289 && r->put == msg->put
1290 && keys_match
1291 )
1292 {
1293 GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r);
1294 GNUNET_free_non_null (r->key);
1295 GNUNET_free (r);
1296 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1297 return; /* Delete only ONE entry */
1298 }
1299 r = r->next;
1300 }
1301
1302 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1303}
1304
1305
1306/**
1307 * Functions with this signature are called whenever a client
1308 * is disconnected on the network level.
1309 *
1310 * @param cls closure (NULL for dht)
1311 * @param client identification of the client; NULL
1312 * for the last call when the server is destroyed
1313 */
1314static void
1315handle_client_disconnect (void *cls,
1316 struct GNUNET_SERVER_Client *client)
1317{
1318 struct ClientList *pos;
1319 struct PendingMessage *reply;
1320 struct ClientMonitorRecord *monitor;
1321
1322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1323 "Local client %p disconnects\n",
1324 client);
1325 pos = find_active_client (client);
1326 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos);
1327 if (pos->transmit_handle != NULL)
1328 GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle);
1329 while (NULL != (reply = pos->pending_head))
1330 {
1331 GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply);
1332 GNUNET_free (reply);
1333 }
1334 monitor = monitor_head;
1335 while (NULL != monitor)
1336 {
1337 if (monitor->client == pos)
1338 {
1339 struct ClientMonitorRecord *next;
1340
1341 GNUNET_free_non_null (monitor->key);
1342 next = monitor->next;
1343 GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor);
1344 GNUNET_free (monitor);
1345 monitor = next;
1346 }
1347 else
1348 monitor = monitor->next;
1349 }
1350 GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records,
1351 pos);
1352 GNUNET_free (pos);
1353}
1354
1355
1356
1357/**
1358 * Initialize client subsystem.
1359 *
1360 * @param server the initialized server
1361 */
1362void
1363GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server)
1364{
1365 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
1366 {&handle_dht_local_put, NULL,
1367 GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, 0},
1368 {&handle_dht_local_get, NULL,
1369 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, 0},
1370 {&handle_dht_local_get_stop, NULL,
1371 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP,
1372 sizeof (struct GNUNET_DHT_ClientGetStopMessage)},
1373 {&handle_dht_local_monitor, NULL,
1374 GNUNET_MESSAGE_TYPE_DHT_MONITOR_START,
1375 sizeof (struct GNUNET_DHT_MonitorStartStopMessage)},
1376 {&handle_dht_local_monitor_stop, NULL,
1377 GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP,
1378 sizeof (struct GNUNET_DHT_MonitorStartStopMessage)},
1379 {&handle_dht_local_get_result_seen, NULL,
1380 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0},
1381 {NULL, NULL, 0, 0}
1382 };
1383 forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO);
1384 retry_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1385 GNUNET_SERVER_add_handlers (server, plugin_handlers);
1386 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1387}
1388
1389
1390/**
1391 * Shutdown client subsystem.
1392 */
1393void
1394GDS_CLIENTS_done ()
1395{
1396 GNUNET_assert (client_head == NULL);
1397 GNUNET_assert (client_tail == NULL);
1398 if (NULL != retry_task)
1399 {
1400 GNUNET_SCHEDULER_cancel (retry_task);
1401 retry_task = NULL;
1402 }
1403 if (NULL != retry_heap)
1404 {
1405 GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap));
1406 GNUNET_CONTAINER_heap_destroy (retry_heap);
1407 retry_heap = NULL;
1408 }
1409 if (NULL != forward_map)
1410 {
1411 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map));
1412 GNUNET_CONTAINER_multihashmap_destroy (forward_map);
1413 forward_map = NULL;
1414 }
1415}
1416
1417/* end of gnunet-service-dht_clients.c */
diff --git a/src/dht/gnunet-service-xdht_clients.h b/src/dht/gnunet-service-xdht_clients.h
deleted file mode 100644
index f51564136..000000000
--- a/src/dht/gnunet-service-xdht_clients.h
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-xdht_clients.h
23 * @brief GNUnet DHT service's client management code
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#ifndef GNUNET_SERVICE_DHT_CLIENT_H
28#define GNUNET_SERVICE_DHT_CLIENT_H
29
30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h"
32
33/**
34 * Handle a reply we've received from another peer. If the reply
35 * matches any of our pending queries, forward it to the respective
36 * client(s).
37 *
38 * @param expiration when will the reply expire
39 * @param key the query this reply is for
40 * @param get_path_length number of peers in @a get_path
41 * @param get_path path the reply took on get
42 * @param put_path_length number of peers in @a put_path
43 * @param put_path path the reply took on put
44 * @param type type of the reply
45 * @param data_size number of bytes in @a data
46 * @param data application payload data
47 */
48void
49GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration,
50 const struct GNUNET_HashCode *key,
51 unsigned int get_path_length,
52 const struct GNUNET_PeerIdentity *get_path,
53 unsigned int put_path_length,
54 const struct GNUNET_PeerIdentity *put_path,
55 enum GNUNET_BLOCK_Type type, size_t data_size,
56 const void *data);
57
58
59/**
60 * Check if some client is monitoring GET messages and notify
61 * them in that case.
62 *
63 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
64 * @param type The type of data in the request.
65 * @param hop_count Hop count so far.
66 * @param path_length number of entries in path (or 0 if not recorded).
67 * @param path peers on the GET path (or NULL if not recorded).
68 * @param desired_replication_level Desired replication level.
69 * @param key Key of the requested data.
70 */
71void
72GDS_CLIENTS_process_get (uint32_t options,
73 enum GNUNET_BLOCK_Type type,
74 uint32_t hop_count,
75 uint32_t desired_replication_level,
76 unsigned int path_length,
77 const struct GNUNET_PeerIdentity *path,
78 const struct GNUNET_HashCode *key);
79
80
81/**
82 * Check if some client is monitoring GET RESP messages and notify
83 * them in that case.
84 *
85 * @param type The type of data in the result.
86 * @param get_path Peers on GET path (or NULL if not recorded).
87 * @param get_path_length number of entries in @a get_path.
88 * @param put_path peers on the PUT path (or NULL if not recorded).
89 * @param put_path_length number of entries in @a get_path.
90 * @param exp Expiration time of the data.
91 * @param key Key of the @a data.
92 * @param data Pointer to the result data.
93 * @param size Number of bytes in @a data.
94 */
95void
96GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type,
97 const struct GNUNET_PeerIdentity *get_path,
98 unsigned int get_path_length,
99 const struct GNUNET_PeerIdentity *put_path,
100 unsigned int put_path_length,
101 struct GNUNET_TIME_Absolute exp,
102 const struct GNUNET_HashCode * key,
103 const void *data,
104 size_t size);
105
106
107/**
108 * Check if some client is monitoring PUT messages and notify
109 * them in that case.
110 *
111 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
112 * @param type The type of data in the request.
113 * @param hop_count Hop count so far.
114 * @param path_length number of entries in path (or 0 if not recorded).
115 * @param path peers on the PUT path (or NULL if not recorded).
116 * @param desired_replication_level Desired replication level.
117 * @param exp Expiration time of the data.
118 * @param key Key under which data is to be stored.
119 * @param data Pointer to the data carried.
120 * @param size Number of bytes in data.
121 */
122void
123GDS_CLIENTS_process_put (uint32_t options,
124 enum GNUNET_BLOCK_Type type,
125 uint32_t hop_count,
126 uint32_t desired_replication_level,
127 unsigned int path_length,
128 const struct GNUNET_PeerIdentity *path,
129 struct GNUNET_TIME_Absolute exp,
130 const struct GNUNET_HashCode * key,
131 const void *data,
132 size_t size);
133
134/**
135 * Initialize client subsystem.
136 *
137 * @param server the initialized server
138 */
139void
140GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server);
141
142
143/**
144 * Shutdown client subsystem.
145 */
146void
147GDS_CLIENTS_done (void);
148
149#endif
diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c
deleted file mode 100644
index 10ae0068e..000000000
--- a/src/dht/gnunet-service-xdht_datacache.c
+++ /dev/null
@@ -1,401 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file dht/gnunet-service-xdht_datacache.c
22 * @brief GNUnet DHT service's datacache integration
23 * @author Christian Grothoff
24 * @author Nathan Evans
25 */
26#include "platform.h"
27#include "gnunet_datacache_lib.h"
28#include "gnunet-service-xdht_clients.h"
29#include "gnunet-service-xdht_datacache.h"
30#include "gnunet-service-xdht_routing.h"
31#include "gnunet-service-xdht_neighbours.h"
32#include "gnunet-service-dht.h"
33
34#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__)
35
36#define DEBUG(...) \
37 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
38
39/**
40 * Handle to the datacache service (for inserting/retrieving data)
41 */
42static struct GNUNET_DATACACHE_Handle *datacache;
43
44
45/**
46 * Handle a datum we've received from another peer. Cache if
47 * possible.
48 *
49 * @param expiration when will the reply expire
50 * @param key the query this reply is for
51 * @param put_path_length number of peers in @a put_path
52 * @param put_path path the reply took on put
53 * @param type type of the reply
54 * @param data_size number of bytes in @a data
55 * @param data application payload data
56 */
57void
58GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
59 const struct GNUNET_HashCode *key,
60 unsigned int put_path_length,
61 const struct GNUNET_PeerIdentity *put_path,
62 enum GNUNET_BLOCK_Type type,
63 size_t data_size,
64 const void *data)
65{
66 int r;
67
68 if (NULL == datacache)
69 {
70 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
71 "PUT request received, but have no datacache!\n");
72 return;
73 }
74 if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
75 {
76 GNUNET_break (0);
77 return;
78 }
79
80 /* Put size is actual data size plus struct overhead plus path length (if any) */
81 r = GNUNET_DATACACHE_put (datacache,
82 key,
83 data_size,
84 data,
85 type,
86 expiration,
87 put_path_length,
88 put_path);
89 if (GNUNET_OK == r)
90 GNUNET_STATISTICS_update (GDS_stats,
91 gettext_noop ("# ITEMS stored in datacache"), 1,
92 GNUNET_NO);
93 LOG (GNUNET_ERROR_TYPE_DEBUG,
94 "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n",
95 GNUNET_h2s (key),
96 data_size,
97 r,
98 put_path_length);
99}
100
101
102/**
103 * List of peers in the get path.
104 */
105struct GetPath
106{
107 /**
108 * Pointer to next item in the list
109 */
110 struct GetPath *next;
111
112 /**
113 * Pointer to previous item in the list
114 */
115 struct GetPath *prev;
116
117 /**
118 * An element in the get path.
119 */
120 struct GNUNET_PeerIdentity peer;
121};
122
123
124/**
125 * Context containing information about a GET request.
126 */
127struct GetRequestContext
128{
129 /**
130 * extended query (see gnunet_block_lib.h).
131 */
132 const void *xquery;
133
134 /**
135 * Bloomfilter to filter out duplicate replies (updated)
136 */
137 struct GNUNET_CONTAINER_BloomFilter **reply_bf;
138
139 /**
140 * The key this request was about
141 */
142 struct GNUNET_HashCode key;
143
144 /**
145 * Number of bytes in xquery.
146 */
147 size_t xquery_size;
148
149 /**
150 * Mutator value for the @e reply_bf, see gnunet_block_lib.h
151 */
152 uint32_t reply_bf_mutator;
153
154 /**
155 * Total number of peers in get path.
156 */
157 unsigned int get_path_length;
158
159 /**
160 * Return value to give back.
161 */
162 enum GNUNET_BLOCK_EvaluationResult eval;
163
164 /**
165 * Peeer which has the data for the key.
166 */
167 struct GNUNET_PeerIdentity source_peer;
168
169 /**
170 * Next hop to forward the get result to.
171 */
172 struct GNUNET_PeerIdentity next_hop;
173
174 /**
175 * Head of get path.
176 */
177 struct GetPath *head;
178
179 /**
180 * Tail of get path.
181 */
182 struct GetPath *tail;
183
184 /* get_path */
185};
186
187
188/**
189 * Iterator for local get request results,
190 *
191 * @param cls closure for iterator, a `struct GetRequestContext`
192 * @param key the key this @a data is stored under
193 * @param size the size of the data identified by key
194 * @param data the actual data
195 * @param type the type of the @a data
196 * @param exp when does this value expire?
197 * @param put_path_length number of peers in @a put_path
198 * @param put_path path the reply took on put
199 * @return #GNUNET_OK to continue iteration, anything else
200 * to stop iteration.
201 */
202static int
203datacache_get_iterator (void *cls,
204 const struct GNUNET_HashCode *key,
205 size_t size,
206 const char *data,
207 enum GNUNET_BLOCK_Type type,
208 struct GNUNET_TIME_Absolute exp,
209 unsigned int put_path_length,
210 const struct GNUNET_PeerIdentity *put_path)
211{
212 struct GetRequestContext *ctx = cls;
213 enum GNUNET_BLOCK_EvaluationResult eval;
214
215 eval =
216 GNUNET_BLOCK_evaluate (GDS_block_context,
217 type,
218 GNUNET_BLOCK_EO_NONE,
219 key,
220 ctx->reply_bf,
221 ctx->reply_bf_mutator,
222 ctx->xquery,
223 ctx->xquery_size,
224 data,
225 size);
226 LOG (GNUNET_ERROR_TYPE_DEBUG,
227 "Found reply for query %s in datacache, evaluation result is %d\n",
228 GNUNET_h2s (key), (int) eval);
229 ctx->eval = eval;
230
231 switch (eval)
232 {
233 case GNUNET_BLOCK_EVALUATION_OK_MORE:
234 case GNUNET_BLOCK_EVALUATION_OK_LAST:
235 /* forward to local clients */
236 GNUNET_STATISTICS_update (GDS_stats,
237 gettext_noop
238 ("# Good RESULTS found in datacache"), 1,
239 GNUNET_NO);
240 struct GNUNET_PeerIdentity *get_path;
241 get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) *
242 ctx->get_path_length);
243 struct GetPath *iterator;
244 iterator = ctx->head;
245 int i = 0;
246 while (i < ctx->get_path_length)
247 {
248 get_path[i] = iterator->peer;
249 i++;
250 iterator = iterator->next;
251 }
252 GDS_NEIGHBOURS_send_get_result (key,type,
253 &ctx->next_hop,
254 &ctx->source_peer,
255 put_path_length,
256 put_path,
257 ctx->get_path_length,
258 get_path,
259 exp,
260 data,
261 size);
262 GNUNET_free_non_null (get_path);
263 break;
264 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
265 GNUNET_STATISTICS_update (GDS_stats,
266 gettext_noop
267 ("# Duplicate RESULTS found in datacache"), 1,
268 GNUNET_NO);
269 break;
270 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
271 GNUNET_STATISTICS_update (GDS_stats,
272 gettext_noop
273 ("# Invalid RESULTS found in datacache"), 1,
274 GNUNET_NO);
275 break;
276 case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT:
277 GNUNET_STATISTICS_update (GDS_stats,
278 gettext_noop
279 ("# Irrelevant RESULTS found in datacache"), 1,
280 GNUNET_NO);
281 break;
282 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
283 GNUNET_break (0);
284 break;
285 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
286 GNUNET_break_op (0);
287 return GNUNET_SYSERR;
288 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
289 GNUNET_STATISTICS_update (GDS_stats,
290 gettext_noop
291 ("# Unsupported RESULTS found in datacache"), 1,
292 GNUNET_NO);
293 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
294 _("Unsupported block type (%u) in local response!\n"),
295 type);
296 break;
297 }
298
299 return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK;
300}
301
302
303/**
304 * Handle a GET request we've received from another peer.
305 *
306 * @param key the query
307 * @param type requested data type
308 * @param xquery extended query
309 * @param xquery_size number of bytes in @a xquery
310 * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL
311 * @param reply_bf_mutator mutation value for @a reply_bf
312 * @return evaluation result for the local replies
313 * @get_path_length Total number of peers in get path
314 * @get_path Peers in get path.
315 */
316enum GNUNET_BLOCK_EvaluationResult
317GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key,
318 enum GNUNET_BLOCK_Type type,
319 const void *xquery,
320 size_t xquery_size,
321 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
322 uint32_t reply_bf_mutator,
323 uint32_t get_path_length,
324 struct GNUNET_PeerIdentity *get_path,
325 struct GNUNET_PeerIdentity *next_hop,
326 struct GNUNET_PeerIdentity *source_peer)
327{
328 struct GetRequestContext ctx;
329 unsigned int r;
330
331 if (datacache == NULL)
332 return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
333 GNUNET_STATISTICS_update (GDS_stats,
334 gettext_noop ("# GET requests given to datacache"),
335 1, GNUNET_NO);
336 ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
337 ctx.key = *key;
338 ctx.xquery = xquery;
339 ctx.xquery_size = xquery_size;
340 ctx.reply_bf = reply_bf;
341 ctx.reply_bf_mutator = reply_bf_mutator;
342 ctx.get_path_length = get_path_length;
343
344 if (NULL != next_hop)
345 ctx.next_hop = *next_hop;
346 unsigned int i = 0;
347
348 ctx.head = NULL;
349 ctx.tail = NULL;
350 if (NULL != get_path)
351 {
352 while (i < get_path_length)
353 {
354 struct GetPath *element;
355 element = GNUNET_new (struct GetPath);
356 element->next = NULL;
357 element->prev = NULL;
358 element->peer = get_path[i];
359 GNUNET_CONTAINER_DLL_insert_tail (ctx.head, ctx.tail, element);
360 i++;
361 }
362 }
363
364 r = GNUNET_DATACACHE_get (datacache,
365 key,
366 type,
367 &datacache_get_iterator,
368 &ctx);
369 DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n",
370 GNUNET_h2s (key),
371 ctx.eval,
372 r);
373 return ctx.eval;
374}
375
376
377/**
378 * Initialize datacache subsystem.
379 */
380void
381GDS_DATACACHE_init ()
382{
383 datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache");
384}
385
386
387/**
388 * Shutdown datacache subsystem.
389 */
390void
391GDS_DATACACHE_done ()
392{
393 if (NULL != datacache)
394 {
395 GNUNET_DATACACHE_destroy (datacache);
396 datacache = NULL;
397 }
398}
399
400
401/* end of gnunet-service-xdht_datacache.c */
diff --git a/src/dht/gnunet-service-xdht_datacache.h b/src/dht/gnunet-service-xdht_datacache.h
deleted file mode 100644
index f160d03bc..000000000
--- a/src/dht/gnunet-service-xdht_datacache.h
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-dht_datacache.h
23 * @brief GNUnet DHT service's datacache integration
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#ifndef GNUNET_SERVICE_DHT_DATACACHE_H
28#define GNUNET_SERVICE_DHT_DATACACHE_H
29
30#include "gnunet_util_lib.h"
31#include "gnunet_block_lib.h"
32
33/**
34 * Handle a datum we've received from another peer. Cache if
35 * possible.
36 *
37 * @param expiration when will the reply expire
38 * @param key the query this reply is for
39 * @param put_path_length number of peers in 'put_path'
40 * @param put_path path the reply took on put
41 * @param type type of the reply
42 * @param data_size number of bytes in 'data'
43 * @param data application payload data
44 */
45void
46GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration,
47 const struct GNUNET_HashCode * key,
48 unsigned int put_path_length,
49 const struct GNUNET_PeerIdentity *put_path,
50 enum GNUNET_BLOCK_Type type, size_t data_size,
51 const void *data);
52
53
54/**
55 * Handle a GET request we've received from another peer.
56 *
57 * @param key the query
58 * @param type requested data type
59 * @param xquery extended query
60 * @param xquery_size number of bytes in xquery
61 * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL
62 * @param reply_bf_mutator mutation value for reply_bf
63 * @return evaluation result for the local replies
64 */
65enum GNUNET_BLOCK_EvaluationResult
66GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key,
67 enum GNUNET_BLOCK_Type type, const void *xquery,
68 size_t xquery_size,
69 struct GNUNET_CONTAINER_BloomFilter **reply_bf,
70 uint32_t reply_bf_mutator,
71 uint32_t get_path_length,
72 struct GNUNET_PeerIdentity *get_path,
73 struct GNUNET_PeerIdentity *next_hop,
74 struct GNUNET_PeerIdentity *source_peer);
75
76
77/**
78 * Initialize datacache subsystem.
79 */
80void
81GDS_DATACACHE_init (void);
82
83
84/**
85 * Shutdown datacache subsystem.
86 */
87void
88GDS_DATACACHE_done (void);
89
90#endif
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c
index 7ab462a58..e3462f618 100644
--- a/src/dht/gnunet-service-xdht_neighbours.c
+++ b/src/dht/gnunet-service-xdht_neighbours.c
@@ -37,10 +37,9 @@
37#include "gnunet_transport_service.h" 37#include "gnunet_transport_service.h"
38#include "gnunet_dht_service.h" 38#include "gnunet_dht_service.h"
39#include "gnunet_statistics_service.h" 39#include "gnunet_statistics_service.h"
40#include "gnunet-service-xdht.h" 40#include "gnunet-service-dht.h"
41#include "gnunet-service-xdht_clients.h" 41#include "gnunet-service-dht_datacache.h"
42#include "gnunet-service-xdht_datacache.h" 42#include "gnunet-service-dht_neighbours.h"
43#include "gnunet-service-xdht_neighbours.h"
44#include "gnunet-service-xdht_routing.h" 43#include "gnunet-service-xdht_routing.h"
45#include "dht.h" 44#include "dht.h"
46 45
@@ -1017,7 +1016,7 @@ GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *queryi
1017 tsrm->finger_identity = *finger; 1016 tsrm->finger_identity = *finger;
1018 tsrm->is_predecessor = htonl (is_predecessor); 1017 tsrm->is_predecessor = htonl (is_predecessor);
1019 tsrm->trail_id = *trail_id; 1018 tsrm->trail_id = *trail_id;
1020 tsrm->ultimate_destination_finger_value 1019 tsrm->ultimate_destination_finger_value
1021 = GNUNET_htonll (ultimate_destination_finger_value); 1020 = GNUNET_htonll (ultimate_destination_finger_value);
1022 GNUNET_memcpy (&tsrm[1], 1021 GNUNET_memcpy (&tsrm[1],
1023 trail_peer_list, 1022 trail_peer_list,
@@ -1114,7 +1113,7 @@ GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_pe
1114 trm->congestion_time = congestion_timeout; 1113 trm->congestion_time = congestion_timeout;
1115 trm->is_predecessor = htonl (is_predecessor); 1114 trm->is_predecessor = htonl (is_predecessor);
1116 trm->trail_id = *trail_id; 1115 trm->trail_id = *trail_id;
1117 trm->ultimate_destination_finger_value 1116 trm->ultimate_destination_finger_value
1118 = GNUNET_htonll (ultimate_destination_finger_value); 1117 = GNUNET_htonll (ultimate_destination_finger_value);
1119 GNUNET_memcpy (&trm[1], 1118 GNUNET_memcpy (&trm[1],
1120 trail_peer_list, 1119 trail_peer_list,
@@ -1957,7 +1956,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
1957 GNUNET_break (0); 1956 GNUNET_break (0);
1958 return; 1957 return;
1959 } 1958 }
1960 1959
1961 GNUNET_assert (NULL != 1960 GNUNET_assert (NULL !=
1962 (target_friend = 1961 (target_friend =
1963 GNUNET_CONTAINER_multipeermap_get (friend_peermap, 1962 GNUNET_CONTAINER_multipeermap_get (friend_peermap,
@@ -1989,20 +1988,29 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key,
1989/** 1988/**
1990 * Handle the put request from the client. 1989 * Handle the put request from the client.
1991 * 1990 *
1992 * @param key Key for the content
1993 * @param block_type Type of the block 1991 * @param block_type Type of the block
1994 * @param options Routing options 1992 * @param options Routing options
1995 * @param desired_replication_level Desired replication count 1993 * @param desired_replication_level Desired replication count
1996 * @param expiration_time When does the content expire 1994 * @param expiration_time When does the content expire
1995 * @param hop_count how many hops has this message traversed so far
1996 * @param bf Bloom filter of peers this PUT has already traversed
1997 * @param key Key for the content
1998 * @param put_path_length number of entries in put_path
1999 * @param put_path peers this request has traversed so far (if tracked)
1997 * @param data Content to store 2000 * @param data Content to store
1998 * @param data_size Size of content @a data in bytes 2001 * @param data_size Size of content @a data in bytes
2002 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
1999 */ 2003 */
2000void 2004int
2001GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, 2005GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type,
2002 enum GNUNET_BLOCK_Type block_type,
2003 enum GNUNET_DHT_RouteOption options, 2006 enum GNUNET_DHT_RouteOption options,
2004 uint32_t desired_replication_level, 2007 uint32_t desired_replication_level,
2005 struct GNUNET_TIME_Absolute expiration_time, 2008 struct GNUNET_TIME_Absolute expiration_time,
2009 uint32_t hop_count,
2010 struct GNUNET_CONTAINER_BloomFilter *bf,
2011 const struct GNUNET_HashCode *key,
2012 unsigned int put_path_length,
2013 struct GNUNET_PeerIdentity *put_path,
2006 const void *data, 2014 const void *data,
2007 size_t data_size) 2015 size_t data_size)
2008{ 2016{
@@ -2045,7 +2053,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
2045 key, 2053 key,
2046 data, 2054 data,
2047 data_size); 2055 data_size);
2048 return; 2056 return GNUNET_NO;
2049 } 2057 }
2050 /* In case we are sending the request to a finger, then send across all of its 2058 /* In case we are sending the request to a finger, then send across all of its
2051 trail.*/ 2059 trail.*/
@@ -2062,6 +2070,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
2062 expiration_time, 2070 expiration_time,
2063 data, 2071 data,
2064 data_size); 2072 data_size);
2073 return GNUNET_OK;
2065} 2074}
2066 2075
2067 2076
@@ -2099,7 +2108,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2099 struct GNUNET_MQ_Envelope *env; 2108 struct GNUNET_MQ_Envelope *env;
2100 struct FriendInfo *target_friend; 2109 struct FriendInfo *target_friend;
2101 size_t msize; 2110 size_t msize;
2102 2111
2103 msize = get_path_length * sizeof (struct GNUNET_PeerIdentity); 2112 msize = get_path_length * sizeof (struct GNUNET_PeerIdentity);
2104 if (msize + sizeof (struct PeerGetMessage) 2113 if (msize + sizeof (struct PeerGetMessage)
2105 >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) 2114 >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)
@@ -2129,70 +2138,10 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key,
2129 2138
2130 2139
2131/** 2140/**
2132 * Handle the get request from the client file. If I am destination do
2133 * datacache put and return. Else find the target friend and forward message
2134 * to it.
2135 *
2136 * @param key Key for the content
2137 * @param block_type Type of the block
2138 * @param options Routing options
2139 * @param desired_replication_level Desired replication count
2140 */
2141void
2142GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
2143 enum GNUNET_BLOCK_Type block_type,
2144 enum GNUNET_DHT_RouteOption options,
2145 uint32_t desired_replication_level)
2146{
2147 struct Closest_Peer successor;
2148 struct GNUNET_PeerIdentity best_known_dest;
2149 struct GNUNET_HashCode intermediate_trail_id;
2150 uint64_t key_value;
2151
2152 GNUNET_memcpy (&key_value,
2153 key,
2154 sizeof (uint64_t));
2155 key_value = GNUNET_ntohll (key_value);
2156 successor = find_local_best_known_next_hop (key_value,
2157 GDS_FINGER_TYPE_NON_PREDECESSOR);
2158 best_known_dest = successor.best_known_destination;
2159 intermediate_trail_id = successor.trail_id;
2160
2161 /* I am the destination. I have the data. */
2162 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
2163 &best_known_dest))
2164 {
2165 GDS_DATACACHE_handle_get (key,
2166 block_type,
2167 NULL,
2168 0,
2169 NULL,
2170 0,
2171 1,
2172 &my_identity,
2173 NULL,
2174 &my_identity);
2175 return;
2176 }
2177
2178 GDS_NEIGHBOURS_send_get (key,
2179 block_type,
2180 options,
2181 desired_replication_level,
2182 &best_known_dest,
2183 &intermediate_trail_id,
2184 &successor.next_hop,
2185 0,
2186 1,
2187 &my_identity);
2188}
2189
2190
2191/**
2192 * Send the get result to requesting client. 2141 * Send the get result to requesting client.
2193 * 2142 *
2194 * @param key Key of the requested data. 2143 * @param key Key of the requested data.
2195 * @param type Block type 2144 * @param block_type Block type
2196 * @param target_peer Next peer to forward the message to. 2145 * @param target_peer Next peer to forward the message to.
2197 * @param source_peer Peer which has the data for the key. 2146 * @param source_peer Peer which has the data for the key.
2198 * @param put_path_length Number of peers in @a put_path 2147 * @param put_path_length Number of peers in @a put_path
@@ -2205,7 +2154,7 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
2205 */ 2154 */
2206void 2155void
2207GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, 2156GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
2208 enum GNUNET_BLOCK_Type type, 2157 enum GNUNET_BLOCK_Type block_type,
2209 const struct GNUNET_PeerIdentity *target_peer, 2158 const struct GNUNET_PeerIdentity *target_peer,
2210 const struct GNUNET_PeerIdentity *source_peer, 2159 const struct GNUNET_PeerIdentity *source_peer,
2211 unsigned int put_path_length, 2160 unsigned int put_path_length,
@@ -2256,15 +2205,15 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
2256 if (0 == current_path_index) 2205 if (0 == current_path_index)
2257 { 2206 {
2258 DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s", 2207 DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s",
2259 GNUNET_h2s(key), 2208 GNUNET_h2s (key),
2260 GNUNET_i2s(&my_identity)); 2209 GNUNET_i2s (&my_identity));
2261 GDS_CLIENTS_handle_reply (expiration, 2210 GDS_CLIENTS_handle_reply (expiration,
2262 key, 2211 key,
2263 get_path_length, 2212 get_path_length,
2264 get_path, 2213 get_path,
2265 put_path_length, 2214 put_path_length,
2266 put_path, 2215 put_path,
2267 type, 2216 block_type,
2268 data_size, 2217 data_size,
2269 data); 2218 data);
2270 return; 2219 return;
@@ -2298,6 +2247,120 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
2298 2247
2299 2248
2300/** 2249/**
2250 * Handle a result for a GET operation.
2251 *
2252 * @param cls closure
2253 * @param type type of the block
2254 * @param expiration_time when does the content expire
2255 * @param key key for the content
2256 * @param put_path_length number of entries in @a put_path
2257 * @param put_path peers the original PUT traversed (if tracked)
2258 * @param get_path_length number of entries in @a get_path
2259 * @param get_path peers this reply has traversed so far (if tracked)
2260 * @param data payload of the reply
2261 * @param data_size number of bytes in @a data
2262 */
2263static void
2264get_cb (void *cls,
2265 enum GNUNET_BLOCK_Type type,
2266 struct GNUNET_TIME_Absolute expiration_time,
2267 const struct GNUNET_HashCode *key,
2268 unsigned int put_path_length,
2269 const struct GNUNET_PeerIdentity *put_path,
2270 unsigned int get_path_length,
2271 const struct GNUNET_PeerIdentity *get_path,
2272 const void *data,
2273 size_t data_size)
2274{
2275 struct GNUNET_PeerIdentity *target_peer = cls;
2276 // FIXME: inline?
2277 GDS_NEIGHBOURS_send_get_result (key,
2278 type,
2279 target_peer,
2280 &my_identity,
2281 put_path_length,
2282 put_path,
2283 1,
2284 &my_identity,
2285 expiration_time,
2286 data,
2287 data_size);
2288}
2289
2290
2291/**
2292 * Perform a GET operation. Forwards the given request to other
2293 * peers. Does not lookup the key locally. May do nothing if this is
2294 * the only peer in the network (or if we are the closest peer in the
2295 * network).
2296 *
2297 * @param block_type type of the block
2298 * @param options routing options
2299 * @param desired_replication_level desired replication count
2300 * @param hop_count how many hops did this request traverse so far?
2301 * @param key key for the content
2302 * @param xquery extended query
2303 * @param xquery_size number of bytes in @a xquery
2304 * @param reply_bf bloomfilter to filter duplicates
2305 * @param reply_bf_mutator mutator for @a reply_bf
2306 * @param peer_bf filter for peers not to select (again, updated)
2307 * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not
2308 */
2309int
2310GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type,
2311 enum GNUNET_DHT_RouteOption options,
2312 uint32_t desired_replication_level,
2313 uint32_t hop_count,
2314 const struct GNUNET_HashCode *key,
2315 const void *xquery, size_t xquery_size,
2316 const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
2317 uint32_t reply_bf_mutator,
2318 struct GNUNET_CONTAINER_BloomFilter *peer_bf)
2319{
2320 struct Closest_Peer successor;
2321 struct GNUNET_PeerIdentity best_known_dest;
2322 struct GNUNET_HashCode intermediate_trail_id;
2323 uint64_t key_value;
2324
2325 GNUNET_memcpy (&key_value,
2326 key,
2327 sizeof (uint64_t));
2328 key_value = GNUNET_ntohll (key_value);
2329 successor = find_local_best_known_next_hop (key_value,
2330 GDS_FINGER_TYPE_NON_PREDECESSOR);
2331 best_known_dest = successor.best_known_destination;
2332 intermediate_trail_id = successor.trail_id;
2333
2334 /* I am the destination. I have the data. */
2335 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
2336 &best_known_dest))
2337 {
2338 GDS_DATACACHE_handle_get (key,
2339 block_type,
2340 NULL,
2341 0,
2342 NULL,
2343 0,
2344 &get_cb,
2345 NULL);
2346 return GNUNET_NO;
2347 }
2348
2349 GDS_NEIGHBOURS_send_get (key,
2350 block_type,
2351 options,
2352 desired_replication_level,
2353 &best_known_dest,
2354 &intermediate_trail_id,
2355 &successor.next_hop,
2356 0,
2357 1,
2358 &my_identity);
2359 return GNUNET_OK;
2360}
2361
2362
2363/**
2301 * Randomly choose one of your friends (which is not congested and have not crossed 2364 * Randomly choose one of your friends (which is not congested and have not crossed
2302 * trail threshold) from the friend_peermap 2365 * trail threshold) from the friend_peermap
2303 * @return Friend Randomly chosen friend. 2366 * @return Friend Randomly chosen friend.
@@ -3121,7 +3184,7 @@ update_current_search_finger_index (unsigned int finger_table_index)
3121 { 3184 {
3122 if (NULL == send_verify_successor_task) 3185 if (NULL == send_verify_successor_task)
3123 { 3186 {
3124 send_verify_successor_task 3187 send_verify_successor_task
3125 = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, 3188 = GNUNET_SCHEDULER_add_now (&send_verify_successor_message,
3126 NULL); 3189 NULL);
3127 } 3190 }
@@ -3389,7 +3452,7 @@ finger_table_add (const struct GNUNET_PeerIdentity *finger_identity,
3389 else 3452 else
3390 select_and_replace_trail (existing_finger, 3453 select_and_replace_trail (existing_finger,
3391 finger_trail, 3454 finger_trail,
3392 finger_trail_length, 3455 finger_trail_length,
3393 finger_trail_id); 3456 finger_trail_id);
3394 } 3457 }
3395 update_current_search_finger_index (finger_table_index); 3458 update_current_search_finger_index (finger_table_index);
@@ -3425,7 +3488,7 @@ check_dht_p2p_put (void *cls,
3425 return GNUNET_OK; 3488 return GNUNET_OK;
3426} 3489}
3427 3490
3428 3491
3429/** 3492/**
3430 * Core handler for P2P put messages. 3493 * Core handler for P2P put messages.
3431 * 3494 *
@@ -3435,7 +3498,7 @@ check_dht_p2p_put (void *cls,
3435static void 3498static void
3436handle_dht_p2p_put (void *cls, 3499handle_dht_p2p_put (void *cls,
3437 const struct PeerPutMessage *put) 3500 const struct PeerPutMessage *put)
3438{ 3501{
3439 struct GNUNET_PeerIdentity *put_path; 3502 struct GNUNET_PeerIdentity *put_path;
3440 struct GNUNET_PeerIdentity current_best_known_dest; 3503 struct GNUNET_PeerIdentity current_best_known_dest;
3441 struct GNUNET_PeerIdentity best_known_dest; 3504 struct GNUNET_PeerIdentity best_known_dest;
@@ -3623,7 +3686,7 @@ handle_dht_p2p_put (void *cls,
3623 * @return #GNUNET_OK if @a get is well-formed 3686 * @return #GNUNET_OK if @a get is well-formed
3624 */ 3687 */
3625static int 3688static int
3626check_dht_p2p_get (void *cls, 3689check_dht_p2p_get (void *cls,
3627 const struct PeerGetMessage *get) 3690 const struct PeerGetMessage *get)
3628{ 3691{
3629 uint32_t get_length; 3692 uint32_t get_length;
@@ -3653,7 +3716,7 @@ check_dht_p2p_get (void *cls,
3653 * @param get the message 3716 * @param get the message
3654 */ 3717 */
3655static void 3718static void
3656handle_dht_p2p_get (void *cls, 3719handle_dht_p2p_get (void *cls,
3657 const struct PeerGetMessage *get) 3720 const struct PeerGetMessage *get)
3658{ 3721{
3659 const struct GNUNET_PeerIdentity *get_path; 3722 const struct GNUNET_PeerIdentity *get_path;
@@ -3744,10 +3807,8 @@ handle_dht_p2p_get (void *cls,
3744 0, 3807 0,
3745 NULL, 3808 NULL,
3746 0, 3809 0,
3747 1, 3810 &get_cb,
3748 &my_identity, 3811 NULL);
3749 NULL,
3750 &my_identity);
3751 } 3812 }
3752 else 3813 else
3753 { 3814 {
@@ -3757,10 +3818,8 @@ handle_dht_p2p_get (void *cls,
3757 0, 3818 0,
3758 NULL, 3819 NULL,
3759 0, 3820 0,
3760 get_length, 3821 &get_cb,
3761 gp, 3822 &gp[get_length - 2]);
3762 &gp[get_length - 2],
3763 &my_identity);
3764 } 3823 }
3765 } 3824 }
3766 else 3825 else
@@ -3822,7 +3881,7 @@ check_dht_p2p_get_result (void *cls,
3822static void 3881static void
3823handle_dht_p2p_get_result (void *cls, 3882handle_dht_p2p_get_result (void *cls,
3824 const struct PeerGetResultMessage *get_result) 3883 const struct PeerGetResultMessage *get_result)
3825{ 3884{
3826 const struct GNUNET_PeerIdentity *get_path; 3885 const struct GNUNET_PeerIdentity *get_path;
3827 const struct GNUNET_PeerIdentity *put_path; 3886 const struct GNUNET_PeerIdentity *put_path;
3828 const void *payload; 3887 const void *payload;
@@ -3965,7 +4024,7 @@ get_local_best_known_next_hop (uint64_t final_dest_finger_val,
3965 * @return #GNUNET_OK if @a trail_setup is well-formed 4024 * @return #GNUNET_OK if @a trail_setup is well-formed
3966 */ 4025 */
3967static int 4026static int
3968check_dht_p2p_trail_setup (void *cls, 4027check_dht_p2p_trail_setup (void *cls,
3969 const struct PeerTrailSetupMessage *trail_setup) 4028 const struct PeerTrailSetupMessage *trail_setup)
3970{ 4029{
3971 size_t msize; 4030 size_t msize;
@@ -3988,7 +4047,7 @@ check_dht_p2p_trail_setup (void *cls,
3988 * @param trail_setup the message 4047 * @param trail_setup the message
3989 */ 4048 */
3990static void 4049static void
3991handle_dht_p2p_trail_setup (void *cls, 4050handle_dht_p2p_trail_setup (void *cls,
3992 const struct PeerTrailSetupMessage *trail_setup) 4051 const struct PeerTrailSetupMessage *trail_setup)
3993{ 4052{
3994 struct FriendInfo *friend = cls; 4053 struct FriendInfo *friend = cls;
@@ -4014,7 +4073,7 @@ handle_dht_p2p_trail_setup (void *cls,
4014 trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_setup[1]; 4073 trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_setup[1];
4015 current_dest = trail_setup->best_known_destination; 4074 current_dest = trail_setup->best_known_destination;
4016 trail_id = trail_setup->trail_id; 4075 trail_id = trail_setup->trail_id;
4017 final_dest_finger_val 4076 final_dest_finger_val
4018 = GNUNET_ntohll (trail_setup->final_destination_finger_value); 4077 = GNUNET_ntohll (trail_setup->final_destination_finger_value);
4019 source = trail_setup->source_peer; 4078 source = trail_setup->source_peer;
4020 is_predecessor = ntohl (trail_setup->is_predecessor); 4079 is_predecessor = ntohl (trail_setup->is_predecessor);
@@ -4024,7 +4083,7 @@ handle_dht_p2p_trail_setup (void *cls,
4024 if ( (trail_length > 0) && 4083 if ( (trail_length > 0) &&
4025 (0 != memcmp (&trail_peer_list[trail_length-1], 4084 (0 != memcmp (&trail_peer_list[trail_length-1],
4026 friend->id, 4085 friend->id,
4027 sizeof (struct GNUNET_PeerIdentity))) ) 4086 sizeof (struct GNUNET_PeerIdentity))) )
4028 { 4087 {
4029 GNUNET_break_op (0); 4088 GNUNET_break_op (0);
4030 return; 4089 return;
@@ -4052,7 +4111,7 @@ handle_dht_p2p_trail_setup (void *cls,
4052 /* Is my routing table full? */ 4111 /* Is my routing table full? */
4053 if (GNUNET_YES == GDS_ROUTING_threshold_reached ()) 4112 if (GNUNET_YES == GDS_ROUTING_threshold_reached ())
4054 { 4113 {
4055 target_friend 4114 target_friend
4056 = (trail_length > 0) 4115 = (trail_length > 0)
4057 ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, 4116 ? GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4058 &trail_peer_list[trail_length - 1]) 4117 &trail_peer_list[trail_length - 1])
@@ -4077,7 +4136,7 @@ handle_dht_p2p_trail_setup (void *cls,
4077 } 4136 }
4078 4137
4079 /* Get the next hop to forward the trail setup request. */ 4138 /* Get the next hop to forward the trail setup request. */
4080 struct Closest_Peer next_peer 4139 struct Closest_Peer next_peer
4081 = get_local_best_known_next_hop (final_dest_finger_val, 4140 = get_local_best_known_next_hop (final_dest_finger_val,
4082 &intermediate_trail_id, 4141 &intermediate_trail_id,
4083 is_predecessor, 4142 is_predecessor,
@@ -4100,7 +4159,7 @@ handle_dht_p2p_trail_setup (void *cls,
4100 return; 4159 return;
4101 } 4160 }
4102 4161
4103 target_friend 4162 target_friend
4104 = (trail_length > 0) 4163 = (trail_length > 0)
4105 ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, 4164 ? GNUNET_CONTAINER_multipeermap_get (friend_peermap,
4106 &trail_peer_list[trail_length-1]) 4165 &trail_peer_list[trail_length-1])
@@ -4139,7 +4198,7 @@ handle_dht_p2p_trail_setup (void *cls,
4139 { 4198 {
4140 /* Add yourself to list of peers. */ 4199 /* Add yourself to list of peers. */
4141 struct GNUNET_PeerIdentity peer_list[trail_length + 1]; 4200 struct GNUNET_PeerIdentity peer_list[trail_length + 1];
4142 4201
4143 GNUNET_memcpy (peer_list, 4202 GNUNET_memcpy (peer_list,
4144 trail_peer_list, 4203 trail_peer_list,
4145 trail_length * sizeof (struct GNUNET_PeerIdentity)); 4204 trail_length * sizeof (struct GNUNET_PeerIdentity));
@@ -4175,7 +4234,7 @@ handle_dht_p2p_trail_setup (void *cls,
4175 * @return #GNUNET_OK if @a trail_result is well-formed 4234 * @return #GNUNET_OK if @a trail_result is well-formed
4176 */ 4235 */
4177static int 4236static int
4178check_dht_p2p_trail_setup_result (void *cls, 4237check_dht_p2p_trail_setup_result (void *cls,
4179 const struct PeerTrailSetupResultMessage *trail_result) 4238 const struct PeerTrailSetupResultMessage *trail_result)
4180{ 4239{
4181 size_t msize; 4240 size_t msize;
@@ -4189,7 +4248,7 @@ check_dht_p2p_trail_setup_result (void *cls,
4189 } 4248 }
4190 return GNUNET_OK; 4249 return GNUNET_OK;
4191} 4250}
4192 4251
4193 4252
4194/** 4253/**
4195 * Core handle for p2p trail setup result messages. 4254 * Core handle for p2p trail setup result messages.
@@ -4198,7 +4257,7 @@ check_dht_p2p_trail_setup_result (void *cls,
4198 * @param trail_result the message 4257 * @param trail_result the message
4199 */ 4258 */
4200static void 4259static void
4201handle_dht_p2p_trail_setup_result (void *cls, 4260handle_dht_p2p_trail_setup_result (void *cls,
4202 const struct PeerTrailSetupResultMessage *trail_result) 4261 const struct PeerTrailSetupResultMessage *trail_result)
4203{ 4262{
4204 struct FriendInfo *friend = cls; 4263 struct FriendInfo *friend = cls;
@@ -4228,7 +4287,7 @@ handle_dht_p2p_trail_setup_result (void *cls,
4228 finger_identity = trail_result->finger_identity; 4287 finger_identity = trail_result->finger_identity;
4229 trail_id = trail_result->trail_id; 4288 trail_id = trail_result->trail_id;
4230 trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; 4289 trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1];
4231 ultimate_destination_finger_value 4290 ultimate_destination_finger_value
4232 = GNUNET_ntohll (trail_result->ultimate_destination_finger_value); 4291 = GNUNET_ntohll (trail_result->ultimate_destination_finger_value);
4233 4292
4234 /* Am I the one who initiated the query? */ 4293 /* Am I the one who initiated the query? */
@@ -4314,7 +4373,7 @@ handle_dht_p2p_trail_setup_result (void *cls,
4314 GDS_NEIGHBOURS_send_trail_setup_result (&querying_peer, 4373 GDS_NEIGHBOURS_send_trail_setup_result (&querying_peer,
4315 &finger_identity, 4374 &finger_identity,
4316 target_friend, 4375 target_friend,
4317 trail_length, 4376 trail_length,
4318 trail_peer_list, 4377 trail_peer_list,
4319 is_predecessor, 4378 is_predecessor,
4320 ultimate_destination_finger_value, 4379 ultimate_destination_finger_value,
@@ -4569,7 +4628,7 @@ get_trail_src_to_curr_pred (struct GNUNET_PeerIdentity source_peer,
4569 *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i; 4628 *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i;
4570 trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length, 4629 trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length,
4571 struct GNUNET_PeerIdentity); 4630 struct GNUNET_PeerIdentity);
4572 4631
4573 4632
4574 for (j = 0; j < *trail_src_to_curr_pred_length; i++,j++) 4633 for (j = 0; j < *trail_src_to_curr_pred_length; i++,j++)
4575 trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i]; 4634 trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i];
@@ -4821,7 +4880,7 @@ handle_dht_p2p_verify_successor (void *cls,
4821 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor.finger_identity, 4880 if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&current_predecessor.finger_identity,
4822 &source_peer))) 4881 &source_peer)))
4823 { 4882 {
4824 trail_src_to_curr_pred 4883 trail_src_to_curr_pred
4825 = get_trail_src_to_curr_pred (source_peer, 4884 = get_trail_src_to_curr_pred (source_peer,
4826 trail, 4885 trail,
4827 trail_length, 4886 trail_length,
@@ -4832,7 +4891,7 @@ handle_dht_p2p_verify_successor (void *cls,
4832 trail_src_to_curr_pred_len = trail_length; 4891 trail_src_to_curr_pred_len = trail_length;
4833 trail_src_to_curr_pred = GNUNET_new_array (trail_src_to_curr_pred_len, 4892 trail_src_to_curr_pred = GNUNET_new_array (trail_src_to_curr_pred_len,
4834 struct GNUNET_PeerIdentity); 4893 struct GNUNET_PeerIdentity);
4835 4894
4836 for (unsigned int i = 0; i < trail_src_to_curr_pred_len; i++) 4895 for (unsigned int i = 0; i < trail_src_to_curr_pred_len; i++)
4837 { 4896 {
4838 trail_src_to_curr_pred[i] = trail[i]; 4897 trail_src_to_curr_pred[i] = trail[i];
@@ -5175,7 +5234,7 @@ check_dht_p2p_verify_successor_result (void *cls,
5175static void 5234static void
5176handle_dht_p2p_verify_successor_result (void *cls, 5235handle_dht_p2p_verify_successor_result (void *cls,
5177 const struct PeerVerifySuccessorResultMessage *vsrm) 5236 const struct PeerVerifySuccessorResultMessage *vsrm)
5178{ 5237{
5179 enum GDS_ROUTING_trail_direction trail_direction; 5238 enum GDS_ROUTING_trail_direction trail_direction;
5180 struct GNUNET_PeerIdentity querying_peer; 5239 struct GNUNET_PeerIdentity querying_peer;
5181 struct GNUNET_HashCode trail_id; 5240 struct GNUNET_HashCode trail_id;
@@ -5211,7 +5270,7 @@ handle_dht_p2p_verify_successor_result (void *cls,
5211 if (NULL != send_verify_successor_retry_task) 5270 if (NULL != send_verify_successor_retry_task)
5212 { 5271 {
5213 struct VerifySuccessorContext *ctx; 5272 struct VerifySuccessorContext *ctx;
5214 5273
5215 ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); 5274 ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task);
5216 GNUNET_free (ctx); 5275 GNUNET_free (ctx);
5217 send_verify_successor_retry_task = NULL; 5276 send_verify_successor_retry_task = NULL;
@@ -5277,7 +5336,7 @@ check_dht_p2p_notify_new_successor (void *cls,
5277 return GNUNET_OK; 5336 return GNUNET_OK;
5278} 5337}
5279 5338
5280 5339
5281/** 5340/**
5282 * Core handle for p2p notify new successor messages. 5341 * Core handle for p2p notify new successor messages.
5283 * 5342 *
@@ -5387,7 +5446,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls,
5387 struct GNUNET_HashCode trail_id; 5446 struct GNUNET_HashCode trail_id;
5388 struct FriendInfo *target_friend; 5447 struct FriendInfo *target_friend;
5389 const struct GNUNET_PeerIdentity *next_hop; 5448 const struct GNUNET_PeerIdentity *next_hop;
5390 5449
5391 GNUNET_STATISTICS_update (GDS_stats, 5450 GNUNET_STATISTICS_update (GDS_stats,
5392 gettext_noop ("# Bytes received from other peers"), 5451 gettext_noop ("# Bytes received from other peers"),
5393 ntohs (notify_confirmation->header.size), 5452 ntohs (notify_confirmation->header.size),
@@ -5431,7 +5490,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls,
5431 DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us + 5490 DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us +
5432 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 5491 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
5433 DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us); 5492 DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us);
5434 send_verify_successor_task 5493 send_verify_successor_task
5435 = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, 5494 = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time,
5436 &send_verify_successor_message, 5495 &send_verify_successor_message,
5437 NULL); 5496 NULL);
@@ -5476,7 +5535,7 @@ check_dht_p2p_trail_setup_rejection (void *cls,
5476 } 5535 }
5477 return GNUNET_OK; 5536 return GNUNET_OK;
5478} 5537}
5479 5538
5480 5539
5481/** 5540/**
5482 * Core handler for P2P trail rejection message 5541 * Core handler for P2P trail rejection message
@@ -5487,7 +5546,7 @@ check_dht_p2p_trail_setup_rejection (void *cls,
5487static void 5546static void
5488handle_dht_p2p_trail_setup_rejection (void *cls, 5547handle_dht_p2p_trail_setup_rejection (void *cls,
5489 const struct PeerTrailRejectionMessage *trail_rejection) 5548 const struct PeerTrailRejectionMessage *trail_rejection)
5490{ 5549{
5491 struct FriendInfo *friend = cls; 5550 struct FriendInfo *friend = cls;
5492 unsigned int trail_length; 5551 unsigned int trail_length;
5493 const struct GNUNET_PeerIdentity *trail_peer_list; 5552 const struct GNUNET_PeerIdentity *trail_peer_list;
@@ -5514,7 +5573,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls,
5514 congestion_timeout = trail_rejection->congestion_time; 5573 congestion_timeout = trail_rejection->congestion_time;
5515 source = trail_rejection->source_peer; 5574 source = trail_rejection->source_peer;
5516 trail_id = trail_rejection->trail_id; 5575 trail_id = trail_rejection->trail_id;
5517 ultimate_destination_finger_value 5576 ultimate_destination_finger_value
5518 = GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value); 5577 = GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value);
5519 /* First set the congestion time of the friend that sent you this message. */ 5578 /* First set the congestion time of the friend that sent you this message. */
5520 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 5579 target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
@@ -5525,7 +5584,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls,
5525 GNUNET_break(0); 5584 GNUNET_break(0);
5526 return; 5585 return;
5527 } 5586 }
5528 target_friend->congestion_timestamp 5587 target_friend->congestion_timestamp
5529 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), 5588 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
5530 congestion_timeout); 5589 congestion_timeout);
5531 5590
@@ -5549,7 +5608,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls,
5549 else 5608 else
5550 next_peer = trail[new_trail_length-1]; 5609 next_peer = trail[new_trail_length-1];
5551 5610
5552 target_friend 5611 target_friend
5553 = GNUNET_CONTAINER_multipeermap_get (friend_peermap, 5612 = GNUNET_CONTAINER_multipeermap_get (friend_peermap,
5554 &next_peer); 5613 &next_peer);
5555 if (NULL == target_friend) 5614 if (NULL == target_friend)
@@ -5640,7 +5699,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls,
5640 * @param trail_teardown the message 5699 * @param trail_teardown the message
5641 */ 5700 */
5642static void 5701static void
5643handle_dht_p2p_trail_teardown (void *cls, 5702handle_dht_p2p_trail_teardown (void *cls,
5644 const struct PeerTrailTearDownMessage *trail_teardown) 5703 const struct PeerTrailTearDownMessage *trail_teardown)
5645{ 5704{
5646 enum GDS_ROUTING_trail_direction trail_direction; 5705 enum GDS_ROUTING_trail_direction trail_direction;
@@ -5707,7 +5766,7 @@ handle_dht_p2p_trail_teardown (void *cls,
5707 * @return #GNUNET_OK if @a add_trail is well-formed 5766 * @return #GNUNET_OK if @a add_trail is well-formed
5708 */ 5767 */
5709static int 5768static int
5710check_dht_p2p_add_trail (void *cls, 5769check_dht_p2p_add_trail (void *cls,
5711 const struct PeerAddTrailMessage *add_trail) 5770 const struct PeerAddTrailMessage *add_trail)
5712{ 5771{
5713 size_t msize; 5772 size_t msize;
@@ -5730,9 +5789,9 @@ check_dht_p2p_add_trail (void *cls,
5730 * @param add_trail the message 5789 * @param add_trail the message
5731 */ 5790 */
5732static void 5791static void
5733handle_dht_p2p_add_trail (void *cls, 5792handle_dht_p2p_add_trail (void *cls,
5734 const struct PeerAddTrailMessage *add_trail) 5793 const struct PeerAddTrailMessage *add_trail)
5735{ 5794{
5736 struct FriendInfo *friend = cls; 5795 struct FriendInfo *friend = cls;
5737 const struct GNUNET_PeerIdentity *trail; 5796 const struct GNUNET_PeerIdentity *trail;
5738 struct GNUNET_HashCode trail_id; 5797 struct GNUNET_HashCode trail_id;
@@ -6183,7 +6242,7 @@ GDS_NEIGHBOURS_done (void)
6183 if (NULL != send_notify_new_successor_retry_task) 6242 if (NULL != send_notify_new_successor_retry_task)
6184 { 6243 {
6185 struct SendNotifyContext *notify_ctx; 6244 struct SendNotifyContext *notify_ctx;
6186 6245
6187 notify_ctx = GNUNET_SCHEDULER_cancel (send_notify_new_successor_retry_task); 6246 notify_ctx = GNUNET_SCHEDULER_cancel (send_notify_new_successor_retry_task);
6188 GNUNET_free (notify_ctx->successor_trail); 6247 GNUNET_free (notify_ctx->successor_trail);
6189 GNUNET_free (notify_ctx); 6248 GNUNET_free (notify_ctx);
@@ -6197,10 +6256,10 @@ GDS_NEIGHBOURS_done (void)
6197 * 6256 *
6198 * @return my identity 6257 * @return my identity
6199 */ 6258 */
6200struct GNUNET_PeerIdentity 6259struct GNUNET_PeerIdentity *
6201GDS_NEIGHBOURS_get_my_id (void) 6260GDS_NEIGHBOURS_get_id (void)
6202{ 6261{
6203 return my_identity; 6262 return &my_identity;
6204} 6263}
6205 6264
6206/* end of gnunet-service-xdht_neighbours.c */ 6265/* end of gnunet-service-xdht_neighbours.c */
diff --git a/src/dht/gnunet-service-xdht_neighbours.h b/src/dht/gnunet-service-xdht_neighbours.h
index 1df45031d..2fb118448 100644
--- a/src/dht/gnunet-service-xdht_neighbours.h
+++ b/src/dht/gnunet-service-xdht_neighbours.h
@@ -33,67 +33,6 @@
33 33
34 34
35/** 35/**
36 * Handle the put request from the client.
37 * @param key Key for the content
38 * @param block_type Type of the block
39 * @param options Routing options
40 * @param desired_replication_level Desired replication count
41 * @param expiration_time When does the content expire
42 * @param data Content to store
43 * @param data_size Size of content @a data in bytes
44 */
45void
46GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key,
47 enum GNUNET_BLOCK_Type block_type,
48 enum GNUNET_DHT_RouteOption options,
49 uint32_t desired_replication_level,
50 struct GNUNET_TIME_Absolute expiration_time,
51 const void *data, size_t data_size);
52
53/**
54 * Handle the get request from the client file. If I am destination do
55 * datacache put and return. Else find the target friend and forward message
56 * to it.
57 * @param key Key for the content
58 * @param block_type Type of the block
59 * @param options Routing options
60 * @param desired_replication_level Desired replication count
61 */
62void
63GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key,
64 enum GNUNET_BLOCK_Type block_type,
65 enum GNUNET_DHT_RouteOption options,
66 uint32_t desired_replication_level);
67
68/**
69 * Send the get result to requesting client.
70 * @param key Key of the requested data.
71 * @param type Block type
72 * @param target_peer Next peer to forward the message to.
73 * @param source_peer Peer which has the data for the key.
74 * @param put_path_length Number of peers in @a put_path
75 * @param put_path Path taken to put the data at its stored location.
76 * @param get_path_length Number of peers in @a get_path
77 * @param get_path Path taken to reach to the location of the key.
78 * @param expiration When will this result expire?
79 * @param data Payload to store
80 * @param data_size Size of the @a data
81 */
82void
83GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key,
84 enum GNUNET_BLOCK_Type type,
85 const struct GNUNET_PeerIdentity *target_peer,
86 const struct GNUNET_PeerIdentity *source_peer,
87 unsigned int put_path_length,
88 const struct GNUNET_PeerIdentity *put_path,
89 unsigned int get_path_length,
90 const struct GNUNET_PeerIdentity *get_path,
91 struct GNUNET_TIME_Absolute expiration,
92 const void *data,
93 size_t data_size);
94
95
96/**
97 * Construct a trail teardown message and forward it to target friend. 36 * Construct a trail teardown message and forward it to target friend.
98 * @param trail_id Unique identifier of the trail. 37 * @param trail_id Unique identifier of the trail.
99 * @param trail_direction Direction of trail. 38 * @param trail_direction Direction of trail.
@@ -105,29 +44,4 @@ GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_HashCode *trail_id,
105 const struct GNUNET_PeerIdentity *peer); 44 const struct GNUNET_PeerIdentity *peer);
106 45
107 46
108/**
109 * Initialize neighbours subsystem.
110 *
111 * @return #GNUNET_OK on success,
112 * #GNUNET_SYSERR on error
113 */
114int
115GDS_NEIGHBOURS_init (void);
116
117
118/**
119 * Shutdown neighbours subsystem.
120 */
121void
122GDS_NEIGHBOURS_done (void);
123
124
125/**
126 * Get my identity
127 *
128 * @return my identity
129 */
130struct GNUNET_PeerIdentity
131GDS_NEIGHBOURS_get_my_id (void);
132
133#endif 47#endif
diff --git a/src/dht/gnunet-service-xdht_nse.c b/src/dht/gnunet-service-xdht_nse.c
deleted file mode 100644
index b7d60013a..000000000
--- a/src/dht/gnunet-service-xdht_nse.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-xdht_nse.c
23 * @brief GNUnet DHT integration with NSE
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_nse_service.h"
28#include "gnunet-service-xdht.h"
29#include "gnunet-service-xdht_nse.h"
30
31/**
32 * log of the current network size estimate, used as the point where
33 * we switch between random and deterministic routing. Default
34 * value of 4.0 is used if NSE module is not available (i.e. not
35 * configured).
36 */
37static double log_of_network_size_estimate = 4.0;
38
39/**
40 * Network size estimation handle.
41 */
42static struct GNUNET_NSE_Handle *nse;
43
44
45/**
46 * Callback that is called when network size estimate is updated.
47 *
48 * @param cls closure
49 * @param timestamp time when the estimate was received from the server (or created by the server)
50 * @param logestimate the log(Base 2) value of the current network size estimate
51 * @param std_dev standard deviation for the estimate
52 *
53 */
54static void
55update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp,
56 double logestimate, double std_dev)
57{
58 GNUNET_STATISTICS_update (GDS_stats,
59 gettext_noop ("# Network size estimates received"),
60 1, GNUNET_NO);
61 /* do not allow estimates < 0.5 */
62 log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate);
63}
64
65
66/**
67 * Return the log of the current network size estimate.
68 *
69 * @return log of NSE
70 */
71double
72GDS_NSE_get ()
73{
74 return log_of_network_size_estimate;
75}
76
77
78/**
79 * Initialize NSE subsystem.
80 */
81void
82GDS_NSE_init ()
83{
84 unsigned long long hops;
85
86 if ( (GNUNET_YES ==
87 GNUNET_CONFIGURATION_have_value (GDS_cfg,
88 "dht",
89 "FORCE_NSE")) &&
90 (GNUNET_OK ==
91 GNUNET_CONFIGURATION_get_value_number (GDS_cfg,
92 "dht",
93 "FORCE_NSE",
94 &hops)) )
95 {
96 log_of_network_size_estimate = (double) hops;
97 return;
98 }
99 nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL);
100}
101
102
103/**
104 * Shutdown NSE subsystem.
105 */
106void
107GDS_NSE_done ()
108{
109 if (NULL != nse)
110 {
111 GNUNET_NSE_disconnect (nse);
112 nse = NULL;
113 }
114}
115
116/* end of gnunet-service-dht_nse.c */
diff --git a/src/dht/gnunet-service-xdht_nse.h b/src/dht/gnunet-service-xdht_nse.h
deleted file mode 100644
index 358c0c4bd..000000000
--- a/src/dht/gnunet-service-xdht_nse.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file dht/gnunet-service-xdht_nse.h
23 * @brief GNUnet DHT integration with NSE
24 * @author Christian Grothoff
25 */
26#ifndef GNUNET_SERVICE_XDHT_NSE_H
27#define GNUNET_SERVICE_XDHT_NSE_H
28
29
30/**
31 * Return the log of the current network size estimate.
32 *
33 * @return log of NSE
34 */
35double
36GDS_NSE_get (void);
37
38
39/**
40 * Initialize NSE subsystem.
41 */
42void
43GDS_NSE_init (void);
44
45
46/**
47 * Shutdown NSE subsystem.
48 */
49void
50GDS_NSE_done (void);
51
52#endif
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c
index 12b85eb7f..ec7361579 100644
--- a/src/dht/gnunet-service-xdht_routing.c
+++ b/src/dht/gnunet-service-xdht_routing.c
@@ -24,9 +24,10 @@
24 * @author Supriti Singh 24 * @author Supriti Singh
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet-service-dht_neighbours.h"
27#include "gnunet-service-xdht_neighbours.h" 28#include "gnunet-service-xdht_neighbours.h"
28#include "gnunet-service-xdht_routing.h" 29#include "gnunet-service-xdht_routing.h"
29#include "gnunet-service-xdht.h" 30#include "gnunet-service-dht.h"
30 31
31 32
32/** 33/**
@@ -207,7 +208,7 @@ remove_matching_trails (void *cls,
207 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop, 208 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop,
208 disconnected_peer)) 209 disconnected_peer))
209 { 210 {
210 my_identity = GDS_NEIGHBOURS_get_my_id (); 211 my_identity = *GDS_NEIGHBOURS_get_id ();
211 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, 212 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
212 &remove_trail->prev_hop)) 213 &remove_trail->prev_hop))
213 { 214 {
@@ -222,7 +223,7 @@ remove_matching_trails (void *cls,
222 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop, 223 if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop,
223 disconnected_peer)) 224 disconnected_peer))
224 { 225 {
225 my_identity = GDS_NEIGHBOURS_get_my_id (); 226 my_identity = *GDS_NEIGHBOURS_get_id ();
226 227
227 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, 228 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity,
228 &remove_trail->next_hop)) 229 &remove_trail->next_hop))
@@ -255,7 +256,7 @@ GDS_ROUTING_test_print (void)
255 struct GNUNET_HashCode key_ret; 256 struct GNUNET_HashCode key_ret;
256 int i; 257 int i;
257 258
258 struct GNUNET_PeerIdentity my_identity = GDS_NEIGHBOURS_get_my_id(); 259 struct GNUNET_PeerIdentity my_identity = *GDS_NEIGHBOURS_get_id();
259 print_peer = my_identity; 260 print_peer = my_identity;
260 FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer)); 261 FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer));
261 iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table); 262 iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table);