aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dht/dht.h8
-rw-r--r--src/dht/dht_api.c511
-rw-r--r--src/dht/gnunet-service-dht.c433
-rw-r--r--src/dht/test_dht_api.c128
4 files changed, 695 insertions, 385 deletions
diff --git a/src/dht/dht.h b/src/dht/dht.h
index 68591a97e..6c2f4cbd8 100644
--- a/src/dht/dht.h
+++ b/src/dht/dht.h
@@ -30,7 +30,8 @@
30#define DEBUG_DHT GNUNET_NO 30#define DEBUG_DHT GNUNET_NO
31 31
32typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls, 32typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls,
33 struct GNUNET_MessageHeader *msg); 33 struct GNUNET_MessageHeader
34 * msg);
34 35
35/** 36/**
36 * Generic DHT message, wrapper for other message types 37 * Generic DHT message, wrapper for other message types
@@ -159,6 +160,11 @@ struct GNUNET_DHT_GetResultMessage
159 GNUNET_HashCode key; 160 GNUNET_HashCode key;
160 161
161 /** 162 /**
163 * When does this entry expire?
164 */
165 struct GNUNET_TIME_Absolute expiration;
166
167 /**
162 * The size of the data, appended to the end of this message. 168 * The size of the data, appended to the end of this message.
163 */ 169 */
164 size_t data_size; 170 size_t data_size;
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index f935d69d3..d4fc9296b 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -39,7 +39,7 @@
39#include "gnunet_dht_service.h" 39#include "gnunet_dht_service.h"
40#include "dht.h" 40#include "dht.h"
41 41
42#define DEBUG_DHT_API GNUNET_NO 42#define DEBUG_DHT_API GNUNET_YES
43 43
44#define DEFAULT_DHT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 44#define DEFAULT_DHT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
45 45
@@ -193,12 +193,12 @@ struct GNUNET_DHT_FindPeerHandle
193 /** 193 /**
194 * Handle to the actual route operation for the request 194 * Handle to the actual route operation for the request
195 */ 195 */
196 struct GNUNET_DHT_RouteHandle *route_handle; 196 struct GNUNET_DHT_RouteHandle *route_handle;
197 197
198 /** 198 /**
199 * The context of the get request 199 * The context of the get request
200 */ 200 */
201 struct GNUNET_DHT_FindPeerContext find_peer_context; 201 struct GNUNET_DHT_FindPeerContext find_peer_context;
202}; 202};
203 203
204 204
@@ -257,23 +257,24 @@ struct GNUNET_DHT_Handle
257static struct GNUNET_TIME_Relative default_request_timeout; 257static struct GNUNET_TIME_Relative default_request_timeout;
258 258
259/* Forward declaration */ 259/* Forward declaration */
260static void process_pending_message(struct GNUNET_DHT_Handle *handle); 260static void process_pending_message (struct GNUNET_DHT_Handle *handle);
261 261
262static GNUNET_HashCode * hash_from_uid(uint64_t uid) 262static GNUNET_HashCode *
263hash_from_uid (uint64_t uid)
263{ 264{
264 int count; 265 int count;
265 int remaining; 266 int remaining;
266 GNUNET_HashCode *hash; 267 GNUNET_HashCode *hash;
267 hash = GNUNET_malloc(sizeof(GNUNET_HashCode)); 268 hash = GNUNET_malloc (sizeof (GNUNET_HashCode));
268 count = 0; 269 count = 0;
269 270
270 while (count < sizeof(GNUNET_HashCode)) 271 while (count < sizeof (GNUNET_HashCode))
271 { 272 {
272 remaining = sizeof(GNUNET_HashCode) - count; 273 remaining = sizeof (GNUNET_HashCode) - count;
273 if (remaining > sizeof(uid)) 274 if (remaining > sizeof (uid))
274 remaining = sizeof(uid); 275 remaining = sizeof (uid);
275 276
276 memcpy(hash, &uid, remaining); 277 memcpy (hash, &uid, remaining);
277 count += remaining; 278 count += remaining;
278 } 279 }
279 280
@@ -285,8 +286,8 @@ static GNUNET_HashCode * hash_from_uid(uint64_t uid)
285 * a demultiplexer which handles numerous message types 286 * a demultiplexer which handles numerous message types
286 * 287 *
287 */ 288 */
288void service_message_handler (void *cls, 289void
289 const struct GNUNET_MessageHeader *msg) 290service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
290{ 291{
291 struct GNUNET_DHT_Handle *handle = cls; 292 struct GNUNET_DHT_Handle *handle = cls;
292 struct GNUNET_DHT_Message *dht_msg; 293 struct GNUNET_DHT_Message *dht_msg;
@@ -300,73 +301,89 @@ void service_message_handler (void *cls,
300 * Should be a non unique acknowledgment, or unique result. */ 301 * Should be a non unique acknowledgment, or unique result. */
301 302
302 if (msg == NULL) 303 if (msg == NULL)
303 { 304 {
304#if DEBUG_DHT_API 305#if DEBUG_DHT_API
305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 306 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
306 "`%s': Received NULL from server, connection down?\n", "DHT API"); 307 "`%s': Received NULL from server, connection down?\n",
308 "DHT API");
307#endif 309#endif
308 return; 310 return;
309 } 311 }
310 312
311 if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT) 313 switch (ntohs (msg->type))
312 { 314 {
313 dht_msg = (struct GNUNET_DHT_Message *)msg; 315 case GNUNET_MESSAGE_TYPE_DHT:
314 uid = GNUNET_ntohll(dht_msg->unique_id); 316 {
317 dht_msg = (struct GNUNET_DHT_Message *) msg;
318 uid = GNUNET_ntohll (dht_msg->unique_id);
315#if DEBUG_DHT_API 319#if DEBUG_DHT_API
316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 320 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
317 "`%s': Received response to message (uid %llu)\n", "DHT API", uid); 321 "`%s': Received response to message (uid %llu)\n",
322 "DHT API", uid);
318#endif 323#endif
319 if (ntohs(dht_msg->unique)) 324 if (ntohs (dht_msg->unique))
320 {
321 uid_hash = hash_from_uid(ntohl(dht_msg->unique_id));
322 route_handle = GNUNET_CONTAINER_multihashmap_get(handle->outstanding_requests, uid_hash);
323 GNUNET_free(uid_hash);
324 if (route_handle == NULL) /* We have no recollection of this request */
325 { 325 {
326 uid_hash = hash_from_uid (uid);
327 route_handle =
328 GNUNET_CONTAINER_multihashmap_get (handle->outstanding_requests,
329 uid_hash);
330 GNUNET_free (uid_hash);
331 if (route_handle == NULL) /* We have no recollection of this request */
332 {
326#if DEBUG_DHT_API 333#if DEBUG_DHT_API
327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 334 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
328 "`%s': Received response to message (uid %llu), but have no recollection of it!\n", "DHT API", ntohl(dht_msg->unique_id)); 335 "`%s': Received response to message (uid %llu), but have no recollection of it!\n",
336 "DHT API", uid);
329#endif 337#endif
338 }
339 else
340 {
341 enc_size =
342 ntohs (dht_msg->header.size) -
343 sizeof (struct GNUNET_DHT_Message);
344 GNUNET_assert (enc_size > 0);
345 enc_msg = (struct GNUNET_MessageHeader *) &dht_msg[1];
346 route_handle->iter (route_handle->iter_cls, enc_msg);
347
348 }
330 } 349 }
331 else 350 break;
332 {
333 enc_size = ntohs(dht_msg->header.size) - sizeof(struct GNUNET_DHT_Message);
334 GNUNET_assert(enc_size > 0);
335 enc_msg = (struct GNUNET_MessageHeader *)&dht_msg[1];
336 route_handle->iter(route_handle->iter_cls, enc_msg);
337 }
338 } 351 }
339 } 352 case GNUNET_MESSAGE_TYPE_DHT_STOP:
340 else if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DHT_STOP)
341 {
342 stop_msg = (struct GNUNET_DHT_StopMessage *)msg;
343 uid = GNUNET_ntohll(stop_msg->unique_id);
344#if DEBUG_DHT_API
345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
346 "`%s': Received response to message (uid %llu), current uid %llu\n", "DHT API", uid, handle->current->unique_id);
347#endif
348 if (handle->current->unique_id == uid)
349 { 353 {
354 stop_msg = (struct GNUNET_DHT_StopMessage *) msg;
355 uid = GNUNET_ntohll (stop_msg->unique_id);
350#if DEBUG_DHT_API 356#if DEBUG_DHT_API
351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 357 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
352 "`%s': Have pending confirmation for this message!\n", "DHT API", uid); 358 "`%s': Received response to message (uid %llu), current uid %llu\n",
359 "DHT API", uid, handle->current->unique_id);
353#endif 360#endif
354 if (handle->current->cont != NULL) 361 if (handle->current->unique_id == uid)
355 GNUNET_SCHEDULER_add_continuation(handle->sched, handle->current->cont, handle->current->cont_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); 362 {
356
357 GNUNET_free(handle->current->msg);
358 GNUNET_free(handle->current);
359 handle->current = NULL;
360 }
361 }
362 else
363 {
364#if DEBUG_DHT_API 363#if DEBUG_DHT_API
365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 364 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
366 "`%s': Received unknown message type %d\n", "DHT API", ntohs(msg->type)); 365 "`%s': Have pending confirmation for this message!\n",
366 "DHT API", uid);
367#endif 367#endif
368 } 368 if (handle->current->cont != NULL)
369 369 GNUNET_SCHEDULER_add_continuation (handle->sched,
370 handle->current->cont,
371 handle->current->cont_cls,
372 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
373
374 GNUNET_free (handle->current->msg);
375 GNUNET_free (handle->current);
376 handle->current = NULL;
377 }
378 break;
379 }
380 default:
381 {
382 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
383 "`%s': Received unknown message type %d\n", "DHT API",
384 ntohs (msg->type));
385 }
386 }
370 GNUNET_CLIENT_receive (handle->client, 387 GNUNET_CLIENT_receive (handle->client,
371 &service_message_handler, 388 &service_message_handler,
372 handle, GNUNET_TIME_UNIT_FOREVER_REL); 389 handle, GNUNET_TIME_UNIT_FOREVER_REL);
@@ -391,9 +408,10 @@ GNUNET_DHT_connect (struct GNUNET_SCHEDULER_Handle *sched,
391{ 408{
392 struct GNUNET_DHT_Handle *handle; 409 struct GNUNET_DHT_Handle *handle;
393 410
394 handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_Handle)); 411 handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_Handle));
395 412
396 default_request_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5); 413 default_request_timeout =
414 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5);
397 handle->cfg = cfg; 415 handle->cfg = cfg;
398 handle->sched = sched; 416 handle->sched = sched;
399 417
@@ -401,12 +419,13 @@ GNUNET_DHT_connect (struct GNUNET_SCHEDULER_Handle *sched,
401 handle->do_destroy = GNUNET_NO; 419 handle->do_destroy = GNUNET_NO;
402 handle->th = NULL; 420 handle->th = NULL;
403 421
404 handle->client = GNUNET_CLIENT_connect(sched, "dht", cfg); 422 handle->client = GNUNET_CLIENT_connect (sched, "dht", cfg);
405 handle->outstanding_requests = GNUNET_CONTAINER_multihashmap_create(ht_len); 423 handle->outstanding_requests =
424 GNUNET_CONTAINER_multihashmap_create (ht_len);
406 425
407 if (handle->client == NULL) 426 if (handle->client == NULL)
408 { 427 {
409 GNUNET_free(handle); 428 GNUNET_free (handle);
410 return NULL; 429 return NULL;
411 } 430 }
412#if DEBUG_DHT_API 431#if DEBUG_DHT_API
@@ -433,17 +452,17 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle)
433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
434 "`%s': Called GNUNET_DHT_disconnect\n", "DHT API"); 453 "`%s': Called GNUNET_DHT_disconnect\n", "DHT API");
435#endif 454#endif
436 GNUNET_assert(handle != NULL); 455 GNUNET_assert (handle != NULL);
437 456
438 if (handle->th != NULL) /* We have a live transmit request in the Aether */ 457 if (handle->th != NULL) /* We have a live transmit request in the Aether */
439 { 458 {
440 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); 459 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
441 handle->th = NULL; 460 handle->th = NULL;
442 } 461 }
443 if (handle->current != NULL) /* We are trying to send something now, clean it up */ 462 if (handle->current != NULL) /* We are trying to send something now, clean it up */
444 GNUNET_free(handle->current); 463 GNUNET_free (handle->current);
445 464
446 if (handle->client != NULL) /* Finally, disconnect from the service */ 465 if (handle->client != NULL) /* Finally, disconnect from the service */
447 { 466 {
448 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); 467 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
449 handle->client = NULL; 468 handle->client = NULL;
@@ -462,24 +481,27 @@ finish (struct GNUNET_DHT_Handle *handle, int code)
462 /* TODO: if code is not GNUNET_OK, do something! */ 481 /* TODO: if code is not GNUNET_OK, do something! */
463 struct PendingMessage *pos = handle->current; 482 struct PendingMessage *pos = handle->current;
464#if DEBUG_DHT_API 483#if DEBUG_DHT_API
465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s': Finish called!\n", "DHT API");
466 "`%s': Finish called!\n", "DHT API");
467#endif 485#endif
468 GNUNET_assert(pos != NULL); 486 GNUNET_assert (pos != NULL);
469 487
470 if (pos->is_unique) 488 if (pos->is_unique)
471 { 489 {
472 if (pos->cont != NULL) 490 if (pos->cont != NULL)
473 { 491 {
474 if (code == GNUNET_SYSERR) 492 if (code == GNUNET_SYSERR)
475 GNUNET_SCHEDULER_add_continuation(handle->sched, pos->cont, pos->cont_cls, GNUNET_SCHEDULER_REASON_TIMEOUT); 493 GNUNET_SCHEDULER_add_continuation (handle->sched, pos->cont,
476 else 494 pos->cont_cls,
477 GNUNET_SCHEDULER_add_continuation(handle->sched, pos->cont, pos->cont_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); 495 GNUNET_SCHEDULER_REASON_TIMEOUT);
478 } 496 else
479 497 GNUNET_SCHEDULER_add_continuation (handle->sched, pos->cont,
480 GNUNET_free(pos->msg); 498 pos->cont_cls,
499 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
500 }
501
502 GNUNET_free (pos->msg);
481 handle->current = NULL; 503 handle->current = NULL;
482 GNUNET_free(pos); 504 GNUNET_free (pos);
483 } 505 }
484 /* Otherwise we need to wait for a response to this message! */ 506 /* Otherwise we need to wait for a response to this message! */
485} 507}
@@ -494,8 +516,8 @@ transmit_pending (void *cls, size_t size, void *buf)
494 size_t tsize; 516 size_t tsize;
495 517
496#if DEBUG_DHT_API 518#if DEBUG_DHT_API
497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
498 "`%s': In transmit_pending\n", "DHT API"); 520 "`%s': In transmit_pending\n", "DHT API");
499#endif 521#endif
500 if (buf == NULL) 522 if (buf == NULL)
501 { 523 {
@@ -504,30 +526,30 @@ transmit_pending (void *cls, size_t size, void *buf)
504 "`%s': In transmit_pending buf is NULL\n", "DHT API"); 526 "`%s': In transmit_pending buf is NULL\n", "DHT API");
505#endif 527#endif
506 /* FIXME: free associated resources or summat */ 528 /* FIXME: free associated resources or summat */
507 finish(handle, GNUNET_SYSERR); 529 finish (handle, GNUNET_SYSERR);
508 return 0; 530 return 0;
509 } 531 }
510 532
511 handle->th = NULL; 533 handle->th = NULL;
512 534
513 if (handle->current != NULL) 535 if (handle->current != NULL)
514 {
515 tsize = ntohs(handle->current->msg->size);
516 if (size >= tsize)
517 { 536 {
537 tsize = ntohs (handle->current->msg->size);
538 if (size >= tsize)
539 {
518#if DEBUG_DHT_API 540#if DEBUG_DHT_API
519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
520 "`%s': Sending message size %d\n", "DHT API", tsize); 542 "`%s': Sending message size %d\n", "DHT API", tsize);
521#endif 543#endif
522 memcpy(buf, handle->current->msg, tsize); 544 memcpy (buf, handle->current->msg, tsize);
523 finish(handle, GNUNET_OK); 545 finish (handle, GNUNET_OK);
524 return tsize; 546 return tsize;
547 }
548 else
549 {
550 return 0;
551 }
525 } 552 }
526 else
527 {
528 return 0;
529 }
530 }
531 /* Have no pending request */ 553 /* Have no pending request */
532 return 0; 554 return 0;
533} 555}
@@ -557,7 +579,8 @@ try_connect (struct GNUNET_DHT_Handle *handle)
557/** 579/**
558 * Try to send messages from list of messages to send 580 * Try to send messages from list of messages to send
559 */ 581 */
560static void process_pending_message(struct GNUNET_DHT_Handle *handle) 582static void
583process_pending_message (struct GNUNET_DHT_Handle *handle)
561{ 584{
562 585
563 if (handle->current == NULL) 586 if (handle->current == NULL)
@@ -577,10 +600,13 @@ static void process_pending_message(struct GNUNET_DHT_Handle *handle)
577 600
578 if (NULL == 601 if (NULL ==
579 (handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, 602 (handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client,
580 ntohs(handle->current->msg->size), 603 ntohs (handle->
581 handle->current->timeout, 604 current->msg->
582 GNUNET_YES, 605 size),
583 &transmit_pending, handle))) 606 handle->current->
607 timeout, GNUNET_YES,
608 &transmit_pending,
609 handle)))
584 { 610 {
585#if DEBUG_DHT_API 611#if DEBUG_DHT_API
586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -590,7 +616,8 @@ static void process_pending_message(struct GNUNET_DHT_Handle *handle)
590 } 616 }
591#if DEBUG_DHT_API 617#if DEBUG_DHT_API
592 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
593 "`%s': Scheduled sending message of size %d to service\n", "DHT API", ntohs(handle->current->msg->size)); 619 "`%s': Scheduled sending message of size %d to service\n",
620 "DHT API", ntohs (handle->current->msg->size));
594#endif 621#endif
595} 622}
596 623
@@ -598,10 +625,28 @@ static void process_pending_message(struct GNUNET_DHT_Handle *handle)
598 * Iterator called on each result obtained from a generic route 625 * Iterator called on each result obtained from a generic route
599 * operation 626 * operation
600 */ 627 */
601void get_reply_iterator (void *cls, 628void
602 const struct GNUNET_MessageHeader *reply) 629get_reply_iterator (void *cls, const struct GNUNET_MessageHeader *reply)
603{ 630{
631 struct GNUNET_DHT_GetHandle *get_handle = cls;
632 struct GNUNET_DHT_GetResultMessage *result;
633 size_t data_size;
634 char *result_data;
604 635
636 if (ntohs (reply->type) != GNUNET_MESSAGE_TYPE_DHT_GET_RESULT)
637 return;
638
639 GNUNET_assert (ntohs (reply->size) >=
640 sizeof (struct GNUNET_DHT_GetResultMessage));
641 result = (struct GNUNET_DHT_GetResultMessage *) reply;
642 data_size = ntohs (result->data_size);
643 GNUNET_assert (ntohs (reply->size) ==
644 sizeof (struct GNUNET_DHT_GetResultMessage) + data_size);
645 result_data = (char *) &result[1]; /* Set data pointer to end of message */
646
647 get_handle->get_context.iter (get_handle->get_context.iter_cls,
648 result->expiration, &result->key,
649 ntohs (result->type), data_size, result_data);
605} 650}
606 651
607 652
@@ -609,10 +654,32 @@ void get_reply_iterator (void *cls,
609 * Iterator called on each result obtained from a generic route 654 * Iterator called on each result obtained from a generic route
610 * operation 655 * operation
611 */ 656 */
612void find_peer_reply_iterator (void *cls, 657void
613 const struct GNUNET_MessageHeader *reply) 658find_peer_reply_iterator (void *cls, const struct GNUNET_MessageHeader *reply)
614{ 659{
660 struct GNUNET_DHT_FindPeerHandle *find_peer_handle = cls;
661 struct GNUNET_DHT_FindPeerResultMessage *result;
662 size_t data_size;
663 struct GNUNET_MessageHeader *result_data;
615 664
665 if (ntohs (reply->type) != GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_RESULT)
666 return;
667
668 GNUNET_assert (ntohs (reply->size) >=
669 sizeof (struct GNUNET_DHT_FindPeerResultMessage));
670 result = (struct GNUNET_DHT_FindPeerResultMessage *) reply;
671 data_size = ntohs (result->data_size);
672 GNUNET_assert (ntohs (reply->size) ==
673 sizeof (struct GNUNET_DHT_GetResultMessage) + data_size);
674
675 if (data_size > 0)
676 result_data = (struct GNUNET_MessageHeader *) &result[1]; /* Set data pointer to end of message */
677 else
678 result_data = NULL;
679
680 find_peer_handle->find_peer_context.proc (find_peer_handle->
681 find_peer_context.proc_cls,
682 &result->peer, result_data);
616} 683}
617 684
618/** 685/**
@@ -639,15 +706,14 @@ void find_peer_reply_iterator (void *cls,
639 */ 706 */
640struct GNUNET_DHT_RouteHandle * 707struct GNUNET_DHT_RouteHandle *
641GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, 708GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
642 const GNUNET_HashCode *key, 709 const GNUNET_HashCode * key,
643 unsigned int desired_replication_level, 710 unsigned int desired_replication_level,
644 enum GNUNET_DHT_RouteOption options, 711 enum GNUNET_DHT_RouteOption options,
645 const struct GNUNET_MessageHeader *enc, 712 const struct GNUNET_MessageHeader *enc,
646 struct GNUNET_TIME_Relative timeout, 713 struct GNUNET_TIME_Relative timeout,
647 GNUNET_DHT_ReplyProcessor iter, 714 GNUNET_DHT_ReplyProcessor iter,
648 void *iter_cls, 715 void *iter_cls,
649 GNUNET_SCHEDULER_Task cont, 716 GNUNET_SCHEDULER_Task cont, void *cont_cls)
650 void *cont_cls)
651{ 717{
652 struct GNUNET_DHT_RouteHandle *route_handle; 718 struct GNUNET_DHT_RouteHandle *route_handle;
653 struct PendingMessage *pending; 719 struct PendingMessage *pending;
@@ -665,48 +731,52 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
665 uid_key = NULL; 731 uid_key = NULL;
666 732
667 do 733 do
668 { 734 {
669 GNUNET_free_non_null(uid_key); 735 GNUNET_free_non_null (uid_key);
670 uid = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, -1); 736 uid = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, -1);
671 uid_key = hash_from_uid(uid); 737 uid_key = hash_from_uid (uid);
672 } while (GNUNET_CONTAINER_multihashmap_contains(handle->outstanding_requests, uid_key) == GNUNET_YES); 738 }
739 while (GNUNET_CONTAINER_multihashmap_contains
740 (handle->outstanding_requests, uid_key) == GNUNET_YES);
673 741
674 if (is_unique) 742 if (is_unique)
675 { 743 {
676 route_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_RouteHandle)); 744 route_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_RouteHandle));
677 memcpy(&route_handle->key, key, sizeof(GNUNET_HashCode)); 745 memcpy (&route_handle->key, key, sizeof (GNUNET_HashCode));
678 route_handle->iter = iter; 746 route_handle->iter = iter;
679 route_handle->iter_cls = iter_cls; 747 route_handle->iter_cls = iter_cls;
680 route_handle->dht_handle = handle; 748 route_handle->dht_handle = handle;
681 route_handle->uid = uid; 749 route_handle->uid = uid;
682#if DEBUG_DHT_API 750#if DEBUG_DHT_API
683 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
684 "`%s': Unique ID is %llu\n", "DHT API", uid); 752 "`%s': Unique ID is %llu\n", "DHT API", uid);
685#endif 753#endif
686 /** 754 /**
687 * Store based on random identifier! 755 * Store based on random identifier!
688 */ 756 */
689 GNUNET_CONTAINER_multihashmap_put(handle->outstanding_requests, uid_key, route_handle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 757 GNUNET_CONTAINER_multihashmap_put (handle->outstanding_requests,
690 msize = sizeof(struct GNUNET_DHT_Message) + ntohs(enc->size); 758 uid_key, route_handle,
759 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
760 msize = sizeof (struct GNUNET_DHT_Message) + ntohs (enc->size);
691 761
692 } 762 }
693 else 763 else
694 { 764 {
695 msize = sizeof(struct GNUNET_DHT_Message) + ntohs(enc->size); 765 msize = sizeof (struct GNUNET_DHT_Message) + ntohs (enc->size);
696 } 766 }
697 767
698 GNUNET_free(uid_key); 768 GNUNET_free (uid_key);
699 message = GNUNET_malloc(msize); 769 message = GNUNET_malloc (msize);
700 message->header.size = htons(msize); 770 message->header.size = htons (msize);
701 message->header.type = htons(GNUNET_MESSAGE_TYPE_DHT); 771 message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT);
702 memcpy(&message->key, key, sizeof(GNUNET_HashCode)); 772 memcpy (&message->key, key, sizeof (GNUNET_HashCode));
703 message->options = htons(options); 773 message->options = htons (options);
704 message->desired_replication_level = htons(options); 774 message->desired_replication_level = htons (options);
705 message->unique = htons(is_unique); 775 message->unique = htons (is_unique);
706 message->unique_id = GNUNET_htonll(uid); 776 message->unique_id = GNUNET_htonll (uid);
707 memcpy(&message[1], enc, ntohs(enc->size)); 777 memcpy (&message[1], enc, ntohs (enc->size));
708 778
709 pending = GNUNET_malloc(sizeof(struct PendingMessage)); 779 pending = GNUNET_malloc (sizeof (struct PendingMessage));
710 pending->msg = &message->header; 780 pending->msg = &message->header;
711 pending->timeout = timeout; 781 pending->timeout = timeout;
712 pending->cont = cont; 782 pending->cont = cont;
@@ -714,17 +784,18 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
714 pending->is_unique = is_unique; 784 pending->is_unique = is_unique;
715 pending->unique_id = uid; 785 pending->unique_id = uid;
716 786
717 GNUNET_assert(handle->current == NULL); 787 GNUNET_assert (handle->current == NULL);
718 788
719 handle->current = pending; 789 handle->current = pending;
720 790
721 process_pending_message(handle); 791 process_pending_message (handle);
722 792
723 return route_handle; 793 return route_handle;
724} 794}
725 795
726void 796void
727GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls); 797GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle,
798 GNUNET_SCHEDULER_Task cont, void *cont_cls);
728 799
729/** 800/**
730 * Perform an asynchronous GET operation on the DHT identified. 801 * Perform an asynchronous GET operation on the DHT identified.
@@ -747,79 +818,86 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
747 const GNUNET_HashCode * key, 818 const GNUNET_HashCode * key,
748 GNUNET_DHT_GetIterator iter, 819 GNUNET_DHT_GetIterator iter,
749 void *iter_cls, 820 void *iter_cls,
750 GNUNET_SCHEDULER_Task cont, 821 GNUNET_SCHEDULER_Task cont, void *cont_cls)
751 void *cont_cls)
752{ 822{
753 struct GNUNET_DHT_GetHandle *get_handle; 823 struct GNUNET_DHT_GetHandle *get_handle;
754 struct GNUNET_DHT_GetMessage *get_msg; 824 struct GNUNET_DHT_GetMessage *get_msg;
755 825
756 if (handle->current != NULL) /* Can't send right now, we have a pending message... */ 826 if (handle->current != NULL) /* Can't send right now, we have a pending message... */
757 return NULL; 827 return NULL;
758 828
759 get_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetHandle)); 829 get_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_GetHandle));
760 get_handle->get_context.iter = iter; 830 get_handle->get_context.iter = iter;
761 get_handle->get_context.iter_cls = iter_cls; 831 get_handle->get_context.iter_cls = iter_cls;
762 832
763#if DEBUG_DHT_API 833#if DEBUG_DHT_API
764 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
765 "`%s': Inserting pending get request with key %s\n", "DHT API", GNUNET_h2s(key)); 835 "`%s': Inserting pending get request with key %s\n", "DHT API",
836 GNUNET_h2s (key));
766#endif 837#endif
767 838
768 get_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetMessage)); 839 get_msg = GNUNET_malloc (sizeof (struct GNUNET_DHT_GetMessage));
769 get_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_GET); 840 get_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET);
770 get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage)); 841 get_msg->header.size = htons (sizeof (struct GNUNET_DHT_GetMessage));
771 get_msg->type = htonl(type); 842 get_msg->type = htonl (type);
772 843
773 get_handle->route_handle = GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_handle, cont, cont_cls); 844 get_handle->route_handle =
845 GNUNET_DHT_route_start (handle, key, 0, 0, &get_msg->header, timeout,
846 &get_reply_iterator, get_handle, cont, cont_cls);
774 return get_handle; 847 return get_handle;
775} 848}
776 849
777 850
778void 851void
779GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) 852GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle,
853 GNUNET_SCHEDULER_Task cont, void *cont_cls)
780{ 854{
781 struct PendingMessage *pending; 855 struct PendingMessage *pending;
782 struct GNUNET_DHT_StopMessage *message; 856 struct GNUNET_DHT_StopMessage *message;
783 size_t msize; 857 size_t msize;
784 GNUNET_HashCode *uid_key; 858 GNUNET_HashCode *uid_key;
785 859
786 msize = sizeof(struct GNUNET_DHT_StopMessage); 860 msize = sizeof (struct GNUNET_DHT_StopMessage);
787 861
788 message = GNUNET_malloc(msize); 862 message = GNUNET_malloc (msize);
789 message->header.size = htons(msize); 863 message->header.size = htons (msize);
790 message->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_STOP); 864 message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_STOP);
791#if DEBUG_DHT_API 865#if DEBUG_DHT_API
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "`%s': Remove outstanding request for uid %llu\n", "DHT API", route_handle->uid); 867 "`%s': Remove outstanding request for uid %llu\n", "DHT API",
868 route_handle->uid);
794#endif 869#endif
795 message->unique_id = GNUNET_htonll(route_handle->uid); 870 message->unique_id = GNUNET_htonll (route_handle->uid);
796 871
797 GNUNET_assert(route_handle->dht_handle->current == NULL); 872 GNUNET_assert (route_handle->dht_handle->current == NULL);
798 873
799 pending = GNUNET_malloc(sizeof(struct PendingMessage)); 874 pending = GNUNET_malloc (sizeof (struct PendingMessage));
800 pending->msg = (struct GNUNET_MessageHeader *)message; 875 pending->msg = (struct GNUNET_MessageHeader *) message;
801 pending->timeout = DEFAULT_DHT_TIMEOUT; 876 pending->timeout = DEFAULT_DHT_TIMEOUT;
802 pending->cont = cont; 877 pending->cont = cont;
803 pending->cont_cls = cont_cls; 878 pending->cont_cls = cont_cls;
804 pending->is_unique = GNUNET_NO; 879 pending->is_unique = GNUNET_NO;
805 pending->unique_id = route_handle->uid; 880 pending->unique_id = route_handle->uid;
806 881
807 GNUNET_assert(route_handle->dht_handle->current == NULL); 882 GNUNET_assert (route_handle->dht_handle->current == NULL);
808 883
809 route_handle->dht_handle->current = pending; 884 route_handle->dht_handle->current = pending;
810 885
811 process_pending_message(route_handle->dht_handle); 886 process_pending_message (route_handle->dht_handle);
812 887
813 uid_key = hash_from_uid(route_handle->uid); 888 uid_key = hash_from_uid (route_handle->uid);
814 889
815 if (GNUNET_CONTAINER_multihashmap_remove(route_handle->dht_handle->outstanding_requests, uid_key, route_handle) != GNUNET_YES) 890 if (GNUNET_CONTAINER_multihashmap_remove
891 (route_handle->dht_handle->outstanding_requests, uid_key,
892 route_handle) != GNUNET_YES)
816 { 893 {
817#if DEBUG_DHT_API 894#if DEBUG_DHT_API
818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
819 "`%s': Remove outstanding request from hashmap failed for key %s, uid %llu\n", "DHT API", GNUNET_h2s(uid_key), route_handle->uid); 896 "`%s': Remove outstanding request from hashmap failed for key %s, uid %llu\n",
897 "DHT API", GNUNET_h2s (uid_key), route_handle->uid);
820#endif 898#endif
821 } 899 }
822 GNUNET_free(uid_key); 900 GNUNET_free (uid_key);
823 return; 901 return;
824} 902}
825 903
@@ -830,14 +908,17 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHED
830 * @param get_handle handle to the GET operation to stop 908 * @param get_handle handle to the GET operation to stop
831 */ 909 */
832void 910void
833GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) 911GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle,
912 GNUNET_SCHEDULER_Task cont, void *cont_cls)
834{ 913{
835#if DEBUG_DHT_API 914#if DEBUG_DHT_API
836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
837 "`%s': Removing pending get request with key %s, uid %llu\n", "DHT API", GNUNET_h2s(&get_handle->route_handle->key), get_handle->route_handle->uid); 916 "`%s': Removing pending get request with key %s, uid %llu\n",
917 "DHT API", GNUNET_h2s (&get_handle->route_handle->key),
918 get_handle->route_handle->uid);
838#endif 919#endif
839 GNUNET_DHT_route_stop(get_handle->route_handle, cont, cont_cls); 920 GNUNET_DHT_route_stop (get_handle->route_handle, cont, cont_cls);
840 GNUNET_free(get_handle); 921 GNUNET_free (get_handle);
841 922
842} 923}
843 924
@@ -860,47 +941,53 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle, GNUNET_SCHEDULER_T
860 */ 941 */
861struct GNUNET_DHT_FindPeerHandle * 942struct GNUNET_DHT_FindPeerHandle *
862GNUNET_DHT_find_peer_start (struct GNUNET_DHT_Handle *handle, 943GNUNET_DHT_find_peer_start (struct GNUNET_DHT_Handle *handle,
863 struct GNUNET_TIME_Relative timeout, 944 struct GNUNET_TIME_Relative timeout,
864 enum GNUNET_DHT_RouteOption options, 945 enum GNUNET_DHT_RouteOption options,
865 struct GNUNET_MessageHeader *message, 946 struct GNUNET_MessageHeader *message,
866 const GNUNET_HashCode * key, 947 const GNUNET_HashCode * key,
867 GNUNET_DHT_FindPeerProcessor proc, 948 GNUNET_DHT_FindPeerProcessor proc,
868 void *proc_cls, 949 void *proc_cls,
869 GNUNET_SCHEDULER_Task cont, 950 GNUNET_SCHEDULER_Task cont, void *cont_cls)
870 void *cont_cls)
871{ 951{
872 struct GNUNET_DHT_FindPeerHandle *find_peer_handle; 952 struct GNUNET_DHT_FindPeerHandle *find_peer_handle;
873 struct GNUNET_DHT_FindPeerMessage *find_peer_msg; 953 struct GNUNET_DHT_FindPeerMessage *find_peer_msg;
874 size_t msize; 954 size_t msize;
875 955
876 if (handle->current != NULL) /* Can't send right now, we have a pending message... */ 956 if (handle->current != NULL) /* Can't send right now, we have a pending message... */
877 return NULL; 957 return NULL;
878 958
879 if (message != NULL) 959 if (message != NULL)
880 msize = ntohs(message->size); 960 msize = ntohs (message->size);
881 else 961 else
882 msize = 0; 962 msize = 0;
883 963
884 find_peer_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerHandle)); 964 find_peer_handle =
965 GNUNET_malloc (sizeof (struct GNUNET_DHT_FindPeerHandle));
885 find_peer_handle->find_peer_context.proc = proc; 966 find_peer_handle->find_peer_context.proc = proc;
886 find_peer_handle->find_peer_context.proc_cls = proc_cls; 967 find_peer_handle->find_peer_context.proc_cls = proc_cls;
887 968
888#if DEBUG_DHT_API 969#if DEBUG_DHT_API
889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890 "`%s': Inserting pending `%s' request with key %s\n", "DHT API", "FIND PEER", GNUNET_h2s(key)); 971 "`%s': Inserting pending `%s' request with key %s\n", "DHT API",
972 "FIND PEER", GNUNET_h2s (key));
891#endif 973#endif
892 974
893 find_peer_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerMessage) + msize); 975 find_peer_msg =
894 find_peer_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_FIND_PEER); 976 GNUNET_malloc (sizeof (struct GNUNET_DHT_FindPeerMessage) + msize);
895 find_peer_msg->header.size = htons(sizeof(struct GNUNET_DHT_FindPeerMessage)); 977 find_peer_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_FIND_PEER);
978 find_peer_msg->header.size =
979 htons (sizeof (struct GNUNET_DHT_FindPeerMessage));
896 find_peer_msg->msg_len = msize; 980 find_peer_msg->msg_len = msize;
897 981
898 if (message != NULL) 982 if (message != NULL)
899 { 983 {
900 memcpy(&find_peer_msg[1], message, msize); 984 memcpy (&find_peer_msg[1], message, msize);
901 } 985 }
902 986
903 find_peer_handle->route_handle = GNUNET_DHT_route_start(handle, key, 0, options, &find_peer_msg->header, timeout, &find_peer_reply_iterator, find_peer_handle, cont, cont_cls); 987 find_peer_handle->route_handle =
988 GNUNET_DHT_route_start (handle, key, 0, options, &find_peer_msg->header,
989 timeout, &find_peer_reply_iterator,
990 find_peer_handle, cont, cont_cls);
904 return find_peer_handle; 991 return find_peer_handle;
905} 992}
906 993
@@ -910,14 +997,18 @@ GNUNET_DHT_find_peer_start (struct GNUNET_DHT_Handle *handle,
910 * @param find_peer_handle GET operation to stop. 997 * @param find_peer_handle GET operation to stop.
911 */ 998 */
912void 999void
913GNUNET_DHT_find_peer_stop (struct GNUNET_DHT_FindPeerHandle *find_peer_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) 1000GNUNET_DHT_find_peer_stop (struct GNUNET_DHT_FindPeerHandle *find_peer_handle,
1001 GNUNET_SCHEDULER_Task cont, void *cont_cls)
914{ 1002{
915#if DEBUG_DHT_API 1003#if DEBUG_DHT_API
916 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1004 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
917 "`%s': Removing pending `%s' request with key %s, uid %llu\n", "DHT API", "FIND PEER", GNUNET_h2s(&find_peer_handle->route_handle->key), find_peer_handle->route_handle->uid); 1005 "`%s': Removing pending `%s' request with key %s, uid %llu\n",
1006 "DHT API", "FIND PEER",
1007 GNUNET_h2s (&find_peer_handle->route_handle->key),
1008 find_peer_handle->route_handle->uid);
918#endif 1009#endif
919 GNUNET_DHT_route_stop(find_peer_handle->route_handle, cont, cont_cls); 1010 GNUNET_DHT_route_stop (find_peer_handle->route_handle, cont, cont_cls);
920 GNUNET_free(find_peer_handle); 1011 GNUNET_free (find_peer_handle);
921 1012
922} 1013}
923 1014
@@ -946,33 +1037,35 @@ GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
946 const char *data, 1037 const char *data,
947 struct GNUNET_TIME_Absolute exp, 1038 struct GNUNET_TIME_Absolute exp,
948 struct GNUNET_TIME_Relative timeout, 1039 struct GNUNET_TIME_Relative timeout,
949 GNUNET_SCHEDULER_Task cont, 1040 GNUNET_SCHEDULER_Task cont, void *cont_cls)
950 void *cont_cls)
951{ 1041{
952 struct GNUNET_DHT_PutMessage *put_msg; 1042 struct GNUNET_DHT_PutMessage *put_msg;
953 size_t msize; 1043 size_t msize;
954 1044
955 if (handle->current != NULL) 1045 if (handle->current != NULL)
956 { 1046 {
957 GNUNET_SCHEDULER_add_continuation(handle->sched, cont, cont_cls, GNUNET_SCHEDULER_REASON_TIMEOUT); 1047 GNUNET_SCHEDULER_add_continuation (handle->sched, cont, cont_cls,
1048 GNUNET_SCHEDULER_REASON_TIMEOUT);
958 return; 1049 return;
959 } 1050 }
960 1051
961#if DEBUG_DHT_API 1052#if DEBUG_DHT_API
962 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1053 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
963 "`%s': Inserting pending put request with key %s\n", "DHT API", GNUNET_h2s(key)); 1054 "`%s': Inserting pending put request with key %s\n", "DHT API",
1055 GNUNET_h2s (key));
964#endif 1056#endif
965 1057
966 msize = sizeof(struct GNUNET_DHT_PutMessage) + size; 1058 msize = sizeof (struct GNUNET_DHT_PutMessage) + size;
967 put_msg = GNUNET_malloc(msize); 1059 put_msg = GNUNET_malloc (msize);
968 put_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_PUT); 1060 put_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_PUT);
969 put_msg->header.size = htons(msize); 1061 put_msg->header.size = htons (msize);
970 put_msg->type = htonl(type); 1062 put_msg->type = htonl (type);
971 put_msg->data_size = htons(size); 1063 put_msg->data_size = htons (size);
972 put_msg->expiration = exp; 1064 put_msg->expiration = exp;
973 memcpy(&put_msg[1], data, size); 1065 memcpy (&put_msg[1], data, size);
974 1066
975 GNUNET_DHT_route_start(handle, key, 0, 0, &put_msg->header, timeout, NULL, NULL, cont, cont_cls); 1067 GNUNET_DHT_route_start (handle, key, 0, 0, &put_msg->header, timeout, NULL,
1068 NULL, cont, cont_cls);
976 1069
977 GNUNET_free(put_msg); 1070 GNUNET_free (put_msg);
978} 1071}
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index c6ddb0ab9..f03cb379b 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -40,7 +40,7 @@
40/** 40/**
41 * Handle to the datacache service (for inserting/retrieving data) 41 * Handle to the datacache service (for inserting/retrieving data)
42 */ 42 */
43 struct GNUNET_DATACACHE_Handle *datacache; 43struct GNUNET_DATACACHE_Handle *datacache;
44 44
45/** 45/**
46 * The main scheduler to use for the DHT service 46 * The main scheduler to use for the DHT service
@@ -72,28 +72,60 @@ static struct GNUNET_PeerIdentity my_identity;
72 */ 72 */
73static GNUNET_SCHEDULER_TaskIdentifier cleanup_task; 73static GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
74 74
75struct ClientList 75/**
76 * Context for handling results from a get request.
77 */
78struct DatacacheGetContext
76{ 79{
77 /** 80 /**
78 * This is a linked list 81 * The client to send the result to.
82 */
83 struct GNUNET_SERVER_Client *client;
84
85 /**
86 * The unique id of this request
79 */ 87 */
80 struct ClientList *next; 88 unsigned long long unique_id;
89};
90
81 91
92struct DHT_MessageContext
93{
82 /** 94 /**
83 * The client in question 95 * The client this request was received from.
84 */ 96 */
85 struct GNUNET_SERVER_Client *client; 97 struct GNUNET_SERVER_Client *client;
98
99 /**
100 * The key this request was about
101 */
102 GNUNET_HashCode *key;
103
104 /**
105 * The unique identifier of this request
106 */
107 unsigned long long unique_id;
108
109 /**
110 * Desired replication level
111 */
112 size_t replication;
113
114 /**
115 * Any message options for this request
116 */
117 size_t msg_options;
86}; 118};
87 119
88/** 120/**
89 * Server handler for handling locally received dht requests 121 * Server handler for handling locally received dht requests
90 */ 122 */
91static void 123static void
92handle_dht_start_message(void *cls, struct GNUNET_SERVER_Client * client, 124handle_dht_start_message (void *cls, struct GNUNET_SERVER_Client *client,
93 const struct GNUNET_MessageHeader *message); 125 const struct GNUNET_MessageHeader *message);
94 126
95static void 127static void
96handle_dht_stop_message(void *cls, struct GNUNET_SERVER_Client * client, 128handle_dht_stop_message (void *cls, struct GNUNET_SERVER_Client *client,
97 const struct GNUNET_MessageHeader *message); 129 const struct GNUNET_MessageHeader *message);
98 130
99static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { 131static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
@@ -107,28 +139,29 @@ static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
107 * Core handler for p2p dht get requests. 139 * Core handler for p2p dht get requests.
108 */ 140 */
109static int handle_dht_p2p_get (void *cls, 141static int handle_dht_p2p_get (void *cls,
110 const struct GNUNET_PeerIdentity * peer, 142 const struct GNUNET_PeerIdentity *peer,
111 const struct GNUNET_MessageHeader * message, 143 const struct GNUNET_MessageHeader *message,
112 struct GNUNET_TIME_Relative latency, 144 struct GNUNET_TIME_Relative latency,
113 uint32_t distance); 145 uint32_t distance);
114 146
115/** 147/**
116 * Core handler for p2p dht put requests. 148 * Core handler for p2p dht put requests.
117 */ 149 */
118static int handle_dht_p2p_put (void *cls, 150static int handle_dht_p2p_put (void *cls,
119 const struct GNUNET_PeerIdentity * peer, 151 const struct GNUNET_PeerIdentity *peer,
120 const struct GNUNET_MessageHeader * message, 152 const struct GNUNET_MessageHeader *message,
121 struct GNUNET_TIME_Relative latency, 153 struct GNUNET_TIME_Relative latency,
122 uint32_t distance); 154 uint32_t distance);
123 155
124/** 156/**
125 * Core handler for p2p dht find peer requests. 157 * Core handler for p2p dht find peer requests.
126 */ 158 */
127static int handle_dht_p2p_find_peer (void *cls, 159static int handle_dht_p2p_find_peer (void *cls,
128 const struct GNUNET_PeerIdentity * peer, 160 const struct GNUNET_PeerIdentity *peer,
129 const struct GNUNET_MessageHeader * message, 161 const struct GNUNET_MessageHeader
130 struct GNUNET_TIME_Relative latency, 162 *message,
131 uint32_t distance); 163 struct GNUNET_TIME_Relative latency,
164 uint32_t distance);
132 165
133static struct GNUNET_CORE_MessageHandler core_handlers[] = { 166static struct GNUNET_CORE_MessageHandler core_handlers[] = {
134 {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_GET, 0}, 167 {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_GET, 0},
@@ -138,25 +171,131 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = {
138}; 171};
139 172
140 173
174static size_t
175send_reply (void *cls, size_t size, void *buf)
176{
177 struct GNUNET_DHT_Message *reply = cls;
178
179 if (buf == NULL) /* Message timed out, that's crappy... */
180 {
181 GNUNET_free (reply);
182 return 0;
183 }
184
185 if (size >= ntohs (reply->header.size))
186 {
187 memcpy (buf, reply, ntohs (reply->header.size));
188 return ntohs (reply->header.size);
189 }
190 else
191 return 0;
192}
193
194
195static void
196send_reply_to_client (struct GNUNET_SERVER_Client *client,
197 struct GNUNET_MessageHeader *message,
198 unsigned long long uid)
199{
200 struct GNUNET_DHT_Message *reply;
201 size_t msize;
202 size_t tsize;
203#if DEBUG_DHT
204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
205 "`%s': Sending reply to client.\n", "DHT");
206#endif
207 msize = ntohs (message->size);
208 tsize = sizeof (struct GNUNET_DHT_Message) + msize;
209 reply = GNUNET_malloc (tsize);
210 reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT);
211 reply->header.size = htons (tsize);
212 if (uid != 0)
213 reply->unique = htons (GNUNET_YES);
214 reply->unique_id = GNUNET_htonll (uid);
215 memcpy (&reply[1], message, msize);
216
217 GNUNET_SERVER_notify_transmit_ready (client,
218 tsize,
219 GNUNET_TIME_relative_multiply
220 (GNUNET_TIME_UNIT_SECONDS, 5),
221 &send_reply, reply);
222
223}
224
225
226/**
227 * Iterator for local get request results, return
228 * GNUNET_OK to continue iteration, anything else
229 * to stop iteration.
230 */
231static int
232datacache_get_iterator (void *cls,
233 struct GNUNET_TIME_Absolute exp,
234 const GNUNET_HashCode * key,
235 uint32_t size, const char *data, uint32_t type)
236{
237 struct DatacacheGetContext *datacache_get_ctx = cls;
238 struct GNUNET_DHT_GetResultMessage *get_result;
239
240 get_result =
241 GNUNET_malloc (sizeof (struct GNUNET_DHT_GetResultMessage) + size);
242 get_result->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET_RESULT);
243 get_result->header.size =
244 htons (sizeof (struct GNUNET_DHT_GetResultMessage) + size);
245 get_result->data_size = htons (size);
246 get_result->expiration = exp;
247 memcpy (&get_result->key, key, sizeof (GNUNET_HashCode));
248 get_result->type = htons (type);
249 memcpy (&get_result[1], data, size);
250
251 send_reply_to_client (datacache_get_ctx->client, &get_result->header,
252 datacache_get_ctx->unique_id);
253
254 GNUNET_free (get_result);
255 return GNUNET_OK;
256}
141 257
142/** 258/**
143 * Server handler for initiating local dht get requests 259 * Server handler for initiating local dht get requests
144 */ 260 */
145static void handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg, GNUNET_HashCode *key) 261static void
262handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg,
263 struct DHT_MessageContext *message_context)
146{ 264{
147#if DEBUG_DHT 265#if DEBUG_DHT
148 GNUNET_HashCode get_key; 266 GNUNET_HashCode get_key;
149#endif 267#endif
150 size_t get_type; 268 size_t get_type;
269 unsigned int results;
270 struct DatacacheGetContext *datacache_get_context;
151 271
152 GNUNET_assert(ntohs(get_msg->header.size) >= sizeof(struct GNUNET_DHT_GetMessage)); 272 GNUNET_assert (ntohs (get_msg->header.size) >=
153 get_type = ntohs(get_msg->type); 273 sizeof (struct GNUNET_DHT_GetMessage));
274 get_type = ntohs (get_msg->type);
154 275
155#if DEBUG_DHT 276#if DEBUG_DHT
156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 277 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
157 "`%s': Received `%s' request from client, message type %d, key %s\n", "DHT", "GET", get_type, GNUNET_h2s(&get_key)); 278 "`%s': Received `%s' request from client, message type %d, key %s, uid %llu\n",
279 "DHT", "GET", get_type, GNUNET_h2s (&get_key),
280 message_context->unique_id);
158#endif 281#endif
159 282
283 datacache_get_context = GNUNET_malloc (sizeof (struct DatacacheGetContext));
284 datacache_get_context->client = message_context->client;
285 datacache_get_context->unique_id = message_context->unique_id;
286
287 results = 0;
288 if (datacache != NULL)
289 results =
290 GNUNET_DATACACHE_get (datacache, message_context->key, get_type,
291 datacache_get_iterator, datacache_get_context);
292
293#if DEBUG_DHT
294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
295 "`%s': Found %d results for local `%s' request\n", "DHT",
296 results, "GET");
297#endif
298 GNUNET_free (datacache_get_context);
160 /* FIXME: Implement get functionality here */ 299 /* FIXME: Implement get functionality here */
161} 300}
162 301
@@ -164,14 +303,20 @@ static void handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg, GN
164/** 303/**
165 * Server handler for initiating local dht find peer requests 304 * Server handler for initiating local dht find peer requests
166 */ 305 */
167static void handle_dht_find_peer (void *cls, struct GNUNET_DHT_FindPeerMessage *find_msg, GNUNET_HashCode *key) 306static void
307handle_dht_find_peer (void *cls, struct GNUNET_DHT_FindPeerMessage *find_msg,
308 struct DHT_MessageContext *message_context)
168{ 309{
169#if DEBUG_DHT 310#if DEBUG_DHT
170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
171 "`%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n", "DHT", "FIND PEER", GNUNET_h2s(key), ntohs(find_msg->header.size), sizeof(struct GNUNET_DHT_FindPeerMessage)); 312 "`%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n",
313 "DHT", "FIND PEER", GNUNET_h2s (message_context->key),
314 ntohs (find_msg->header.size),
315 sizeof (struct GNUNET_DHT_FindPeerMessage));
172#endif 316#endif
173 317
174 GNUNET_assert(ntohs(find_msg->header.size) >= sizeof(struct GNUNET_DHT_FindPeerMessage)); 318 GNUNET_assert (ntohs (find_msg->header.size) >=
319 sizeof (struct GNUNET_DHT_FindPeerMessage));
175 320
176 /* FIXME: Implement find peer functionality here */ 321 /* FIXME: Implement find peer functionality here */
177} 322}
@@ -180,35 +325,44 @@ static void handle_dht_find_peer (void *cls, struct GNUNET_DHT_FindPeerMessage *
180/** 325/**
181 * Server handler for initiating local dht put requests 326 * Server handler for initiating local dht put requests
182 */ 327 */
183static void handle_dht_put (void *cls, struct GNUNET_DHT_PutMessage *put_msg, GNUNET_HashCode *key) 328static void
329handle_dht_put (void *cls, struct GNUNET_DHT_PutMessage *put_msg,
330 struct DHT_MessageContext *message_context)
184{ 331{
185 size_t put_type; 332 size_t put_type;
186 size_t data_size; 333 size_t data_size;
187 char *data;
188 334
189 GNUNET_assert(ntohs(put_msg->header.size) >= sizeof(struct GNUNET_DHT_PutMessage)); 335 GNUNET_assert (ntohs (put_msg->header.size) >=
336 sizeof (struct GNUNET_DHT_PutMessage));
190 337
191 put_type = ntohs(put_msg->type); 338 put_type = ntohs (put_msg->type);
192 data_size = ntohs(put_msg->data_size); 339 data_size = ntohs (put_msg->data_size);
193#if DEBUG_DHT 340#if DEBUG_DHT
194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
195 "`%s': %s msg total size is %d, data size %d, struct size %d\n", "DHT", "PUT", ntohs(put_msg->header.size), data_size, sizeof(struct GNUNET_DHT_PutMessage)); 342 "`%s': %s msg total size is %d, data size %d, struct size %d\n",
343 "DHT", "PUT", ntohs (put_msg->header.size), data_size,
344 sizeof (struct GNUNET_DHT_PutMessage));
196#endif 345#endif
197 GNUNET_assert(ntohs(put_msg->header.size) == sizeof(struct GNUNET_DHT_PutMessage) + data_size); 346 GNUNET_assert (ntohs (put_msg->header.size) ==
198 data = GNUNET_malloc(data_size); 347 sizeof (struct GNUNET_DHT_PutMessage) + data_size);
199 memcpy(data, &put_msg[1], data_size);
200 348
201#if DEBUG_DHT 349#if DEBUG_DHT
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "`%s': Received `%s' request from client, message type %d, key %s\n", "DHT", "PUT", put_type, GNUNET_h2s(key)); 351 "`%s': Received `%s' request from client, message type %d, key %s\n",
352 "DHT", "PUT", put_type, GNUNET_h2s (message_context->key));
204#endif 353#endif
205 354
206 355 /**
356 * Simplest DHT functionality, store any message we receive a put request for.
357 */
358 if (datacache != NULL)
359 GNUNET_DATACACHE_put (datacache, message_context->key, data_size,
360 (char *) &put_msg[1], put_type,
361 put_msg->expiration);
207 /** 362 /**
208 * FIXME: Implement dht put request functionality here! 363 * FIXME: Implement dht put request functionality here!
209 */ 364 */
210 365
211 GNUNET_free(data);
212} 366}
213 367
214/** 368/**
@@ -224,117 +378,145 @@ struct SendConfirmationContext
224 /** 378 /**
225 * Transmit handle. 379 * Transmit handle.
226 */ 380 */
227 struct GNUNET_CONNECTION_TransmitHandle * transmit_handle; 381 struct GNUNET_CONNECTION_TransmitHandle *transmit_handle;
228}; 382};
229 383
230static size_t send_confirmation (void *cls, 384static size_t
231 size_t size, void *buf) 385send_confirmation (void *cls, size_t size, void *buf)
232{ 386{
233 struct GNUNET_DHT_StopMessage *confirmation_message = cls; 387 struct GNUNET_DHT_StopMessage *confirmation_message = cls;
234 388
235 if (buf == NULL) /* Message timed out, that's crappy... */ 389 if (buf == NULL) /* Message timed out, that's crappy... */
236 { 390 {
237 GNUNET_free(confirmation_message); 391 GNUNET_free (confirmation_message);
238 return 0; 392 return 0;
239 } 393 }
240 394
241 if (size >= ntohs(confirmation_message->header.size)) 395 if (size >= ntohs (confirmation_message->header.size))
242 { 396 {
243 memcpy(buf, confirmation_message, ntohs(confirmation_message->header.size)); 397 memcpy (buf, confirmation_message,
244 return ntohs(confirmation_message->header.size); 398 ntohs (confirmation_message->header.size));
245 } 399 return ntohs (confirmation_message->header.size);
400 }
246 else 401 else
247 return 0; 402 return 0;
248} 403}
249 404
405
250static void 406static void
251send_client_receipt_confirmation(struct GNUNET_SERVER_Client *client, uint64_t uid) 407send_client_receipt_confirmation (struct GNUNET_SERVER_Client *client,
408 uint64_t uid)
252{ 409{
253 struct GNUNET_DHT_StopMessage *confirm_message; 410 struct GNUNET_DHT_StopMessage *confirm_message;
254 411
255#if DEBUG_DHT 412#if DEBUG_DHT
256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
257 "`%s': Sending receipt confirmation for uid %llu\n", "DHT", uid); 414 "`%s': Sending receipt confirmation for uid %llu\n", "DHT",
415 uid);
258#endif 416#endif
259 confirm_message = GNUNET_malloc(sizeof(struct GNUNET_DHT_StopMessage)); 417 confirm_message = GNUNET_malloc (sizeof (struct GNUNET_DHT_StopMessage));
260 confirm_message->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_STOP); 418 confirm_message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_STOP);
261 confirm_message->header.size = htons(sizeof(struct GNUNET_DHT_StopMessage)); 419 confirm_message->header.size =
262 confirm_message->unique_id = GNUNET_htonll(uid); 420 htons (sizeof (struct GNUNET_DHT_StopMessage));
421 confirm_message->unique_id = GNUNET_htonll (uid);
263 422
264 GNUNET_SERVER_notify_transmit_ready (client, 423 GNUNET_SERVER_notify_transmit_ready (client,
265 sizeof(struct GNUNET_DHT_StopMessage), 424 sizeof (struct GNUNET_DHT_StopMessage),
266 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), 425 GNUNET_TIME_relative_multiply
426 (GNUNET_TIME_UNIT_SECONDS, 5),
267 &send_confirmation, confirm_message); 427 &send_confirmation, confirm_message);
268 428
269} 429}
270 430
271static void 431static void
272handle_dht_start_message(void *cls, struct GNUNET_SERVER_Client * client, 432handle_dht_start_message (void *cls, struct GNUNET_SERVER_Client *client,
273 const struct GNUNET_MessageHeader *message) 433 const struct GNUNET_MessageHeader *message)
274{ 434{
275 struct GNUNET_DHT_Message *dht_msg = (struct GNUNET_DHT_Message *)message; 435 struct GNUNET_DHT_Message *dht_msg = (struct GNUNET_DHT_Message *) message;
276 struct GNUNET_MessageHeader *enc_msg; 436 struct GNUNET_MessageHeader *enc_msg;
437 struct DHT_MessageContext *message_context;
277 size_t enc_type; 438 size_t enc_type;
278 439
279 enc_msg = (struct GNUNET_MessageHeader *)&dht_msg[1]; 440 enc_msg = (struct GNUNET_MessageHeader *) &dht_msg[1];
280 enc_type = ntohs(enc_msg->type); 441 enc_type = ntohs (enc_msg->type);
281 442
282 443
283#if DEBUG_DHT 444#if DEBUG_DHT
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
285 "`%s': Received `%s' request from client, message type %d, key %s, uid %llu\n", "DHT", "GENERIC", enc_type, GNUNET_h2s(&dht_msg->key), GNUNET_ntohll(dht_msg->unique_id)); 446 "`%s': Received `%s' request from client, message type %d, key %s, uid %llu\n",
447 "DHT", "GENERIC", enc_type, GNUNET_h2s (&dht_msg->key),
448 GNUNET_ntohll (dht_msg->unique_id));
286#endif 449#endif
287 450
288 /* FIXME: Implement demultiplexing functionality here */ 451 message_context = GNUNET_malloc (sizeof (struct DHT_MessageContext));
452 message_context->client = client;
453 message_context->key = &dht_msg->key;
454 message_context->unique_id = GNUNET_ntohll (dht_msg->unique_id);
455 message_context->replication = ntohs (dht_msg->desired_replication_level);
456 message_context->msg_options = ntohs (dht_msg->options);
457
289 switch (enc_type) 458 switch (enc_type)
290 { 459 {
291 case GNUNET_MESSAGE_TYPE_DHT_GET: 460 case GNUNET_MESSAGE_TYPE_DHT_GET:
292 handle_dht_get(cls, (struct GNUNET_DHT_GetMessage *)enc_msg, &dht_msg->key); 461 handle_dht_get (cls, (struct GNUNET_DHT_GetMessage *) enc_msg,
462 message_context);
293 break; 463 break;
294 case GNUNET_MESSAGE_TYPE_DHT_PUT: 464 case GNUNET_MESSAGE_TYPE_DHT_PUT:
295 handle_dht_put(cls, (struct GNUNET_DHT_PutMessage *)enc_msg, &dht_msg->key); 465 handle_dht_put (cls, (struct GNUNET_DHT_PutMessage *) enc_msg,
296 send_client_receipt_confirmation(client, GNUNET_ntohll(dht_msg->unique_id)); 466 message_context);
467 send_client_receipt_confirmation (client,
468 GNUNET_ntohll (dht_msg->unique_id));
297 break; 469 break;
298 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER: 470 case GNUNET_MESSAGE_TYPE_DHT_FIND_PEER:
299 handle_dht_find_peer(cls, (struct GNUNET_DHT_FindPeerMessage *)enc_msg, &dht_msg->key); 471 handle_dht_find_peer (cls,
472 (struct GNUNET_DHT_FindPeerMessage *) enc_msg,
473 message_context);
300 break; 474 break;
301 default: 475 default:
302 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 476 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
303 "`%s': Message type (%d) not handled\n", "DHT", enc_type); 477 "`%s': Message type (%d) not handled\n", "DHT", enc_type);
304 } 478 }
305 479
306 GNUNET_SERVER_receive_done(client, GNUNET_OK); 480 GNUNET_free (message_context);
481 GNUNET_SERVER_receive_done (client, GNUNET_OK);
307 482
308} 483}
309 484
310 485
311static void 486static void
312handle_dht_stop_message(void *cls, struct GNUNET_SERVER_Client * client, 487handle_dht_stop_message (void *cls, struct GNUNET_SERVER_Client *client,
313 const struct GNUNET_MessageHeader *message) 488 const struct GNUNET_MessageHeader *message)
314{ 489{
315 struct GNUNET_DHT_StopMessage * dht_stop_msg = (struct GNUNET_DHT_StopMessage *)message; 490 struct GNUNET_DHT_StopMessage *dht_stop_msg =
491 (struct GNUNET_DHT_StopMessage *) message;
316 492
317#if DEBUG_DHT 493#if DEBUG_DHT
318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
319 "`%s': Received `%s' request from client, uid %llu\n", "DHT", "GENERIC STOP", GNUNET_ntohll(dht_stop_msg->unique_id)); 495 "`%s': Received `%s' request from client, uid %llu\n", "DHT",
496 "GENERIC STOP", GNUNET_ntohll (dht_stop_msg->unique_id));
320#endif 497#endif
321 send_client_receipt_confirmation(client, GNUNET_ntohll(dht_stop_msg->unique_id)); 498
322 GNUNET_SERVER_receive_done(client, GNUNET_OK); 499 /* TODO: Put in demultiplexing here */
500
501 send_client_receipt_confirmation (client,
502 GNUNET_ntohll (dht_stop_msg->unique_id));
503 GNUNET_SERVER_receive_done (client, GNUNET_OK);
323} 504}
324 505
325 506
326/** 507/**
327 * Core handler for p2p dht get requests. 508 * Core handler for p2p dht get requests.
328 */ 509 */
329static int handle_dht_p2p_get (void *cls, 510static int
330 const struct GNUNET_PeerIdentity * peer, 511handle_dht_p2p_get (void *cls,
331 const struct GNUNET_MessageHeader * message, 512 const struct GNUNET_PeerIdentity *peer,
332 struct GNUNET_TIME_Relative latency, 513 const struct GNUNET_MessageHeader *message,
333 uint32_t distance) 514 struct GNUNET_TIME_Relative latency, uint32_t distance)
334{ 515{
335#if DEBUG_DHT 516#if DEBUG_DHT
336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 517 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
337 "`%s': Received `%s' request from another peer\n", "DHT", "GET"); 518 "`%s': Received `%s' request from another peer\n", "DHT",
519 "GET");
338#endif 520#endif
339 521
340 return GNUNET_YES; 522 return GNUNET_YES;
@@ -343,15 +525,16 @@ static int handle_dht_p2p_get (void *cls,
343/** 525/**
344 * Core handler for p2p dht put requests. 526 * Core handler for p2p dht put requests.
345 */ 527 */
346static int handle_dht_p2p_put (void *cls, 528static int
347 const struct GNUNET_PeerIdentity * peer, 529handle_dht_p2p_put (void *cls,
348 const struct GNUNET_MessageHeader * message, 530 const struct GNUNET_PeerIdentity *peer,
349 struct GNUNET_TIME_Relative latency, 531 const struct GNUNET_MessageHeader *message,
350 uint32_t distance) 532 struct GNUNET_TIME_Relative latency, uint32_t distance)
351{ 533{
352#if DEBUG_DHT 534#if DEBUG_DHT
353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
354 "`%s': Received `%s' request from another peer\n", "DHT", "PUT"); 536 "`%s': Received `%s' request from another peer\n", "DHT",
537 "PUT");
355#endif 538#endif
356 539
357 return GNUNET_YES; 540 return GNUNET_YES;
@@ -360,15 +543,17 @@ static int handle_dht_p2p_put (void *cls,
360/** 543/**
361 * Core handler for p2p dht find peer requests. 544 * Core handler for p2p dht find peer requests.
362 */ 545 */
363static int handle_dht_p2p_find_peer (void *cls, 546static int
364 const struct GNUNET_PeerIdentity * peer, 547handle_dht_p2p_find_peer (void *cls,
365 const struct GNUNET_MessageHeader * message, 548 const struct GNUNET_PeerIdentity *peer,
366 struct GNUNET_TIME_Relative latency, 549 const struct GNUNET_MessageHeader *message,
367 uint32_t distance) 550 struct GNUNET_TIME_Relative latency,
551 uint32_t distance)
368{ 552{
369#if DEBUG_DHT 553#if DEBUG_DHT
370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
371 "`%s': Received `%s' request from another peer\n", "DHT", "FIND PEER"); 555 "`%s': Received `%s' request from another peer\n", "DHT",
556 "FIND PEER");
372#endif 557#endif
373 558
374 return GNUNET_YES; 559 return GNUNET_YES;
@@ -381,8 +566,7 @@ static int handle_dht_p2p_find_peer (void *cls,
381 * @param tc unused 566 * @param tc unused
382 */ 567 */
383static void 568static void
384shutdown_task (void *cls, 569shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
385 const struct GNUNET_SCHEDULER_TaskContext *tc)
386{ 570{
387 GNUNET_CORE_disconnect (coreAPI); 571 GNUNET_CORE_disconnect (coreAPI);
388} 572}
@@ -390,23 +574,25 @@ shutdown_task (void *cls,
390/** 574/**
391 * To be called on core init/fail. 575 * To be called on core init/fail.
392 */ 576 */
393void core_init (void *cls, 577void
394 struct GNUNET_CORE_Handle * server, 578core_init (void *cls,
395 const struct GNUNET_PeerIdentity *identity, 579 struct GNUNET_CORE_Handle *server,
396 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * publicKey) 580 const struct GNUNET_PeerIdentity *identity,
581 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
397{ 582{
398 583
399 if (server == NULL) 584 if (server == NULL)
400 { 585 {
401 GNUNET_SCHEDULER_cancel(sched, cleanup_task); 586 GNUNET_SCHEDULER_cancel (sched, cleanup_task);
402 GNUNET_SCHEDULER_add_now(sched, &shutdown_task, NULL); 587 GNUNET_SCHEDULER_add_now (sched, &shutdown_task, NULL);
403 return; 588 return;
404 } 589 }
405#if DEBUG_DHT 590#if DEBUG_DHT
406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 591 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
407 "%s: Core connection initialized, I am peer: %s\n", "dht", GNUNET_i2s(identity)); 592 "%s: Core connection initialized, I am peer: %s\n", "dht",
593 GNUNET_i2s (identity));
408#endif 594#endif
409 memcpy(&my_identity, identity, sizeof(struct GNUNET_PeerIdentity)); 595 memcpy (&my_identity, identity, sizeof (struct GNUNET_PeerIdentity));
410 coreAPI = server; 596 coreAPI = server;
411} 597}
412 598
@@ -429,32 +615,31 @@ run (void *cls,
429 615
430 datacache = GNUNET_DATACACHE_create (sched, cfg, "dhtcache"); 616 datacache = GNUNET_DATACACHE_create (sched, cfg, "dhtcache");
431 617
432 client_transmit_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5); 618 client_transmit_timeout =
619 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5);
433 GNUNET_SERVER_add_handlers (server, plugin_handlers); 620 GNUNET_SERVER_add_handlers (server, plugin_handlers);
434 621
435 coreAPI = 622 coreAPI = GNUNET_CORE_connect (sched, /* Main scheduler */
436 GNUNET_CORE_connect (sched, /* Main scheduler */ 623 cfg, /* Main configuration */
437 cfg, /* Main configuration */ 624 client_transmit_timeout, /* Delay for connecting */
438 client_transmit_timeout, /* Delay for connecting */ 625 NULL, /* FIXME: anything we want to pass around? */
439 NULL, /* FIXME: anything we want to pass around? */ 626 &core_init, /* Call core_init once connected */
440 &core_init, /* Call core_init once connected */ 627 NULL, /* Don't care about pre-connects */
441 NULL, /* Don't care about pre-connects */ 628 NULL, /* Don't care about connects */
442 NULL, /* Don't care about connects */ 629 NULL, /* Don't care about disconnects */
443 NULL, /* Don't care about disconnects */ 630 NULL, /* Don't want notified about all incoming messages */
444 NULL, /* Don't want notified about all incoming messages */ 631 GNUNET_NO, /* For header only inbound notification */
445 GNUNET_NO, /* For header only inbound notification */ 632 NULL, /* Don't want notified about all outbound messages */
446 NULL, /* Don't want notified about all outbound messages */ 633 GNUNET_NO, /* For header only outbound notification */
447 GNUNET_NO, /* For header only outbound notification */ 634 core_handlers); /* Register these handlers */
448 core_handlers); /* Register these handlers */
449 635
450 if (coreAPI == NULL) 636 if (coreAPI == NULL)
451 return; 637 return;
452 638
453 /* Scheduled the task to clean up when shutdown is called */ 639 /* Scheduled the task to clean up when shutdown is called */
454 cleanup_task = GNUNET_SCHEDULER_add_delayed (sched, 640 cleanup_task = GNUNET_SCHEDULER_add_delayed (sched,
455 GNUNET_TIME_UNIT_FOREVER_REL, 641 GNUNET_TIME_UNIT_FOREVER_REL,
456 &shutdown_task, 642 &shutdown_task, NULL);
457 NULL);
458} 643}
459 644
460 645
diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c
index 9dc429148..f9d9e008c 100644
--- a/src/dht/test_dht_api.c
+++ b/src/dht/test_dht_api.c
@@ -75,8 +75,7 @@ GNUNET_SCHEDULER_TaskIdentifier die_task;
75 75
76 76
77static void 77static void
78end (void *cls, 78end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
79 const struct GNUNET_SCHEDULER_TaskContext * tc)
80{ 79{
81 /* do work here */ 80 /* do work here */
82 GNUNET_SCHEDULER_cancel (sched, die_task); 81 GNUNET_SCHEDULER_cancel (sched, die_task);
@@ -86,15 +85,17 @@ end (void *cls,
86 die_task = GNUNET_SCHEDULER_NO_TASK; 85 die_task = GNUNET_SCHEDULER_NO_TASK;
87 86
88 if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) 87 if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
89 { 88 {
90 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DHT disconnected, returning FAIL!\n"); 89 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
91 ok = 365; 90 "DHT disconnected, returning FAIL!\n");
92 } 91 ok = 365;
92 }
93 else 93 else
94 { 94 {
95 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DHT disconnected, returning success!\n"); 95 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
96 ok = 0; 96 "DHT disconnected, returning success!\n");
97 } 97 ok = 0;
98 }
98} 99}
99 100
100static void 101static void
@@ -114,7 +115,7 @@ end_badly ()
114{ 115{
115 /* do work here */ 116 /* do work here */
116#if VERBOSE 117#if VERBOSE
117 fprintf(stderr, "Ending on an unhappy note.\n"); 118 fprintf (stderr, "Ending on an unhappy note.\n");
118#endif 119#endif
119 120
120 GNUNET_DHT_disconnect (p1.dht_handle); 121 GNUNET_DHT_disconnect (p1.dht_handle);
@@ -129,18 +130,18 @@ end_badly ()
129 * @param cls closure 130 * @param cls closure
130 * @param tc context information (why was this task triggered now) 131 * @param tc context information (why was this task triggered now)
131 */ 132 */
132void test_find_peer_stop (void *cls, 133void
133 const struct GNUNET_SCHEDULER_TaskContext * tc) 134test_find_peer_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
134{ 135{
135 struct PeerContext *peer = cls; 136 struct PeerContext *peer = cls;
136 137
137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer_stop!\n"); 138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer_stop!\n");
138 if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) 139 if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
139 GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL); 140 GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
140 141
141 GNUNET_assert (peer->dht_handle != NULL); 142 GNUNET_assert (peer->dht_handle != NULL);
142 143
143 GNUNET_DHT_find_peer_stop(peer->find_peer_handle, &end, &p1); 144 GNUNET_DHT_find_peer_stop (peer->find_peer_handle, &end, &p1);
144 145
145 //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &end, &p1); 146 //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &end, &p1);
146 147
@@ -152,20 +153,22 @@ void test_find_peer_stop (void *cls,
152 * @param cls closure 153 * @param cls closure
153 * @param tc context information (why was this task triggered now) 154 * @param tc context information (why was this task triggered now)
154 */ 155 */
155void test_find_peer (void *cls, 156void
156 const struct GNUNET_SCHEDULER_TaskContext * tc) 157test_find_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
157{ 158{
158 struct PeerContext *peer = cls; 159 struct PeerContext *peer = cls;
159 GNUNET_HashCode hash; 160 GNUNET_HashCode hash;
160 memset(&hash, 42, sizeof(GNUNET_HashCode)); 161 memset (&hash, 42, sizeof (GNUNET_HashCode));
161 162
162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer!\n"); 163 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer!\n");
163 GNUNET_assert (peer->dht_handle != NULL); 164 GNUNET_assert (peer->dht_handle != NULL);
164 165
165 peer->find_peer_handle = GNUNET_DHT_find_peer_start(peer->dht_handle, TIMEOUT, 0, NULL, &hash, NULL, NULL, &test_find_peer_stop, &p1); 166 peer->find_peer_handle =
167 GNUNET_DHT_find_peer_start (peer->dht_handle, TIMEOUT, 0, NULL, &hash,
168 NULL, NULL, &test_find_peer_stop, &p1);
166 169
167 if (peer->find_peer_handle == NULL) 170 if (peer->find_peer_handle == NULL)
168 GNUNET_SCHEDULER_add_now(sched, &end_badly, &p1); 171 GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1);
169} 172}
170 173
171/** 174/**
@@ -174,21 +177,34 @@ void test_find_peer (void *cls,
174 * @param cls closure 177 * @param cls closure
175 * @param tc context information (why was this task triggered now) 178 * @param tc context information (why was this task triggered now)
176 */ 179 */
177void test_put (void *cls, 180void
178 const struct GNUNET_SCHEDULER_TaskContext * tc) 181test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
179{ 182{
180 struct PeerContext *peer = cls; 183 struct PeerContext *peer = cls;
181 GNUNET_HashCode hash; 184
182 char *data; 185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n");
183 size_t data_size = 42; 186 if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
184 memset(&hash, 42, sizeof(GNUNET_HashCode)); 187 GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
185 data = GNUNET_malloc(data_size); 188
186 memset(data, 43, data_size);
187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n");
188 GNUNET_assert (peer->dht_handle != NULL); 189 GNUNET_assert (peer->dht_handle != NULL);
189 190
190 GNUNET_DHT_put(peer->dht_handle, &hash, 0, data_size, data, GNUNET_TIME_relative_to_absolute(TIMEOUT), TIMEOUT, &test_find_peer, &p1); 191 GNUNET_DHT_get_stop (peer->get_handle, &test_find_peer, &p1);
192
193 //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1);
194
195}
196
197void
198test_get_iterator (void *cls,
199 struct GNUNET_TIME_Absolute exp,
200 const GNUNET_HashCode * key,
201 uint32_t type, uint32_t size, const void *data)
202{
203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
204 "test_get_iterator called (we got a result), stopping get request!\n");
191 205
206 GNUNET_SCHEDULER_add_continuation (sched, &test_get_stop, &p1,
207 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
192} 208}
193 209
194/** 210/**
@@ -197,21 +213,23 @@ void test_put (void *cls,
197 * @param cls closure 213 * @param cls closure
198 * @param tc context information (why was this task triggered now) 214 * @param tc context information (why was this task triggered now)
199 */ 215 */
200void test_get_stop (void *cls, 216void
201 const struct GNUNET_SCHEDULER_TaskContext * tc) 217test_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
202{ 218{
203 struct PeerContext *peer = cls; 219 struct PeerContext *peer = cls;
220 GNUNET_HashCode hash;
221 memset (&hash, 42, sizeof (GNUNET_HashCode));
204 222
205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n"); 223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get!\n");
206 if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
207 GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL);
208 224
209 GNUNET_assert (peer->dht_handle != NULL); 225 GNUNET_assert (peer->dht_handle != NULL);
210 226
211 GNUNET_DHT_get_stop(peer->get_handle, &test_put, &p1); 227 peer->get_handle =
212 228 GNUNET_DHT_get_start (peer->dht_handle, TIMEOUT, 42, &hash,
213 //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); 229 &test_get_iterator, NULL, NULL, NULL);
214 230
231 if (peer->get_handle == NULL)
232 GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1);
215} 233}
216 234
217/** 235/**
@@ -220,21 +238,25 @@ void test_get_stop (void *cls,
220 * @param cls closure 238 * @param cls closure
221 * @param tc context information (why was this task triggered now) 239 * @param tc context information (why was this task triggered now)
222 */ 240 */
223void test_get (void *cls, 241void
224 const struct GNUNET_SCHEDULER_TaskContext * tc) 242test_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
225{ 243{
226 struct PeerContext *peer = cls; 244 struct PeerContext *peer = cls;
227 GNUNET_HashCode hash; 245 GNUNET_HashCode hash;
228 memset(&hash, 42, sizeof(GNUNET_HashCode)); 246 char *data;
229 247 size_t data_size = 42;
230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get!\n"); 248 memset (&hash, 42, sizeof (GNUNET_HashCode));
249 data = GNUNET_malloc (data_size);
250 memset (data, 43, data_size);
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n");
231 peer->dht_handle = GNUNET_DHT_connect (sched, peer->cfg, 100); 252 peer->dht_handle = GNUNET_DHT_connect (sched, peer->cfg, 100);
253
232 GNUNET_assert (peer->dht_handle != NULL); 254 GNUNET_assert (peer->dht_handle != NULL);
233 255
234 peer->get_handle = GNUNET_DHT_get_start(peer->dht_handle, TIMEOUT, 42, &hash, NULL, NULL, &test_get_stop, &p1); 256 GNUNET_DHT_put (peer->dht_handle, &hash, 0, data_size, data,
257 GNUNET_TIME_relative_to_absolute (TIMEOUT), TIMEOUT,
258 &test_get, &p1);
235 259
236 if (peer->get_handle == NULL)
237 GNUNET_SCHEDULER_add_now(sched, &end_badly, &p1);
238} 260}
239 261
240static void 262static void
@@ -264,11 +286,16 @@ run (void *cls,
264 sched = s; 286 sched = s;
265 287
266 die_task = GNUNET_SCHEDULER_add_delayed (sched, 288 die_task = GNUNET_SCHEDULER_add_delayed (sched,
267 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1), &end_badly, NULL); 289 GNUNET_TIME_relative_multiply
290 (GNUNET_TIME_UNIT_MINUTES, 1),
291 &end_badly, NULL);
268 292
269 setup_peer (&p1, "test_dht_api_peer1.conf"); 293 setup_peer (&p1, "test_dht_api_peer1.conf");
270 294
271 GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_get, &p1); 295 GNUNET_SCHEDULER_add_delayed (sched,
296 GNUNET_TIME_relative_multiply
297 (GNUNET_TIME_UNIT_SECONDS, 1), &test_put,
298 &p1);
272} 299}
273 300
274static int 301static int
@@ -290,8 +317,7 @@ check ()
290 317
291 ok = 1; 318 ok = 1;
292 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, 319 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
293 argv, "test-dht-api", "nohelp", 320 argv, "test-dht-api", "nohelp", options, &run, &ok);
294 options, &run, &ok);
295 stop_arm (&p1); 321 stop_arm (&p1);
296 return ok; 322 return ok;
297} 323}
@@ -314,7 +340,7 @@ main (int argc, char *argv[])
314 NULL); 340 NULL);
315 ret = check (); 341 ret = check ();
316 342
317 //GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-dht-peer-1"); 343 GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-dht-peer-1");
318 344
319 return ret; 345 return ret;
320} 346}