aboutsummaryrefslogtreecommitdiff
path: root/src/arm
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-04-19 18:51:22 +0000
committerChristian Grothoff <christian@grothoff.org>2012-04-19 18:51:22 +0000
commit39e90459cc68f5a33942a1751c6e4b8f85bd25f1 (patch)
treeb73e806c757ea07a52255e71ba1cad2ef57d9b3f /src/arm
parent8e0637f1a72107a8ac1d312ce084644ee27d7981 (diff)
downloadgnunet-39e90459cc68f5a33942a1751c6e4b8f85bd25f1.tar.gz
gnunet-39e90459cc68f5a33942a1751c6e4b8f85bd25f1.zip
-fixes
Diffstat (limited to 'src/arm')
-rw-r--r--src/arm/arm_api.c320
-rw-r--r--src/arm/gnunet-service-arm.c161
-rw-r--r--src/arm/test_exponential_backoff.c82
3 files changed, 261 insertions, 302 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index bb4b355fc..f2992b38a 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -116,16 +116,8 @@ service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg)
116 { 116 {
117 if (shutdown_ctx->cont != NULL) 117 if (shutdown_ctx->cont != NULL)
118 { 118 {
119 if (shutdown_ctx->confirmed == GNUNET_ARM_PROCESS_SHUTDOWN) 119 /* shutdown is now complete, as we waited for the network disconnect... */
120 { 120 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
121 /* shutdown is now complete, as we waited for the network disconnect... */
122 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
123 }
124 else
125 {
126 /* communication error */
127 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
128 }
129 } 121 }
130 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); 122 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
131 GNUNET_CLIENT_disconnect (shutdown_ctx->sock); 123 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
@@ -187,15 +179,14 @@ write_shutdown (void *cls, size_t size, void *buf)
187 179
188 shutdown_ctx->th = NULL; 180 shutdown_ctx->th = NULL;
189 if (size < sizeof (struct GNUNET_MessageHeader)) 181 if (size < sizeof (struct GNUNET_MessageHeader))
190 { 182 {
191 LOG (GNUNET_ERROR_TYPE_WARNING, 183 LOG (GNUNET_ERROR_TYPE_WARNING,
192 _("Failed to transmit shutdown request to client.\n")); 184 _("Failed to transmit shutdown request to client.\n"));
193 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); 185 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
194 GNUNET_CLIENT_disconnect (shutdown_ctx->sock); 186 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
195 GNUNET_free (shutdown_ctx); 187 GNUNET_free (shutdown_ctx);
196 return 0; /* client disconnected */ 188 return 0; /* client disconnected */
197 } 189 }
198
199 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, 190 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler,
200 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); 191 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL);
201 shutdown_ctx->cancel_task = 192 shutdown_ctx->cancel_task =
@@ -349,22 +340,18 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
349 char *lopostfix; 340 char *lopostfix;
350 341
351 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 342 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
352 { 343 {
353#if DEBUG_ARM 344 LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n",
354 LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n", 345 "gnunet-service-arm");
355 "gnunet-service-arm"); 346 /* arm is running! */
356#endif 347 if (pos->callback != NULL)
357 /* arm is running! */ 348 pos->callback (pos->cls, GNUNET_ARM_PROCESS_ALREADY_RUNNING);
358 if (pos->callback != NULL) 349 GNUNET_free (pos);
359 pos->callback (pos->cls, GNUNET_ARM_PROCESS_ALREADY_RUNNING); 350 return;
360 GNUNET_free (pos); 351 }
361 return;
362 }
363#if DEBUG_ARM
364 LOG (GNUNET_ERROR_TYPE_DEBUG, 352 LOG (GNUNET_ERROR_TYPE_DEBUG,
365 "Looks like `%s' is not running, will start it.\n", 353 "Looks like `%s' is not running, will start it.\n",
366 "gnunet-service-arm"); 354 "gnunet-service-arm");
367#endif
368 if (GNUNET_OK != 355 if (GNUNET_OK !=
369 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "PREFIX", 356 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "PREFIX",
370 &loprefix)) 357 &loprefix))
@@ -376,33 +363,33 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
376 if (GNUNET_OK != 363 if (GNUNET_OK !=
377 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "BINARY", 364 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "BINARY",
378 &binary)) 365 &binary))
379 { 366 {
380 LOG (GNUNET_ERROR_TYPE_WARNING, 367 LOG (GNUNET_ERROR_TYPE_WARNING,
381 _ 368 _
382 ("Configuration failes to specify option `%s' in section `%s'!\n"), 369 ("Configuration failes to specify option `%s' in section `%s'!\n"),
383 "BINARY", "arm"); 370 "BINARY", "arm");
384 if (pos->callback != NULL) 371 if (pos->callback != NULL)
385 pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN); 372 pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN);
386 GNUNET_free (pos); 373 GNUNET_free (pos);
387 GNUNET_free (loprefix); 374 GNUNET_free (loprefix);
388 GNUNET_free (lopostfix); 375 GNUNET_free (lopostfix);
389 return; 376 return;
390 } 377 }
391 if (GNUNET_OK != 378 if (GNUNET_OK !=
392 GNUNET_CONFIGURATION_get_value_filename (pos->h->cfg, "arm", "CONFIG", 379 GNUNET_CONFIGURATION_get_value_filename (pos->h->cfg, "arm", "CONFIG",
393 &config)) 380 &config))
394 { 381 {
395 LOG (GNUNET_ERROR_TYPE_WARNING, 382 LOG (GNUNET_ERROR_TYPE_WARNING,
396 _("Configuration fails to specify option `%s' in section `%s'!\n"), 383 _("Configuration fails to specify option `%s' in section `%s'!\n"),
397 "CONFIG", "arm"); 384 "CONFIG", "arm");
398 if (pos->callback != NULL) 385 if (pos->callback != NULL)
399 pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN); 386 pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN);
400 GNUNET_free (binary); 387 GNUNET_free (binary);
401 GNUNET_free (pos); 388 GNUNET_free (pos);
402 GNUNET_free (loprefix); 389 GNUNET_free (loprefix);
403 GNUNET_free (lopostfix); 390 GNUNET_free (lopostfix);
404 return; 391 return;
405 } 392 }
406 if ((GNUNET_YES == 393 if ((GNUNET_YES ==
407 GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "WEAKRANDOM")) 394 GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "WEAKRANDOM"))
408 && (GNUNET_YES == 395 && (GNUNET_YES ==
@@ -411,26 +398,26 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
411 && (GNUNET_NO == 398 && (GNUNET_NO ==
412 GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", 399 GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING",
413 "HOSTFILE"))) 400 "HOSTFILE")))
414 { 401 {
415 /* Means we are ONLY running locally */ 402 /* Means we are ONLY running locally */
416 /* we're clearly running a test, don't daemonize */ 403 /* we're clearly running a test, don't daemonize */
417 proc = do_start_process (GNUNET_NO, 404 proc = do_start_process (GNUNET_NO,
418 NULL, loprefix, binary, "-c", config, 405 NULL, loprefix, binary, "-c", config,
419#if DEBUG_ARM 406#if DEBUG_ARM
420 "-L", "DEBUG", 407 "-L", "DEBUG",
421#endif 408#endif
422 /* no daemonization! */ 409 /* no daemonization! */
423 lopostfix, NULL); 410 lopostfix, NULL);
424 } 411 }
425 else 412 else
426 { 413 {
427 proc = do_start_process (GNUNET_NO, 414 proc = do_start_process (GNUNET_NO,
428 NULL, loprefix, binary, "-c", config, 415 NULL, loprefix, binary, "-c", config,
429#if DEBUG_ARM 416#if DEBUG_ARM
430 "-L", "DEBUG", 417 "-L", "DEBUG",
431#endif 418#endif
432 "-d", lopostfix, NULL); 419 "-d", lopostfix, NULL);
433 } 420 }
434 GNUNET_free (binary); 421 GNUNET_free (binary);
435 GNUNET_free (config); 422 GNUNET_free (config);
436 GNUNET_free (loprefix); 423 GNUNET_free (loprefix);
@@ -465,26 +452,24 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
465 452
466 if ((msg == NULL) || 453 if ((msg == NULL) ||
467 (ntohs (msg->size) != sizeof (struct GNUNET_ARM_ResultMessage))) 454 (ntohs (msg->size) != sizeof (struct GNUNET_ARM_ResultMessage)))
468 { 455 {
469 LOG (GNUNET_ERROR_TYPE_WARNING, 456 LOG (GNUNET_ERROR_TYPE_WARNING,
470 _ 457 _
471 ("Error receiving response to `%s' request from ARM for service `%s'\n"), 458 ("Error receiving response to `%s' request from ARM for service `%s'\n"),
472 (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) ? "START" : "STOP", 459 (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) ? "START" : "STOP",
473 (const char *) &sc[1]); 460 (const char *) &sc[1]);
474 GNUNET_CLIENT_disconnect (sc->h->client); 461 GNUNET_CLIENT_disconnect (sc->h->client);
475 sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg); 462 sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg);
476 GNUNET_assert (NULL != sc->h->client); 463 GNUNET_assert (NULL != sc->h->client);
477 if (sc->callback != NULL) 464 if (sc->callback != NULL)
478 sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR); 465 sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
479 GNUNET_free (sc); 466 GNUNET_free (sc);
480 return; 467 return;
481 } 468 }
482 res = (const struct GNUNET_ARM_ResultMessage *) msg; 469 res = (const struct GNUNET_ARM_ResultMessage *) msg;
483#if DEBUG_ARM
484 LOG (GNUNET_ERROR_TYPE_DEBUG, 470 LOG (GNUNET_ERROR_TYPE_DEBUG,
485 "Received response from ARM for service `%s': %u\n", 471 "Received response from ARM for service `%s': %u\n",
486 (const char *) &sc[1], ntohs (msg->type)); 472 (const char *) &sc[1], ntohs (msg->type));
487#endif
488 status = (enum GNUNET_ARM_ProcessStatus) ntohl (res->status); 473 status = (enum GNUNET_ARM_ProcessStatus) ntohl (res->status);
489 if (sc->callback != NULL) 474 if (sc->callback != NULL)
490 sc->callback (sc->cls, status); 475 sc->callback (sc->cls, status);
@@ -514,19 +499,17 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name,
514 slen = strlen (service_name) + 1; 499 slen = strlen (service_name) + 1;
515 if (slen + sizeof (struct GNUNET_MessageHeader) >= 500 if (slen + sizeof (struct GNUNET_MessageHeader) >=
516 GNUNET_SERVER_MAX_MESSAGE_SIZE) 501 GNUNET_SERVER_MAX_MESSAGE_SIZE)
517 { 502 {
518 GNUNET_break (0); 503 GNUNET_break (0);
519 if (cb != NULL) 504 if (cb != NULL)
520 cb (cb_cls, GNUNET_NO); 505 cb (cb_cls, GNUNET_NO);
521 return; 506 return;
522 } 507 }
523#if DEBUG_ARM
524 LOG (GNUNET_ERROR_TYPE_DEBUG, 508 LOG (GNUNET_ERROR_TYPE_DEBUG,
525 (type == 509 (type ==
526 GNUNET_MESSAGE_TYPE_ARM_START) ? 510 GNUNET_MESSAGE_TYPE_ARM_START) ?
527 _("Requesting start of service `%s'.\n") : 511 _("Requesting start of service `%s'.\n") :
528 _("Requesting termination of service `%s'.\n"), service_name); 512 _("Requesting termination of service `%s'.\n"), service_name);
529#endif
530 sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen); 513 sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen);
531 sctx->h = h; 514 sctx->h = h;
532 sctx->callback = cb; 515 sctx->callback = cb;
@@ -543,20 +526,19 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name,
543 GNUNET_TIME_absolute_get_remaining 526 GNUNET_TIME_absolute_get_remaining
544 (sctx->timeout), GNUNET_YES, 527 (sctx->timeout), GNUNET_YES,
545 &handle_response, sctx)) 528 &handle_response, sctx))
546 { 529 {
547 LOG (GNUNET_ERROR_TYPE_WARNING, 530 LOG (GNUNET_ERROR_TYPE_WARNING,
548 (type == 531 (type ==
549 GNUNET_MESSAGE_TYPE_ARM_START) ? 532 GNUNET_MESSAGE_TYPE_ARM_START)
550 _("Error while trying to transmit request to start `%s' to ARM\n") 533 ? _("Error while trying to transmit request to start `%s' to ARM\n")
551 : 534 : _("Error while trying to transmit request to stop `%s' to ARM\n"),
552 _("Error while trying to transmit request to stop `%s' to ARM\n"), 535 (const char *) &service_name);
553 (const char *) &service_name); 536 if (cb != NULL)
554 if (cb != NULL) 537 cb (cb_cls, GNUNET_SYSERR);
555 cb (cb_cls, GNUNET_SYSERR); 538 GNUNET_free (sctx);
556 GNUNET_free (sctx); 539 GNUNET_free (msg);
557 GNUNET_free (msg); 540 return;
558 return; 541 }
559 }
560 GNUNET_free (msg); 542 GNUNET_free (msg);
561} 543}
562 544
@@ -580,38 +562,36 @@ GNUNET_ARM_start_service (struct GNUNET_ARM_Handle *h,
580 struct GNUNET_CLIENT_Connection *client; 562 struct GNUNET_CLIENT_Connection *client;
581 size_t slen; 563 size_t slen;
582 564
583#if DEBUG_ARM
584 LOG (GNUNET_ERROR_TYPE_DEBUG, 565 LOG (GNUNET_ERROR_TYPE_DEBUG,
585 _("Asked to start service `%s' within %llu ms\n"), service_name, 566 _("Asked to start service `%s' within %llu ms\n"), service_name,
586 (unsigned long long) timeout.rel_value); 567 (unsigned long long) timeout.rel_value);
587#endif
588 if (0 == strcasecmp ("arm", service_name)) 568 if (0 == strcasecmp ("arm", service_name))
589 { 569 {
590 slen = strlen ("arm") + 1; 570 slen = strlen ("arm") + 1;
591 sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen); 571 sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen);
592 sctx->h = h; 572 sctx->h = h;
593 sctx->callback = cb; 573 sctx->callback = cb;
594 sctx->cls = cb_cls; 574 sctx->cls = cb_cls;
595 sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); 575 sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
596 memcpy (&sctx[1], service_name, slen); 576 memcpy (&sctx[1], service_name, slen);
597 GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report, 577 GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report,
598 sctx); 578 sctx);
599 return; 579 return;
600 } 580 }
601 if (h->client == NULL) 581 if (h->client == NULL)
582 {
583 client = GNUNET_CLIENT_connect ("arm", h->cfg);
584 if (client == NULL)
602 { 585 {
603 client = GNUNET_CLIENT_connect ("arm", h->cfg);
604 if (client == NULL)
605 {
606 LOG (GNUNET_ERROR_TYPE_DEBUG,
607 "arm_api, GNUNET_CLIENT_connect returned NULL\n");
608 cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
609 return;
610 }
611 LOG (GNUNET_ERROR_TYPE_DEBUG, 586 LOG (GNUNET_ERROR_TYPE_DEBUG,
612 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); 587 "arm_api, GNUNET_CLIENT_connect returned NULL\n");
613 h->client = client; 588 cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
589 return;
614 } 590 }
591 LOG (GNUNET_ERROR_TYPE_DEBUG,
592 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n");
593 h->client = client;
594 }
615 LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, h->client non-NULL\n"); 595 LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, h->client non-NULL\n");
616 change_service (h, service_name, timeout, cb, cb_cls, 596 change_service (h, service_name, timeout, cb, cb_cls,
617 GNUNET_MESSAGE_TYPE_ARM_START); 597 GNUNET_MESSAGE_TYPE_ARM_START);
@@ -658,25 +638,25 @@ GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h,
658 LOG (GNUNET_ERROR_TYPE_INFO, _("Stopping service `%s' within %llu ms\n"), 638 LOG (GNUNET_ERROR_TYPE_INFO, _("Stopping service `%s' within %llu ms\n"),
659 service_name, (unsigned long long) timeout.rel_value); 639 service_name, (unsigned long long) timeout.rel_value);
660 if (h->client == NULL) 640 if (h->client == NULL)
641 {
642 client = GNUNET_CLIENT_connect ("arm", h->cfg);
643 if (client == NULL)
661 { 644 {
662 client = GNUNET_CLIENT_connect ("arm", h->cfg); 645 cb (cb_cls, GNUNET_SYSERR);
663 if (client == NULL)
664 {
665 cb (cb_cls, GNUNET_SYSERR);
666 return;
667 }
668 h->client = client;
669 }
670 if (0 == strcasecmp ("arm", service_name))
671 {
672 arm_shutdown_ctx = GNUNET_malloc (sizeof (struct ARM_ShutdownContext));
673 arm_shutdown_ctx->cb = cb;
674 arm_shutdown_ctx->cb_cls = cb_cls;
675 arm_service_shutdown (h->client, timeout, &arm_shutdown_callback,
676 arm_shutdown_ctx);
677 h->client = NULL;
678 return; 646 return;
679 } 647 }
648 h->client = client;
649 }
650 if (0 == strcasecmp ("arm", service_name))
651 {
652 arm_shutdown_ctx = GNUNET_malloc (sizeof (struct ARM_ShutdownContext));
653 arm_shutdown_ctx->cb = cb;
654 arm_shutdown_ctx->cb_cls = cb_cls;
655 arm_service_shutdown (h->client, timeout, &arm_shutdown_callback,
656 arm_shutdown_ctx);
657 h->client = NULL;
658 return;
659 }
680 change_service (h, service_name, timeout, cb, cb_cls, 660 change_service (h, service_name, timeout, cb, cb_cls,
681 GNUNET_MESSAGE_TYPE_ARM_STOP); 661 GNUNET_MESSAGE_TYPE_ARM_STOP);
682} 662}
@@ -799,21 +779,21 @@ GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h,
799 struct GNUNET_MessageHeader msg; 779 struct GNUNET_MessageHeader msg;
800 struct GNUNET_CLIENT_Connection *client; 780 struct GNUNET_CLIENT_Connection *client;
801 781
802 if (h->client == NULL) 782 if (h->client == NULL)
783 {
784 client = GNUNET_CLIENT_connect ("arm", h->cfg);
785 if (client == NULL)
803 { 786 {
804 client = GNUNET_CLIENT_connect ("arm", h->cfg);
805 if (client == NULL)
806 {
807 LOG (GNUNET_ERROR_TYPE_DEBUG,
808 "arm_api, GNUNET_CLIENT_connect returned NULL\n");
809 cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR, 0, NULL);
810 return;
811 }
812 LOG (GNUNET_ERROR_TYPE_DEBUG, 787 LOG (GNUNET_ERROR_TYPE_DEBUG,
813 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); 788 "arm_api, GNUNET_CLIENT_connect returned NULL\n");
814 h->client = client; 789 cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR, 0, NULL);
790 return;
815 } 791 }
816 792 LOG (GNUNET_ERROR_TYPE_DEBUG,
793 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n");
794 h->client = client;
795 }
796
817 sctx = GNUNET_malloc (sizeof (struct RequestContext)); 797 sctx = GNUNET_malloc (sizeof (struct RequestContext));
818 sctx->h = h; 798 sctx->h = h;
819 sctx->callback = cb; 799 sctx->callback = cb;
@@ -826,7 +806,7 @@ GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h,
826 "Requesting LIST from ARM service with timeout: %llu ms\n", 806 "Requesting LIST from ARM service with timeout: %llu ms\n",
827 (unsigned long long)timeout.rel_value); 807 (unsigned long long)timeout.rel_value);
828 808
829 if (GNUNET_OK != 809 if (GNUNET_OK !=
830 GNUNET_CLIENT_transmit_and_get_response (sctx->h->client, 810 GNUNET_CLIENT_transmit_and_get_response (sctx->h->client,
831 &msg, 811 &msg,
832 GNUNET_TIME_absolute_get_remaining 812 GNUNET_TIME_absolute_get_remaining
@@ -834,14 +814,14 @@ GNUNET_ARM_list_running_services (struct GNUNET_ARM_Handle *h,
834 GNUNET_YES, 814 GNUNET_YES,
835 &handle_list_response, 815 &handle_list_response,
836 sctx)) 816 sctx))
837 { 817 {
838 LOG (GNUNET_ERROR_TYPE_WARNING, 818 LOG (GNUNET_ERROR_TYPE_WARNING,
839 "Error while trying to transmit request to list services to ARM\n"); 819 "Error while trying to transmit request to list services to ARM\n");
840 if (cb != NULL) 820 if (cb != NULL)
841 cb (cb_cls, GNUNET_SYSERR, 0, NULL); 821 cb (cb_cls, GNUNET_SYSERR, 0, NULL);
842 GNUNET_free (sctx); 822 GNUNET_free (sctx);
843 return; 823 return;
844 } 824 }
845} 825}
846 826
847/* end of arm_api.c */ 827/* end of arm_api.c */
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index 091d5ae54..b1fab4872 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -314,11 +314,9 @@ start_process (struct ServiceList *sl)
314 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG"); 314 use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG");
315 315
316 /* actually start process */ 316 /* actually start process */
317#if DEBUG_ARM
318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
319 "Starting service `%s' using binary `%s' and configuration `%s'\n", 318 "Starting service `%s' using binary `%s' and configuration `%s'\n",
320 sl->name, sl->binary, sl->config); 319 sl->name, sl->binary, sl->config);
321#endif
322 GNUNET_assert (NULL == sl->proc); 320 GNUNET_assert (NULL == sl->proc);
323 if (GNUNET_YES == use_debug) 321 if (GNUNET_YES == use_debug)
324 sl->proc = 322 sl->proc =
@@ -363,10 +361,8 @@ write_result (void *cls, size_t size, void *buf)
363 _("Could not send status result to client\n")); 361 _("Could not send status result to client\n"));
364 return 0; /* error, not much we can do */ 362 return 0; /* error, not much we can do */
365 } 363 }
366#if DEBUG_ARM
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 364 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
368 "Sending status response %u to client\n", (unsigned int) *res); 365 "Sending status response %u to client\n", (unsigned int) *res);
369#endif
370 GNUNET_assert (size >= sizeof (struct GNUNET_ARM_ResultMessage)); 366 GNUNET_assert (size >= sizeof (struct GNUNET_ARM_ResultMessage));
371 msg = buf; 367 msg = buf;
372 msg->header.size = htons (sizeof (struct GNUNET_ARM_ResultMessage)); 368 msg->header.size = htons (sizeof (struct GNUNET_ARM_ResultMessage));
@@ -695,11 +691,9 @@ handle_stop (void *cls, struct GNUNET_SERVER_Client *client,
695 signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_DOWN); 691 signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_DOWN);
696 return; 692 return;
697 } 693 }
698#if DEBUG_ARM
699 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
700 "Sending kill signal to service `%s', waiting for process to die.\n", 695 "Sending kill signal to service `%s', waiting for process to die.\n",
701 servicename); 696 servicename);
702#endif
703 sl->killed_at = GNUNET_TIME_absolute_get (); 697 sl->killed_at = GNUNET_TIME_absolute_get ();
704 if (0 != GNUNET_OS_process_kill (sl->proc, SIGTERM)) 698 if (0 != GNUNET_OS_process_kill (sl->proc, SIGTERM))
705 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 699 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
@@ -799,47 +793,47 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
799 struct ServiceListeningInfo *sli; 793 struct ServiceListeningInfo *sli;
800 794
801 if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) 795 if (GNUNET_SCHEDULER_NO_TASK != child_restart_task)
802 { 796 {
803 GNUNET_SCHEDULER_cancel (child_restart_task); 797 GNUNET_SCHEDULER_cancel (child_restart_task);
804 child_restart_task = GNUNET_SCHEDULER_NO_TASK; 798 child_restart_task = GNUNET_SCHEDULER_NO_TASK;
805 } 799 }
806 in_shutdown = GNUNET_YES; 800 in_shutdown = GNUNET_YES;
807 /* first, stop listening */ 801 /* first, stop listening */
808 for (pos = running_head; NULL != pos; pos = pos->next) 802 for (pos = running_head; NULL != pos; pos = pos->next)
809 { 803 {
810 while (NULL != (sli = pos->listen_head)) 804 while (NULL != (sli = pos->listen_head))
811 { 805 {
812 GNUNET_CONTAINER_DLL_remove (pos->listen_head, 806 GNUNET_CONTAINER_DLL_remove (pos->listen_head,
813 pos->listen_tail, sli); 807 pos->listen_tail, sli);
814 if (sli->accept_task != GNUNET_SCHEDULER_NO_TASK) 808 if (sli->accept_task != GNUNET_SCHEDULER_NO_TASK)
815 { 809 {
816 GNUNET_SCHEDULER_cancel (sli->accept_task); 810 GNUNET_SCHEDULER_cancel (sli->accept_task);
817 sli->accept_task = GNUNET_SCHEDULER_NO_TASK; 811 sli->accept_task = GNUNET_SCHEDULER_NO_TASK;
818 } 812 }
819 GNUNET_break (GNUNET_OK == 813 GNUNET_break (GNUNET_OK ==
820 GNUNET_NETWORK_socket_close (sli->listen_socket)); 814 GNUNET_NETWORK_socket_close (sli->listen_socket));
821 GNUNET_free (sli->service_addr); 815 GNUNET_free (sli->service_addr);
822 GNUNET_free (sli); 816 GNUNET_free (sli);
823 } 817 }
824 } 818 }
825 /* then, shutdown all existing service processes */ 819 /* then, shutdown all existing service processes */
826 nxt = running_head; 820 nxt = running_head;
827 while (NULL != (pos = nxt)) 821 while (NULL != (pos = nxt))
822 {
823 nxt = pos->next;
824 if (pos->proc != NULL)
828 { 825 {
829 nxt = pos->next; 826 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n",
830 if (pos->proc != NULL) 827 pos->name);
831 { 828 pos->killed_at = GNUNET_TIME_absolute_get ();
832 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", 829 if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM))
833 pos->name); 830 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
834 pos->killed_at = GNUNET_TIME_absolute_get (); 831 }
835 if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) 832 else
836 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 833 {
837 } 834 free_service (pos);
838 else
839 {
840 free_service (pos);
841 }
842 } 835 }
836 }
843 /* finally, should all service processes be already gone, terminate for real */ 837 /* finally, should all service processes be already gone, terminate for real */
844 if (running_head == NULL) 838 if (running_head == NULL)
845 do_shutdown (); 839 do_shutdown ();
@@ -869,56 +863,53 @@ delayed_restart_task (void *cls,
869 /* check for services that need to be restarted due to 863 /* check for services that need to be restarted due to
870 * configuration changes or because the last restart failed */ 864 * configuration changes or because the last restart failed */
871 for (sl = running_head; NULL != sl; sl = sl->next) 865 for (sl = running_head; NULL != sl; sl = sl->next)
866 {
867 if (NULL != sl->proc)
868 continue;
869 /* service is currently not running */
870 if (GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value ==
871 0)
872 { 872 {
873 if (sl->proc == NULL) 873 /* restart is now allowed */
874 { 874 if (sl->is_default)
875 /* service is currently not running */ 875 {
876 if (GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value == 876 /* process should run by default, start immediately */
877 0) 877 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
878 { 878 _("Restarting service `%s'.\n"), sl->name);
879 /* restart is now allowed */ 879 start_process (sl);
880 if (sl->is_default) 880 }
881 { 881 else
882 /* process should run by default, start immediately */ 882 {
883 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 883 /* process is run on-demand, ensure it is re-started if there is demand */
884 _("Restarting service `%s'.\n"), sl->name); 884 for (sli = sl->listen_head; NULL != sli; sli = sli->next)
885 start_process (sl); 885 if (GNUNET_SCHEDULER_NO_TASK == sli->accept_task)
886 } 886 {
887 else 887 /* accept was actually paused, so start it again */
888 { 888 sli->accept_task =
889 /* process is run on-demand, ensure it is re-started if there is demand */ 889 GNUNET_SCHEDULER_add_read_net
890 for (sli = sl->listen_head; NULL != sli; sli = sli->next) 890 (GNUNET_TIME_UNIT_FOREVER_REL, sli->listen_socket,
891 if (GNUNET_SCHEDULER_NO_TASK == sli->accept_task) 891 &accept_connection, sli);
892 { 892 }
893 /* accept was actually paused, so start it again */ 893 }
894 sli->accept_task =
895 GNUNET_SCHEDULER_add_read_net
896 (GNUNET_TIME_UNIT_FOREVER_REL, sli->listen_socket,
897 &accept_connection, sli);
898 }
899 }
900 }
901 else
902 {
903 /* update calculation for earliest time to reactivate a service */
904 lowestRestartDelay =
905 GNUNET_TIME_relative_min (lowestRestartDelay,
906 GNUNET_TIME_absolute_get_remaining
907 (sl->restart_at));
908 }
909 }
910 } 894 }
911 if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) 895 else
912 { 896 {
913#if DEBUG_ARM 897 /* update calculation for earliest time to reactivate a service */
914 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will restart process in %llums\n", 898 lowestRestartDelay =
915 (unsigned long long) lowestRestartDelay.rel_value); 899 GNUNET_TIME_relative_min (lowestRestartDelay,
916#endif 900 GNUNET_TIME_absolute_get_remaining
917 child_restart_task = 901 (sl->restart_at));
918 GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay,
919 GNUNET_SCHEDULER_PRIORITY_IDLE,
920 &delayed_restart_task, NULL);
921 } 902 }
903 }
904 if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
905 {
906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will restart process in %llums\n",
907 (unsigned long long) lowestRestartDelay.rel_value);
908 child_restart_task =
909 GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay,
910 GNUNET_SCHEDULER_PRIORITY_IDLE,
911 &delayed_restart_task, NULL);
912 }
922} 913}
923 914
924 915
diff --git a/src/arm/test_exponential_backoff.c b/src/arm/test_exponential_backoff.c
index 15756657f..77bd9e2ce 100644
--- a/src/arm/test_exponential_backoff.c
+++ b/src/arm/test_exponential_backoff.c
@@ -113,59 +113,47 @@ service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg)
113{ 113{
114 struct ShutdownContext *shutdown_ctx = cls; 114 struct ShutdownContext *shutdown_ctx = cls;
115 115
116 if ((msg == NULL) && (shutdown_ctx->confirmed != GNUNET_YES)) 116 if (msg == NULL)
117 { 117 {
118 /* Means the other side closed the connection and never confirmed a shutdown */
119 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
120 "Service handle shutdown before ACK!\n");
121 if (shutdown_ctx->cont != NULL)
122 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR);
123 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
124 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
125 GNUNET_free (shutdown_ctx);
126 }
127 else if ((msg == NULL) && (shutdown_ctx->confirmed == GNUNET_YES))
128 {
129#if VERBOSE 118#if VERBOSE
130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); 119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n");
131#endif 120#endif
132 if (shutdown_ctx->cont != NULL) 121 if (shutdown_ctx->cont != NULL)
133 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_NO); 122 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_NO);
134 123
135 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); 124 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
136 GNUNET_CLIENT_disconnect (shutdown_ctx->sock); 125 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
137 GNUNET_free (shutdown_ctx); 126 GNUNET_free (shutdown_ctx);
138 } 127 return;
139 else 128 }
140 { 129 GNUNET_assert (ntohs (msg->size) ==
141 GNUNET_assert (ntohs (msg->size) == 130 sizeof (struct GNUNET_MessageHeader));
142 sizeof (struct GNUNET_MessageHeader)); 131 switch (ntohs (msg->type))
143 switch (ntohs (msg->type)) 132 {
144 { 133 case GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN:
145 case GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN:
146#if VERBOSE 134#if VERBOSE
147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148 "Received confirmation for service shutdown.\n"); 136 "Received confirmation for service shutdown.\n");
149#endif 137#endif
150 shutdown_ctx->confirmed = GNUNET_YES; 138 shutdown_ctx->confirmed = GNUNET_YES;
151 GNUNET_CLIENT_receive (shutdown_ctx->sock, 139 GNUNET_CLIENT_receive (shutdown_ctx->sock,
152 &service_shutdown_handler, shutdown_ctx, 140 &service_shutdown_handler, shutdown_ctx,
153 GNUNET_TIME_UNIT_FOREVER_REL); 141 GNUNET_TIME_UNIT_FOREVER_REL);
154 break; 142 break;
155 default: /* Fall through */ 143 default: /* Fall through */
156 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 144 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
157 "Service shutdown refused!\n"); 145 "Service shutdown refused!\n");
158 if (shutdown_ctx->cont != NULL) 146 if (shutdown_ctx->cont != NULL)
159 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_YES); 147 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_YES);
160 148
161 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); 149 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
162 GNUNET_CLIENT_disconnect (shutdown_ctx->sock); 150 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
163 GNUNET_free (shutdown_ctx); 151 GNUNET_free (shutdown_ctx);
164 break; 152 break;
165 } 153 }
166 }
167} 154}
168 155
156
169/** 157/**
170 * Shutting down took too long, cancel receive and return error. 158 * Shutting down took too long, cancel receive and return error.
171 * 159 *