diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-07-18 22:24:00 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-07-18 22:24:00 +0000 |
commit | 8f73677b530811bf3e2e4c66802958b38abfccb9 (patch) | |
tree | be4dc00f2a008936772da029aa0d4e7458b097f6 /src/datastore | |
parent | b103d434085de5070880f3bcb025cda5fff6836d (diff) | |
download | gnunet-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.c | 195 |
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 | */ | ||
464 | static void | ||
465 | with_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 | */ | ||
541 | static size_t | ||
542 | transmit_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 | */ | ||
583 | static void | ||
584 | transmit_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 | ||