diff options
Diffstat (limited to 'src/peerstore/peerstore_api.c')
-rw-r--r-- | src/peerstore/peerstore_api.c | 140 |
1 files changed, 99 insertions, 41 deletions
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c index 6abdef43a..243e26c8b 100644 --- a/src/peerstore/peerstore_api.c +++ b/src/peerstore/peerstore_api.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
@@ -76,6 +76,16 @@ struct GNUNET_PEERSTORE_Handle | |||
76 | struct GNUNET_CONTAINER_MultiHashMap *watches; | 76 | struct GNUNET_CONTAINER_MultiHashMap *watches; |
77 | 77 | ||
78 | /** | 78 | /** |
79 | * ID of the task trying to reconnect to the service. | ||
80 | */ | ||
81 | struct GNUNET_SCHEDULER_Task *reconnect_task; | ||
82 | |||
83 | /** | ||
84 | * Delay until we try to reconnect. | ||
85 | */ | ||
86 | struct GNUNET_TIME_Relative reconnect_delay; | ||
87 | |||
88 | /** | ||
79 | * Are we in the process of disconnecting but need to sync first? | 89 | * Are we in the process of disconnecting but need to sync first? |
80 | */ | 90 | */ |
81 | int disconnecting; | 91 | int disconnecting; |
@@ -245,10 +255,72 @@ struct GNUNET_PEERSTORE_WatchContext | |||
245 | /** | 255 | /** |
246 | * Close the existing connection to PEERSTORE and reconnect. | 256 | * Close the existing connection to PEERSTORE and reconnect. |
247 | * | 257 | * |
248 | * @param h handle to the service | 258 | * @param cls a `struct GNUNET_PEERSTORE_Handle *h` |
259 | */ | ||
260 | static void | ||
261 | reconnect (void *cls); | ||
262 | |||
263 | |||
264 | /** | ||
265 | * Disconnect from the peerstore service. | ||
266 | * | ||
267 | * @param h peerstore handle to disconnect | ||
268 | */ | ||
269 | static void | ||
270 | disconnect (struct GNUNET_PEERSTORE_Handle *h) | ||
271 | { | ||
272 | struct GNUNET_PEERSTORE_IterateContext *next; | ||
273 | |||
274 | for (struct GNUNET_PEERSTORE_IterateContext *ic = h->iterate_head; | ||
275 | NULL != ic; | ||
276 | ic = next) | ||
277 | { | ||
278 | next = ic->next; | ||
279 | if (GNUNET_YES == ic->iterating) | ||
280 | { | ||
281 | GNUNET_PEERSTORE_Processor icb; | ||
282 | void *icb_cls; | ||
283 | |||
284 | icb = ic->callback; | ||
285 | icb_cls = ic->callback_cls; | ||
286 | GNUNET_PEERSTORE_iterate_cancel (ic); | ||
287 | if (NULL != icb) | ||
288 | icb (icb_cls, | ||
289 | NULL, | ||
290 | "Iteration canceled due to reconnection"); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | if (NULL != h->mq) | ||
295 | { | ||
296 | GNUNET_MQ_destroy (h->mq); | ||
297 | h->mq = NULL; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | |||
302 | /** | ||
303 | * Function that will schedule the job that will try | ||
304 | * to connect us again to the client. | ||
305 | * | ||
306 | * @param h peerstore to reconnect | ||
249 | */ | 307 | */ |
250 | static void | 308 | static void |
251 | reconnect (struct GNUNET_PEERSTORE_Handle *h); | 309 | disconnect_and_schedule_reconnect (struct GNUNET_PEERSTORE_Handle *h) |
310 | { | ||
311 | GNUNET_assert (NULL == h->reconnect_task); | ||
312 | disconnect (h); | ||
313 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
314 | "Scheduling task to reconnect to PEERSTORE service in %s.\n", | ||
315 | GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, | ||
316 | GNUNET_YES)); | ||
317 | h->reconnect_task = | ||
318 | GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, | ||
319 | &reconnect, | ||
320 | h); | ||
321 | h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); | ||
322 | } | ||
323 | |||
252 | 324 | ||
253 | 325 | ||
254 | /** | 326 | /** |
@@ -288,7 +360,7 @@ handle_client_error (void *cls, | |||
288 | LOG (GNUNET_ERROR_TYPE_ERROR, | 360 | LOG (GNUNET_ERROR_TYPE_ERROR, |
289 | "Received an error notification from MQ of type: %d\n", | 361 | "Received an error notification from MQ of type: %d\n", |
290 | error); | 362 | error); |
291 | reconnect (h); | 363 | disconnect_and_schedule_reconnect (h); |
292 | } | 364 | } |
293 | 365 | ||
294 | 366 | ||
@@ -345,7 +417,7 @@ destroy_watch (void *cls, | |||
345 | * @param h Handle to the service. | 417 | * @param h Handle to the service. |
346 | */ | 418 | */ |
347 | static void | 419 | static void |
348 | do_disconnect (struct GNUNET_PEERSTORE_Handle *h) | 420 | final_disconnect (struct GNUNET_PEERSTORE_Handle *h) |
349 | { | 421 | { |
350 | if (NULL != h->mq) | 422 | if (NULL != h->mq) |
351 | { | 423 | { |
@@ -419,7 +491,7 @@ GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h, | |||
419 | while (NULL != (sc = h->store_head)) | 491 | while (NULL != (sc = h->store_head)) |
420 | GNUNET_PEERSTORE_store_cancel (sc); | 492 | GNUNET_PEERSTORE_store_cancel (sc); |
421 | } | 493 | } |
422 | do_disconnect (h); | 494 | final_disconnect (h); |
423 | } | 495 | } |
424 | 496 | ||
425 | 497 | ||
@@ -443,8 +515,9 @@ GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc) | |||
443 | GNUNET_free (sc->value); | 515 | GNUNET_free (sc->value); |
444 | GNUNET_free (sc->key); | 516 | GNUNET_free (sc->key); |
445 | GNUNET_free (sc); | 517 | GNUNET_free (sc); |
446 | if ((GNUNET_YES == h->disconnecting) && (NULL == h->store_head)) | 518 | if ( (GNUNET_YES == h->disconnecting) && |
447 | do_disconnect (h); | 519 | (NULL == h->store_head) ) |
520 | final_disconnect (h); | ||
448 | } | 521 | } |
449 | 522 | ||
450 | 523 | ||
@@ -530,7 +603,7 @@ handle_iterate_end (void *cls, | |||
530 | { | 603 | { |
531 | LOG (GNUNET_ERROR_TYPE_ERROR, | 604 | LOG (GNUNET_ERROR_TYPE_ERROR, |
532 | _("Unexpected iteration response, this should not happen.\n")); | 605 | _("Unexpected iteration response, this should not happen.\n")); |
533 | reconnect (h); | 606 | disconnect_and_schedule_reconnect (h); |
534 | return; | 607 | return; |
535 | } | 608 | } |
536 | callback = ic->callback; | 609 | callback = ic->callback; |
@@ -538,7 +611,10 @@ handle_iterate_end (void *cls, | |||
538 | ic->iterating = GNUNET_NO; | 611 | ic->iterating = GNUNET_NO; |
539 | GNUNET_PEERSTORE_iterate_cancel (ic); | 612 | GNUNET_PEERSTORE_iterate_cancel (ic); |
540 | if (NULL != callback) | 613 | if (NULL != callback) |
541 | callback (callback_cls, NULL, NULL); | 614 | callback (callback_cls, |
615 | NULL, | ||
616 | NULL); | ||
617 | h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; | ||
542 | } | 618 | } |
543 | 619 | ||
544 | 620 | ||
@@ -579,7 +655,7 @@ handle_iterate_result (void *cls, | |||
579 | { | 655 | { |
580 | LOG (GNUNET_ERROR_TYPE_ERROR, | 656 | LOG (GNUNET_ERROR_TYPE_ERROR, |
581 | _("Unexpected iteration response, this should not happen.\n")); | 657 | _("Unexpected iteration response, this should not happen.\n")); |
582 | reconnect (h); | 658 | disconnect_and_schedule_reconnect (h); |
583 | return; | 659 | return; |
584 | } | 660 | } |
585 | ic->iterating = GNUNET_YES; | 661 | ic->iterating = GNUNET_YES; |
@@ -715,7 +791,7 @@ handle_watch_record (void *cls, | |||
715 | record = PEERSTORE_parse_record_message (msg); | 791 | record = PEERSTORE_parse_record_message (msg); |
716 | if (NULL == record) | 792 | if (NULL == record) |
717 | { | 793 | { |
718 | reconnect (h); | 794 | disconnect_and_schedule_reconnect (h); |
719 | return; | 795 | return; |
720 | } | 796 | } |
721 | PEERSTORE_hash_key (record->sub_system, | 797 | PEERSTORE_hash_key (record->sub_system, |
@@ -730,13 +806,14 @@ handle_watch_record (void *cls, | |||
730 | LOG (GNUNET_ERROR_TYPE_ERROR, | 806 | LOG (GNUNET_ERROR_TYPE_ERROR, |
731 | _("Received a watch result for a non existing watch.\n")); | 807 | _("Received a watch result for a non existing watch.\n")); |
732 | PEERSTORE_destroy_record (record); | 808 | PEERSTORE_destroy_record (record); |
733 | reconnect (h); | 809 | disconnect_and_schedule_reconnect (h); |
734 | return; | 810 | return; |
735 | } | 811 | } |
736 | if (NULL != wc->callback) | 812 | if (NULL != wc->callback) |
737 | wc->callback (wc->callback_cls, | 813 | wc->callback (wc->callback_cls, |
738 | record, | 814 | record, |
739 | NULL); | 815 | NULL); |
816 | h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; | ||
740 | PEERSTORE_destroy_record (record); | 817 | PEERSTORE_destroy_record (record); |
741 | } | 818 | } |
742 | 819 | ||
@@ -744,11 +821,12 @@ handle_watch_record (void *cls, | |||
744 | /** | 821 | /** |
745 | * Close the existing connection to PEERSTORE and reconnect. | 822 | * Close the existing connection to PEERSTORE and reconnect. |
746 | * | 823 | * |
747 | * @param h handle to the service | 824 | * @param cls a `struct GNUNET_PEERSTORE_Handle *` |
748 | */ | 825 | */ |
749 | static void | 826 | static void |
750 | reconnect (struct GNUNET_PEERSTORE_Handle *h) | 827 | reconnect (void *cls) |
751 | { | 828 | { |
829 | struct GNUNET_PEERSTORE_Handle *h = cls; | ||
752 | struct GNUNET_MQ_MessageHandler mq_handlers[] = { | 830 | struct GNUNET_MQ_MessageHandler mq_handlers[] = { |
753 | GNUNET_MQ_hd_fixed_size (iterate_end, | 831 | GNUNET_MQ_hd_fixed_size (iterate_end, |
754 | GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END, | 832 | GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END, |
@@ -764,34 +842,10 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h) | |||
764 | h), | 842 | h), |
765 | GNUNET_MQ_handler_end () | 843 | GNUNET_MQ_handler_end () |
766 | }; | 844 | }; |
767 | struct GNUNET_PEERSTORE_IterateContext *ic; | ||
768 | struct GNUNET_PEERSTORE_IterateContext *next; | ||
769 | GNUNET_PEERSTORE_Processor icb; | ||
770 | void *icb_cls; | ||
771 | struct GNUNET_PEERSTORE_StoreContext *sc; | ||
772 | struct GNUNET_MQ_Envelope *ev; | 845 | struct GNUNET_MQ_Envelope *ev; |
773 | 846 | ||
774 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 847 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
775 | "Reconnecting...\n"); | 848 | "Reconnecting...\n"); |
776 | for (ic = h->iterate_head; NULL != ic; ic = next) | ||
777 | { | ||
778 | next = ic->next; | ||
779 | if (GNUNET_YES == ic->iterating) | ||
780 | { | ||
781 | icb = ic->callback; | ||
782 | icb_cls = ic->callback_cls; | ||
783 | GNUNET_PEERSTORE_iterate_cancel (ic); | ||
784 | if (NULL != icb) | ||
785 | icb (icb_cls, | ||
786 | NULL, | ||
787 | "Iteration canceled due to reconnection"); | ||
788 | } | ||
789 | } | ||
790 | if (NULL != h->mq) | ||
791 | { | ||
792 | GNUNET_MQ_destroy (h->mq); | ||
793 | h->mq = NULL; | ||
794 | } | ||
795 | h->mq = GNUNET_CLIENT_connect (h->cfg, | 849 | h->mq = GNUNET_CLIENT_connect (h->cfg, |
796 | "peerstore", | 850 | "peerstore", |
797 | mq_handlers, | 851 | mq_handlers, |
@@ -805,7 +859,9 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h) | |||
805 | GNUNET_CONTAINER_multihashmap_iterate (h->watches, | 859 | GNUNET_CONTAINER_multihashmap_iterate (h->watches, |
806 | &rewatch_it, | 860 | &rewatch_it, |
807 | h); | 861 | h); |
808 | for (ic = h->iterate_head; NULL != ic; ic = ic->next) | 862 | for (struct GNUNET_PEERSTORE_IterateContext *ic = h->iterate_head; |
863 | NULL != ic; | ||
864 | ic = ic->next) | ||
809 | { | 865 | { |
810 | ev = PEERSTORE_create_record_mq_envelope (ic->sub_system, | 866 | ev = PEERSTORE_create_record_mq_envelope (ic->sub_system, |
811 | &ic->peer, | 867 | &ic->peer, |
@@ -816,7 +872,9 @@ reconnect (struct GNUNET_PEERSTORE_Handle *h) | |||
816 | GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); | 872 | GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE); |
817 | GNUNET_MQ_send (h->mq, ev); | 873 | GNUNET_MQ_send (h->mq, ev); |
818 | } | 874 | } |
819 | for (sc = h->store_head; NULL != sc; sc = sc->next) | 875 | for (struct GNUNET_PEERSTORE_StoreContext *sc = h->store_head; |
876 | NULL != sc; | ||
877 | sc = sc->next) | ||
820 | { | 878 | { |
821 | ev = PEERSTORE_create_record_mq_envelope (sc->sub_system, | 879 | ev = PEERSTORE_create_record_mq_envelope (sc->sub_system, |
822 | &sc->peer, | 880 | &sc->peer, |