aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/peerstore/peerstore_api.c140
-rw-r--r--src/transport/transport_api2_address.c2
2 files changed, 100 insertions, 42 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 */
260static void
261reconnect (void *cls);
262
263
264/**
265 * Disconnect from the peerstore service.
266 *
267 * @param h peerstore handle to disconnect
268 */
269static void
270disconnect (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 */
250static void 308static void
251reconnect (struct GNUNET_PEERSTORE_Handle *h); 309disconnect_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 */
347static void 419static void
348do_disconnect (struct GNUNET_PEERSTORE_Handle *h) 420final_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 */
749static void 826static void
750reconnect (struct GNUNET_PEERSTORE_Handle *h) 827reconnect (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,
diff --git a/src/transport/transport_api2_address.c b/src/transport/transport_api2_address.c
index 1ae1e5b1e..1ff599efb 100644
--- a/src/transport/transport_api2_address.c
+++ b/src/transport/transport_api2_address.c
@@ -123,7 +123,7 @@ reconnect (void *cls)
123/** 123/**
124 * Disconnect from the transport service. 124 * Disconnect from the transport service.
125 * 125 *
126 * @param h transport service to reconnect 126 * @param h transport service to disconnect
127 */ 127 */
128static void 128static void
129disconnect (struct GNUNET_TRANSPORT_AddressHandle *h) 129disconnect (struct GNUNET_TRANSPORT_AddressHandle *h)