aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/peerstore_api.c
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-12-18 17:39:01 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-12-18 17:39:01 +0000
commit42c34f9b26b6b0222a10f61850af73914ce5a359 (patch)
tree35d3e09cba60749f93c0ddc0f9032fcd89a22288 /src/peerstore/peerstore_api.c
parentfb12af8319a84389a536ab2f3735daf3b24f11bd (diff)
downloadgnunet-42c34f9b26b6b0222a10f61850af73914ce5a359.tar.gz
gnunet-42c34f9b26b6b0222a10f61850af73914ce5a359.zip
towards fixing #3581
Diffstat (limited to 'src/peerstore/peerstore_api.c')
-rw-r--r--src/peerstore/peerstore_api.c199
1 files changed, 100 insertions, 99 deletions
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index 46f170a23..52b1b22ca 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -180,6 +180,26 @@ struct GNUNET_PEERSTORE_IterateContext
180 struct GNUNET_PEERSTORE_Handle *h; 180 struct GNUNET_PEERSTORE_Handle *h;
181 181
182 /** 182 /**
183 * Which subsystem does the store?
184 */
185 char *sub_system;
186
187 /**
188 * Peer the store is for.
189 */
190 struct GNUNET_PeerIdentity peer;
191
192 /**
193 * Key for the store operation.
194 */
195 char *key;
196
197 /**
198 * Operation timeout
199 */
200 struct GNUNET_TIME_Relative timeout;
201
202 /**
183 * MQ Envelope with iterate request message 203 * MQ Envelope with iterate request message
184 */ 204 */
185 struct GNUNET_MQ_Envelope *ev; 205 struct GNUNET_MQ_Envelope *ev;
@@ -311,8 +331,7 @@ iterate_request_sent (void *cls)
311{ 331{
312 struct GNUNET_PEERSTORE_IterateContext *ic = cls; 332 struct GNUNET_PEERSTORE_IterateContext *ic = cls;
313 333
314 LOG (GNUNET_ERROR_TYPE_DEBUG, 334 LOG (GNUNET_ERROR_TYPE_DEBUG, "Iterate request sent to service.\n");
315 "Iterate request sent to service.\n");
316 ic->iterating = GNUNET_YES; 335 ic->iterating = GNUNET_YES;
317 ic->ev = NULL; 336 ic->ev = NULL;
318} 337}
@@ -369,9 +388,7 @@ handle_client_error (void *cls, enum GNUNET_MQ_Error error)
369 * Iterator over previous watches to resend them 388 * Iterator over previous watches to resend them
370 */ 389 */
371static int 390static int
372rewatch_it (void *cls, 391rewatch_it (void *cls, const struct GNUNET_HashCode *key, void *value)
373 const struct GNUNET_HashCode *key,
374 void *value)
375{ 392{
376 struct GNUNET_PEERSTORE_Handle *h = cls; 393 struct GNUNET_PEERSTORE_Handle *h = cls;
377 struct GNUNET_PEERSTORE_WatchContext *wc = value; 394 struct GNUNET_PEERSTORE_WatchContext *wc = value;
@@ -390,6 +407,28 @@ rewatch_it (void *cls,
390 407
391 408
392/** 409/**
410 * Called when the iterate request is timedout
411 *
412 * @param cls a `struct GNUNET_PEERSTORE_IterateContext *`
413 * @param tc Scheduler task context (unused)
414 */
415static void
416iterate_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
417{
418 struct GNUNET_PEERSTORE_IterateContext *ic = cls;
419 GNUNET_PEERSTORE_Processor callback;
420 void *callback_cls;
421
422 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
423 callback = ic->callback;
424 callback_cls = ic->callback_cls;
425 GNUNET_PEERSTORE_iterate_cancel (ic);
426 if (NULL != callback)
427 callback (callback_cls, NULL, _("timeout"));
428}
429
430
431/**
393 * Close the existing connection to PEERSTORE and reconnect. 432 * Close the existing connection to PEERSTORE and reconnect.
394 * 433 *
395 * @param h handle to the service 434 * @param h handle to the service
@@ -402,8 +441,7 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
402 void *icb_cls; 441 void *icb_cls;
403 struct GNUNET_PEERSTORE_StoreContext *sc; 442 struct GNUNET_PEERSTORE_StoreContext *sc;
404 443
405 LOG (GNUNET_ERROR_TYPE_DEBUG, 444 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting...\n");
406 "Reconnecting...\n");
407 for (sc = h->store_head; NULL != sc; sc = sc->next) 445 for (sc = h->store_head; NULL != sc; sc = sc->next)
408 { 446 {
409 if (NULL != sc->ev) 447 if (NULL != sc->ev)
@@ -430,9 +468,7 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
430 LOG (GNUNET_ERROR_TYPE_DEBUG, 468 LOG (GNUNET_ERROR_TYPE_DEBUG,
431 "Resending pending requests after reconnect.\n"); 469 "Resending pending requests after reconnect.\n");
432 if (NULL != h->watches) 470 if (NULL != h->watches)
433 GNUNET_CONTAINER_multihashmap_iterate (h->watches, 471 GNUNET_CONTAINER_multihashmap_iterate (h->watches, &rewatch_it, h);
434 &rewatch_it,
435 h);
436 for (ic = h->iterate_head; NULL != ic; ic = ic->next) 472 for (ic = h->iterate_head; NULL != ic; ic = ic->next)
437 { 473 {
438 if (GNUNET_YES == ic->iterating) 474 if (GNUNET_YES == ic->iterating)
@@ -441,31 +477,38 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
441 icb_cls = ic->callback_cls; 477 icb_cls = ic->callback_cls;
442 GNUNET_PEERSTORE_iterate_cancel (ic); 478 GNUNET_PEERSTORE_iterate_cancel (ic);
443 if (NULL != icb) 479 if (NULL != icb)
444 icb (icb_cls, 480 icb (icb_cls, NULL, _("Iteration canceled due to reconnection."));
445 NULL,
446 _("Iteration canceled due to reconnection."));
447 } 481 }
448 else 482 else
449 { 483 {
450 GNUNET_MQ_notify_sent (ic->ev, 484 if (GNUNET_SCHEDULER_NO_TASK != ic->timeout_task)
451 &iterate_request_sent, 485 {
452 ic); 486 GNUNET_SCHEDULER_cancel (ic->timeout_task);
487 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
488 }
489 if (NULL != ic->ev)
490 {
491 GNUNET_MQ_send_cancel (ic->ev);
492 ic->ev = NULL;
493 }
494 ic->ev =
495 PEERSTORE_create_record_mq_envelope (ic->sub_system, &ic->peer,
496 ic->key, NULL, 0, NULL, 0,
497 GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE);
498 GNUNET_MQ_notify_sent (ic->ev, &iterate_request_sent, ic);
453 GNUNET_MQ_send (h->mq, ic->ev); 499 GNUNET_MQ_send (h->mq, ic->ev);
500 ic->timeout_task =
501 GNUNET_SCHEDULER_add_delayed (ic->timeout, &iterate_timeout, ic);
454 } 502 }
455 } 503 }
456 for (sc = h->store_head; NULL != sc; sc = sc->next) 504 for (sc = h->store_head; NULL != sc; sc = sc->next)
457 { 505 {
458 sc->ev = PEERSTORE_create_record_mq_envelope (sc->sub_system, 506 sc->ev =
459 &sc->peer, 507 PEERSTORE_create_record_mq_envelope (sc->sub_system, &sc->peer, sc->key,
460 sc->key, 508 sc->value, sc->size, &sc->expiry,
461 sc->value, 509 sc->options,
462 sc->size, 510 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
463 &sc->expiry, 511 GNUNET_MQ_notify_sent (sc->ev, &store_request_sent, sc);
464 sc->options,
465 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
466 GNUNET_MQ_notify_sent (sc->ev,
467 &store_request_sent,
468 sc);
469 GNUNET_MQ_send (h->mq, sc->ev); 512 GNUNET_MQ_send (h->mq, sc->ev);
470 } 513 }
471} 514}
@@ -480,9 +523,7 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h)
480 * @return #GNUNET_YES to continue iteration 523 * @return #GNUNET_YES to continue iteration
481 */ 524 */
482static int 525static int
483destroy_watch (void *cls, 526destroy_watch (void *cls, const struct GNUNET_HashCode *key, void *value)
484 const struct GNUNET_HashCode *key,
485 void *value)
486{ 527{
487 struct GNUNET_PEERSTORE_WatchContext *wc = value; 528 struct GNUNET_PEERSTORE_WatchContext *wc = value;
488 529
@@ -545,8 +586,7 @@ GNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
545 GNUNET_free (h); 586 GNUNET_free (h);
546 return NULL; 587 return NULL;
547 } 588 }
548 LOG (GNUNET_ERROR_TYPE_DEBUG, 589 LOG (GNUNET_ERROR_TYPE_DEBUG, "New connection created\n");
549 "New connection created\n");
550 return h; 590 return h;
551} 591}
552 592
@@ -567,13 +607,10 @@ GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h, int sync_first)
567 struct GNUNET_PEERSTORE_StoreContext *sc; 607 struct GNUNET_PEERSTORE_StoreContext *sc;
568 struct GNUNET_PEERSTORE_StoreContext *sc_iter; 608 struct GNUNET_PEERSTORE_StoreContext *sc_iter;
569 609
570 LOG (GNUNET_ERROR_TYPE_DEBUG, 610 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting.\n");
571 "Disconnecting.\n");
572 if (NULL != h->watches) 611 if (NULL != h->watches)
573 { 612 {
574 GNUNET_CONTAINER_multihashmap_iterate (h->watches, 613 GNUNET_CONTAINER_multihashmap_iterate (h->watches, &destroy_watch, NULL);
575 &destroy_watch,
576 NULL);
577 GNUNET_CONTAINER_multihashmap_destroy (h->watches); 614 GNUNET_CONTAINER_multihashmap_destroy (h->watches);
578 h->watches = NULL; 615 h->watches = NULL;
579 } 616 }
@@ -626,15 +663,12 @@ GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
626 GNUNET_MQ_send_cancel (sc->ev); 663 GNUNET_MQ_send_cancel (sc->ev);
627 sc->ev = NULL; 664 sc->ev = NULL;
628 } 665 }
629 GNUNET_CONTAINER_DLL_remove (sc->h->store_head, 666 GNUNET_CONTAINER_DLL_remove (sc->h->store_head, sc->h->store_tail, sc);
630 sc->h->store_tail,
631 sc);
632 GNUNET_free (sc->sub_system); 667 GNUNET_free (sc->sub_system);
633 GNUNET_free (sc->value); 668 GNUNET_free (sc->value);
634 GNUNET_free (sc->key); 669 GNUNET_free (sc->key);
635 GNUNET_free (sc); 670 GNUNET_free (sc);
636 if ( (GNUNET_YES == h->disconnecting) && 671 if ((GNUNET_YES == h->disconnecting) && (NULL == h->store_head))
637 (NULL == h->store_head) )
638 do_disconnect (h); 672 do_disconnect (h);
639} 673}
640 674
@@ -658,14 +692,11 @@ GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
658struct GNUNET_PEERSTORE_StoreContext * 692struct GNUNET_PEERSTORE_StoreContext *
659GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h, 693GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
660 const char *sub_system, 694 const char *sub_system,
661 const struct GNUNET_PeerIdentity *peer, 695 const struct GNUNET_PeerIdentity *peer, const char *key,
662 const char *key, 696 const void *value, size_t size,
663 const void *value,
664 size_t size,
665 struct GNUNET_TIME_Absolute expiry, 697 struct GNUNET_TIME_Absolute expiry,
666 enum GNUNET_PEERSTORE_StoreOption options, 698 enum GNUNET_PEERSTORE_StoreOption options,
667 GNUNET_PEERSTORE_Continuation cont, 699 GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
668 void *cont_cls)
669{ 700{
670 struct GNUNET_MQ_Envelope *ev; 701 struct GNUNET_MQ_Envelope *ev;
671 struct GNUNET_PEERSTORE_StoreContext *sc; 702 struct GNUNET_PEERSTORE_StoreContext *sc;
@@ -673,15 +704,11 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
673 LOG (GNUNET_ERROR_TYPE_DEBUG, 704 LOG (GNUNET_ERROR_TYPE_DEBUG,
674 "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n", 705 "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n",
675 size, sub_system, GNUNET_i2s (peer), key); 706 size, sub_system, GNUNET_i2s (peer), key);
676 ev = PEERSTORE_create_record_mq_envelope (sub_system, 707 ev = PEERSTORE_create_record_mq_envelope (sub_system, peer, key, value, size,
677 peer, 708 &expiry, options,
678 key,
679 value,
680 size,
681 &expiry,
682 options,
683 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE); 709 GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
684 sc = GNUNET_new (struct GNUNET_PEERSTORE_StoreContext); 710 sc = GNUNET_new (struct GNUNET_PEERSTORE_StoreContext);
711
685 sc->sub_system = GNUNET_strdup (sub_system); 712 sc->sub_system = GNUNET_strdup (sub_system);
686 sc->peer = *peer; 713 sc->peer = *peer;
687 sc->key = GNUNET_strdup (key); 714 sc->key = GNUNET_strdup (key);
@@ -693,12 +720,8 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
693 sc->cont_cls = cont_cls; 720 sc->cont_cls = cont_cls;
694 sc->h = h; 721 sc->h = h;
695 722
696 GNUNET_CONTAINER_DLL_insert_tail (h->store_head, 723 GNUNET_CONTAINER_DLL_insert_tail (h->store_head, h->store_tail, sc);
697 h->store_tail, 724 GNUNET_MQ_notify_sent (ev, &store_request_sent, sc);
698 sc);
699 GNUNET_MQ_notify_sent (ev,
700 &store_request_sent,
701 sc);
702 GNUNET_MQ_send (h->mq, ev); 725 GNUNET_MQ_send (h->mq, ev);
703 return sc; 726 return sc;
704 727
@@ -716,8 +739,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
716 * @param msg message received, NULL on timeout or fatal error 739 * @param msg message received, NULL on timeout or fatal error
717 */ 740 */
718static void 741static void
719handle_iterate_result (void *cls, 742handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg)
720 const struct GNUNET_MessageHeader *msg)
721{ 743{
722 struct GNUNET_PEERSTORE_Handle *h = cls; 744 struct GNUNET_PEERSTORE_Handle *h = cls;
723 struct GNUNET_PEERSTORE_IterateContext *ic; 745 struct GNUNET_PEERSTORE_IterateContext *ic;
@@ -773,31 +795,6 @@ handle_iterate_result (void *cls,
773 795
774 796
775/** 797/**
776 * Called when the iterate request is timedout
777 *
778 * @param cls a `struct GNUNET_PEERSTORE_IterateContext *`
779 * @param tc Scheduler task context (unused)
780 */
781static void
782iterate_timeout (void *cls,
783 const struct GNUNET_SCHEDULER_TaskContext *tc)
784{
785 struct GNUNET_PEERSTORE_IterateContext *ic = cls;
786 GNUNET_PEERSTORE_Processor callback;
787 void *callback_cls;
788
789 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
790 callback = ic->callback;
791 callback_cls = ic->callback_cls;
792 GNUNET_PEERSTORE_iterate_cancel (ic);
793 if (NULL != callback)
794 callback (callback_cls,
795 NULL,
796 _("timeout"));
797}
798
799
800/**
801 * Cancel an iterate request 798 * Cancel an iterate request
802 * Please do not call after the iterate request is done 799 * Please do not call after the iterate request is done
803 * 800 *
@@ -818,9 +815,10 @@ GNUNET_PEERSTORE_iterate_cancel (struct GNUNET_PEERSTORE_IterateContext *ic)
818 GNUNET_MQ_send_cancel (ic->ev); 815 GNUNET_MQ_send_cancel (ic->ev);
819 ic->ev = NULL; 816 ic->ev = NULL;
820 } 817 }
821 GNUNET_CONTAINER_DLL_remove (ic->h->iterate_head, 818 GNUNET_CONTAINER_DLL_remove (ic->h->iterate_head, ic->h->iterate_tail, ic);
822 ic->h->iterate_tail, 819 GNUNET_free (ic->sub_system);
823 ic); 820 if (NULL != ic->key)
821 GNUNET_free (ic->key);
824 GNUNET_free (ic); 822 GNUNET_free (ic);
825 } 823 }
826 else 824 else
@@ -844,8 +842,7 @@ struct GNUNET_PEERSTORE_IterateContext *
844GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h, 842GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
845 const char *sub_system, 843 const char *sub_system,
846 const struct GNUNET_PeerIdentity *peer, 844 const struct GNUNET_PeerIdentity *peer,
847 const char *key, 845 const char *key, struct GNUNET_TIME_Relative timeout,
848 struct GNUNET_TIME_Relative timeout,
849 GNUNET_PEERSTORE_Processor callback, 846 GNUNET_PEERSTORE_Processor callback,
850 void *callback_cls) 847 void *callback_cls)
851{ 848{
@@ -861,10 +858,14 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
861 ic->callback_cls = callback_cls; 858 ic->callback_cls = callback_cls;
862 ic->ev = ev; 859 ic->ev = ev;
863 ic->h = h; 860 ic->h = h;
861 ic->sub_system = GNUNET_strdup (sub_system);
862 if (NULL != peer)
863 ic->peer = *peer;
864 if (NULL != key)
865 ic->key = GNUNET_strdup (key);
866 ic->timeout = timeout;
864 ic->iterating = GNUNET_NO; 867 ic->iterating = GNUNET_NO;
865 GNUNET_CONTAINER_DLL_insert_tail (h->iterate_head, 868 GNUNET_CONTAINER_DLL_insert_tail (h->iterate_head, h->iterate_tail, ic);
866 h->iterate_tail,
867 ic);
868 LOG (GNUNET_ERROR_TYPE_DEBUG, 869 LOG (GNUNET_ERROR_TYPE_DEBUG,
869 "Sending an iterate request for sub system `%s'\n", sub_system); 870 "Sending an iterate request for sub system `%s'\n", sub_system);
870 GNUNET_MQ_notify_sent (ev, &iterate_request_sent, ic); 871 GNUNET_MQ_notify_sent (ev, &iterate_request_sent, ic);
@@ -896,12 +897,12 @@ handle_watch_result (void *cls, const struct GNUNET_MessageHeader *msg)
896 if (NULL == msg) 897 if (NULL == msg)
897 { 898 {
898 LOG (GNUNET_ERROR_TYPE_ERROR, 899 LOG (GNUNET_ERROR_TYPE_ERROR,
899 _("Problem receiving a watch response, no way to determine which request.\n")); 900 _
901 ("Problem receiving a watch response, no way to determine which request.\n"));
900 reconnect (h); 902 reconnect (h);
901 return; 903 return;
902 } 904 }
903 LOG (GNUNET_ERROR_TYPE_DEBUG, 905 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a watch record from service.\n");
904 "Received a watch record from service.\n");
905 record = PEERSTORE_parse_record_message (msg); 906 record = PEERSTORE_parse_record_message (msg);
906 PEERSTORE_hash_key (record->sub_system, record->peer, record->key, &keyhash); 907 PEERSTORE_hash_key (record->sub_system, record->peer, record->key, &keyhash);
907 wc = GNUNET_CONTAINER_multihashmap_get (h->watches, &keyhash); 908 wc = GNUNET_CONTAINER_multihashmap_get (h->watches, &keyhash);