aboutsummaryrefslogtreecommitdiff
path: root/src/datastore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-07-18 22:24:00 +0000
committerChristian Grothoff <christian@grothoff.org>2009-07-18 22:24:00 +0000
commit8f73677b530811bf3e2e4c66802958b38abfccb9 (patch)
treebe4dc00f2a008936772da029aa0d4e7458b097f6 /src/datastore
parentb103d434085de5070880f3bcb025cda5fff6836d (diff)
downloadgnunet-8f73677b530811bf3e2e4c66802958b38abfccb9.tar.gz
gnunet-8f73677b530811bf3e2e4c66802958b38abfccb9.zip
finished first draft of implementation of datastore API
Diffstat (limited to 'src/datastore')
-rw-r--r--src/datastore/datastore_api.c195
1 files changed, 185 insertions, 10 deletions
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index 951cf2651..c67b7556a 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -23,7 +23,6 @@
23 * @brief Management for the datastore for files stored on a GNUnet node 23 * @brief Management for the datastore for files stored on a GNUnet node
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26
27#include "platform.h" 26#include "platform.h"
28#include "gnunet_datastore_service.h" 27#include "gnunet_datastore_service.h"
29#include "datastore.h" 28#include "datastore.h"
@@ -72,7 +71,7 @@ struct GNUNET_DATASTORE_Handle
72 * this struct, 0 if we have no request pending. 71 * this struct, 0 if we have no request pending.
73 */ 72 */
74 size_t message_size; 73 size_t message_size;
75 74
76}; 75};
77 76
78 77
@@ -194,6 +193,7 @@ with_status_response_handler (void *cls,
194 (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_STATUS) ) 193 (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_STATUS) )
195 { 194 {
196 GNUNET_break (0); 195 GNUNET_break (0);
196 h->response_proc = NULL;
197 GNUNET_CLIENT_disconnect (h->client); 197 GNUNET_CLIENT_disconnect (h->client);
198 h->client = GNUNET_CLIENT_connect (h->sched, "datastore", h->cfg); 198 h->client = GNUNET_CLIENT_connect (h->sched, "datastore", h->cfg);
199 cont (h->response_proc_cls, 199 cont (h->response_proc_cls,
@@ -240,10 +240,10 @@ transmit_get_status (void *cls,
240 GNUNET_DATASTORE_ContinuationWithStatus cont = h->response_proc; 240 GNUNET_DATASTORE_ContinuationWithStatus cont = h->response_proc;
241 uint16_t msize; 241 uint16_t msize;
242 242
243 h->response_proc = NULL;
244 if (buf == NULL) 243 if (buf == NULL)
245 { 244 {
246 h->message_size = 0; 245 h->message_size = 0;
246 h->response_proc = NULL;
247 cont (h->response_proc_cls, 247 cont (h->response_proc_cls,
248 GNUNET_SYSERR, 248 GNUNET_SYSERR,
249 gettext_noop ("Error transmitting message to datastore service.\n")); 249 gettext_noop ("Error transmitting message to datastore service.\n"));
@@ -451,6 +451,167 @@ GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h,
451} 451}
452 452
453 453
454
455
456/**
457 * Type of a function to call when we receive a message
458 * from the service. This specific function is used
459 * to handle messages of type "struct DataMessage".
460 *
461 * @param cls closure
462 * @param msg message received, NULL on timeout or fatal error
463 */
464static void
465with_result_response_handler (void *cls,
466 const struct
467 GNUNET_MessageHeader * msg)
468{
469 static struct GNUNET_TIME_Absolute zero;
470 struct GNUNET_DATASTORE_Handle *h = cls;
471 GNUNET_DATASTORE_Iterator cont = h->response_proc;
472 const struct DataMessage *dm;
473 size_t msize;
474
475 if (msg == NULL)
476 {
477 h->response_proc = NULL;
478 GNUNET_CLIENT_disconnect (h->client);
479 h->client = GNUNET_CLIENT_connect (h->sched, "datastore", h->cfg);
480 cont (h->response_proc_cls,
481 NULL, 0, NULL, 0, 0, 0, zero, 0);
482 return;
483 }
484 if (ntohs(msg->type) == GNUNET_MESSAGE_TYPE_DATASTORE_DATA_END)
485 {
486 GNUNET_break (ntohs(msg->size) == sizeof(struct GNUNET_MessageHeader));
487 h->response_proc = NULL;
488 cont (h->response_proc_cls,
489 NULL, 0, NULL, 0, 0, 0, zero, 0);
490 return;
491 }
492 if ( (ntohs(msg->size) < sizeof(struct DataMessage)) ||
493 (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_DATASTORE_DATA) )
494 {
495 GNUNET_break (0);
496 GNUNET_CLIENT_disconnect (h->client);
497 h->client = GNUNET_CLIENT_connect (h->sched, "datastore", h->cfg);
498 h->response_proc = NULL;
499 cont (h->response_proc_cls,
500 NULL, 0, NULL, 0, 0, 0, zero, 0);
501 return;
502 }
503 dm = (const struct DataMessage*) msg;
504 msize = ntohl(dm->size);
505 if (ntohs(msg->size) != msize + sizeof(struct DataMessage))
506 {
507 GNUNET_break (0);
508 GNUNET_CLIENT_disconnect (h->client);
509 h->client = GNUNET_CLIENT_connect (h->sched, "datastore", h->cfg);
510 h->response_proc = NULL;
511 cont (h->response_proc_cls,
512 NULL, 0, NULL, 0, 0, 0, zero, 0);
513 return;
514 }
515 cont (h->response_proc_cls,
516 &dm->key,
517 msize,
518 &dm[1],
519 ntohl(dm->type),
520 ntohl(dm->priority),
521 ntohl(dm->anonymity),
522 GNUNET_TIME_absolute_ntoh(dm->expiration),
523 GNUNET_ntohll(dm->uid));
524 GNUNET_CLIENT_receive (h->client,
525 &with_result_response_handler,
526 h,
527 GNUNET_TIME_absolute_get_remaining (h->timeout));
528}
529
530
531/**
532 * Transmit message to datastore service and then
533 * read a result message.
534 *
535 * @param cls closure with handle to datastore
536 * @param size number of bytes we can transmit at most
537 * @param buf where to write transmission, NULL on
538 * timeout
539 * @return number of bytes copied to buf
540 */
541static size_t
542transmit_get_result (void *cls,
543 size_t size,
544 void *buf)
545{
546 struct GNUNET_DATASTORE_Handle *h = cls;
547 GNUNET_DATASTORE_ContinuationWithStatus cont = h->response_proc;
548 uint16_t msize;
549
550 h->response_proc = NULL;
551 if (buf == NULL)
552 {
553 h->message_size = 0;
554 cont (h->response_proc_cls,
555 GNUNET_SYSERR,
556 gettext_noop ("Error transmitting message to datastore service.\n"));
557 return 0;
558 }
559 GNUNET_assert (h->message_size <= size);
560 memcpy (buf, &h[1], h->message_size);
561 h->message_size = 0;
562 GNUNET_CLIENT_receive (h->client,
563 &with_result_response_handler,
564 h,
565 GNUNET_TIME_absolute_get_remaining (h->timeout));
566 return msize;
567}
568
569
570/**
571 * Helper function that will initiate the
572 * transmission of a message to the datastore
573 * service. The message must already be prepared
574 * and stored in the buffer at the end of the
575 * handle. The message must be of a type that
576 * expects a "DataMessage" in response.
577 *
578 * @param h handle to the service with prepared message
579 * @param cont function to call with result
580 * @param cont_cls closure
581 * @param timeout timeout for the operation
582 */
583static void
584transmit_for_result (struct GNUNET_DATASTORE_Handle *h,
585 GNUNET_DATASTORE_Iterator cont,
586 void *cont_cls,
587 struct GNUNET_TIME_Relative timeout)
588{
589 static struct GNUNET_TIME_Absolute zero;
590 const struct GNUNET_MessageHeader *hdr;
591 uint16_t msize;
592
593 hdr = (const struct GNUNET_MessageHeader*) &h[1];
594 msize = ntohs(hdr->size);
595 GNUNET_assert (h->response_proc == NULL);
596 h->response_proc = cont;
597 h->response_proc_cls = cont_cls;
598 h->timeout = GNUNET_TIME_relative_to_absolute (timeout);
599 h->message_size = msize;
600 if (NULL == GNUNET_CLIENT_notify_transmit_ready (h->client,
601 msize,
602 timeout,
603 &transmit_get_result,
604 h))
605 {
606 GNUNET_break (0);
607 h->response_proc = NULL;
608 h->message_size = 0;
609 cont (h->response_proc_cls,
610 NULL, 0, NULL, 0, 0, 0, zero, 0);
611 }
612}
613
614
454/** 615/**
455 * Iterate over the results for a particular key 616 * Iterate over the results for a particular key
456 * in the datastore. 617 * in the datastore.
@@ -470,9 +631,21 @@ GNUNET_DATASTORE_get (struct GNUNET_DATASTORE_Handle *h,
470 GNUNET_DATASTORE_Iterator iter, void *iter_cls, 631 GNUNET_DATASTORE_Iterator iter, void *iter_cls,
471 struct GNUNET_TIME_Relative timeout) 632 struct GNUNET_TIME_Relative timeout)
472{ 633{
473 static struct GNUNET_TIME_Absolute zero; 634 struct GetMessage *gm;
474 iter (iter_cls, 635
475 NULL, 0, NULL, 0, 0, 0, zero, 0); 636 gm = (struct GetMessage*) &h[1];
637 gm->header.type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_GET);
638 gm->type = htonl(type);
639 if (key != NULL)
640 {
641 gm->header.size = htons(sizeof (struct GetMessage));
642 gm->key = *key;
643 }
644 else
645 {
646 gm->header.size = htons(sizeof (struct GetMessage) - sizeof(GNUNET_HashCode));
647 }
648 transmit_for_result (h, iter, iter_cls, timeout);
476} 649}
477 650
478 651
@@ -491,10 +664,12 @@ GNUNET_DATASTORE_get_random (struct GNUNET_DATASTORE_Handle *h,
491 GNUNET_DATASTORE_Iterator iter, void *iter_cls, 664 GNUNET_DATASTORE_Iterator iter, void *iter_cls,
492 struct GNUNET_TIME_Relative timeout) 665 struct GNUNET_TIME_Relative timeout)
493{ 666{
494 static struct GNUNET_TIME_Absolute zero; 667 struct GNUNET_MessageHeader *m;
495 668
496 iter (iter_cls, 669 m = (struct GNUNET_MessageHeader*) &h[1];
497 NULL, 0, NULL, 0, 0, 0, zero, 0); 670 m->type = htons(GNUNET_MESSAGE_TYPE_DATASTORE_GET_RANDOM);
671 m->size = htons(sizeof (struct GNUNET_MessageHeader));
672 transmit_for_result (h, iter, iter_cls, timeout);
498} 673}
499 674
500 675