aboutsummaryrefslogtreecommitdiff
path: root/src/arm/arm_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/arm_api.c')
-rw-r--r--src/arm/arm_api.c446
1 files changed, 217 insertions, 229 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index c15c59875..12395fea9 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -84,12 +84,13 @@ struct ShutdownContext
84 void *cont_cls; 84 void *cont_cls;
85 85
86 /** 86 /**
87 * We received a confirmation that the service will shut down. 87 * Result of the operation
88 */ 88 */
89 int confirmed; 89 enum GNUNET_ARM_ProcessStatus confirmed;
90 90
91}; 91};
92 92
93
93/** 94/**
94 * Handler receiving response to service shutdown requests. 95 * Handler receiving response to service shutdown requests.
95 * First call with NULL: service misbehaving, or something. 96 * First call with NULL: service misbehaving, or something.
@@ -105,76 +106,61 @@ static void
105service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) 106service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg)
106{ 107{
107 struct ShutdownContext *shutdown_ctx = cls; 108 struct ShutdownContext *shutdown_ctx = cls;
109 const struct GNUNET_ARM_ResultMessage *rmsg;
108 110
109 if ((msg == NULL) && (shutdown_ctx->confirmed != GNUNET_YES)) 111 if (msg == NULL)
110 {
111#if DEBUG_ARM
112 /* Means the other side closed the connection and never confirmed a shutdown */
113 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service handle shutdown before ACK!\n");
114#endif
115 if (shutdown_ctx->cont != NULL)
116 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR);
117 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
118 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO);
119 GNUNET_free (shutdown_ctx);
120 }
121 else if ((msg == NULL) && (shutdown_ctx->confirmed == GNUNET_YES))
122 { 112 {
123#if DEBUG_ARM
124 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n");
125#endif
126 if (shutdown_ctx->cont != NULL) 113 if (shutdown_ctx->cont != NULL)
127 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_NO); 114 {
128 115 if (shutdown_ctx->confirmed == GNUNET_ARM_PROCESS_SHUTDOWN)
116 {
117 /* shutdown is now complete, as we waited for the network disconnect... */
118 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_DOWN);
119 }
120 else
121 {
122 /* communication error */
123 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
124 }
125 }
129 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); 126 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
130 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); 127 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO);
131 GNUNET_free (shutdown_ctx); 128 GNUNET_free (shutdown_ctx);
129 return;
132 } 130 }
133 else 131 if (ntohs (msg->size) ==
132 sizeof (struct GNUNET_ARM_ResultMessage))
134 { 133 {
135 GNUNET_assert (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader)); 134 rmsg = (const struct GNUNET_ARM_ResultMessage*) msg;
136 switch (ntohs (msg->type)) 135 shutdown_ctx->confirmed = (enum GNUNET_ARM_ProcessStatus) ntohl (rmsg->status);
136 if (shutdown_ctx->confirmed != GNUNET_ARM_PROCESS_SHUTDOWN)
137 { 137 {
138 case GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN_ACK: 138 /* ARM is not shutting down, well, report the error and be done with it... */
139#if DEBUG_ARM 139 shutdown_ctx->cont (shutdown_ctx->cont_cls, shutdown_ctx->confirmed);
140 LOG (GNUNET_ERROR_TYPE_DEBUG,
141 "Received confirmation for service shutdown.\n");
142#endif
143 shutdown_ctx->confirmed = GNUNET_YES;
144 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler,
145 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL);
146 break;
147 default:
148#if DEBUG_ARM
149 LOG (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown refused!\n");
150#endif
151 if (shutdown_ctx->cont != NULL)
152 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_YES);
153
154 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task); 140 GNUNET_SCHEDULER_cancel (shutdown_ctx->cancel_task);
155 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); 141 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO);
156 GNUNET_free (shutdown_ctx); 142 GNUNET_free (shutdown_ctx);
157 break; 143 return;
158 } 144 }
159 } 145 }
146 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler,
147 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL);
160} 148}
161 149
150
162/** 151/**
163 * Shutting down took too long, cancel receive and return error. 152 * Shutting down took too long, cancel receive and return error.
164 * 153 *
165 * @param cls closure 154 * @param cls closure
166 * @param tc context information (why was this task triggered now) 155 * @param tc context information (why was this task triggered now)
167 */ 156 */
168void 157static void
169service_shutdown_cancel (void *cls, 158service_shutdown_cancel (void *cls,
170 const struct GNUNET_SCHEDULER_TaskContext *tc) 159 const struct GNUNET_SCHEDULER_TaskContext *tc)
171{ 160{
172 struct ShutdownContext *shutdown_ctx = cls; 161 struct ShutdownContext *shutdown_ctx = cls;
173 162
174#if DEBUG_ARM 163 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_TIMEOUT);
175 LOG (GNUNET_ERROR_TYPE_DEBUG, "service_shutdown_cancel called!\n");
176#endif
177 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR);
178 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); 164 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO);
179 GNUNET_free (shutdown_ctx); 165 GNUNET_free (shutdown_ctx);
180} 166}
@@ -196,21 +182,21 @@ write_shutdown (void *cls, size_t size, void *buf)
196 struct ShutdownContext *shutdown_ctx = cls; 182 struct ShutdownContext *shutdown_ctx = cls;
197 183
198 if (size < sizeof (struct GNUNET_MessageHeader)) 184 if (size < sizeof (struct GNUNET_MessageHeader))
199 { 185 {
200 LOG (GNUNET_ERROR_TYPE_WARNING, 186 LOG (GNUNET_ERROR_TYPE_WARNING,
201 _("Failed to transmit shutdown request to client.\n")); 187 _("Failed to transmit shutdown request to client.\n"));
202 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); 188 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
203 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO); 189 GNUNET_CLIENT_disconnect (shutdown_ctx->sock, GNUNET_NO);
204 GNUNET_free (shutdown_ctx); 190 GNUNET_free (shutdown_ctx);
205 return 0; /* client disconnected */ 191 return 0; /* client disconnected */
206 } 192 }
207 193
208 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler, 194 GNUNET_CLIENT_receive (shutdown_ctx->sock, &service_shutdown_handler,
209 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL); 195 shutdown_ctx, GNUNET_TIME_UNIT_FOREVER_REL);
210 shutdown_ctx->cancel_task = 196 shutdown_ctx->cancel_task =
211 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining 197 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
212 (shutdown_ctx->timeout), 198 (shutdown_ctx->timeout),
213 &service_shutdown_cancel, shutdown_ctx); 199 &service_shutdown_cancel, shutdown_ctx);
214 msg = (struct GNUNET_MessageHeader *) buf; 200 msg = (struct GNUNET_MessageHeader *) buf;
215 msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN); 201 msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN);
216 msg->size = htons (sizeof (struct GNUNET_MessageHeader)); 202 msg->size = htons (sizeof (struct GNUNET_MessageHeader));
@@ -233,8 +219,8 @@ write_shutdown (void *cls, size_t size, void *buf)
233 */ 219 */
234static void 220static void
235arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock, 221arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock,
236 struct GNUNET_TIME_Relative timeout, 222 struct GNUNET_TIME_Relative timeout,
237 GNUNET_CLIENT_ShutdownTask cont, void *cont_cls) 223 GNUNET_CLIENT_ShutdownTask cont, void *cont_cls)
238{ 224{
239 struct ShutdownContext *shutdown_ctx; 225 struct ShutdownContext *shutdown_ctx;
240 226
@@ -243,10 +229,12 @@ arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock,
243 shutdown_ctx->cont_cls = cont_cls; 229 shutdown_ctx->cont_cls = cont_cls;
244 shutdown_ctx->sock = sock; 230 shutdown_ctx->sock = sock;
245 shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); 231 shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
232 shutdown_ctx->confirmed = GNUNET_ARM_PROCESS_COMMUNICATION_ERROR;
233 /* FIXME: store return value? */
246 GNUNET_CLIENT_notify_transmit_ready (sock, 234 GNUNET_CLIENT_notify_transmit_ready (sock,
247 sizeof (struct GNUNET_MessageHeader), 235 sizeof (struct GNUNET_MessageHeader),
248 timeout, GNUNET_YES, &write_shutdown, 236 timeout, GNUNET_YES, &write_shutdown,
249 shutdown_ctx); 237 shutdown_ctx);
250} 238}
251 239
252 240
@@ -262,7 +250,7 @@ arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock,
262 */ 250 */
263struct GNUNET_ARM_Handle * 251struct GNUNET_ARM_Handle *
264GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 252GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
265 const char *service) 253 const char *service)
266{ 254{
267 struct GNUNET_ARM_Handle *ret; 255 struct GNUNET_ARM_Handle *ret;
268 256
@@ -286,6 +274,7 @@ GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h)
286 GNUNET_free (h); 274 GNUNET_free (h);
287} 275}
288 276
277
289struct ARM_ShutdownContext 278struct ARM_ShutdownContext
290{ 279{
291 /** 280 /**
@@ -300,7 +289,6 @@ struct ARM_ShutdownContext
300}; 289};
301 290
302 291
303
304/** 292/**
305 * Internal state for a request with ARM. 293 * Internal state for a request with ARM.
306 */ 294 */
@@ -357,17 +345,17 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
357 char *lopostfix; 345 char *lopostfix;
358 346
359 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) 347 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
360 { 348 {
361#if DEBUG_ARM 349#if DEBUG_ARM
362 LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n", 350 LOG (GNUNET_ERROR_TYPE_DEBUG, "Looks like `%s' is already running.\n",
363 "gnunet-service-arm"); 351 "gnunet-service-arm");
364#endif 352#endif
365 /* arm is running! */ 353 /* arm is running! */
366 if (pos->callback != NULL) 354 if (pos->callback != NULL)
367 pos->callback (pos->cls, GNUNET_YES); 355 pos->callback (pos->cls, GNUNET_ARM_PROCESS_ALREADY_RUNNING);
368 GNUNET_free (pos); 356 GNUNET_free (pos);
369 return; 357 return;
370 } 358 }
371#if DEBUG_ARM 359#if DEBUG_ARM
372 LOG (GNUNET_ERROR_TYPE_DEBUG, 360 LOG (GNUNET_ERROR_TYPE_DEBUG,
373 "Looks like `%s' is not running, will start it.\n", 361 "Looks like `%s' is not running, will start it.\n",
@@ -375,73 +363,81 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
375#endif 363#endif
376 if (GNUNET_OK != 364 if (GNUNET_OK !=
377 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "PREFIX", 365 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "PREFIX",
378 &loprefix)) 366 &loprefix))
379 loprefix = GNUNET_strdup (""); 367 loprefix = GNUNET_strdup ("");
380 if (GNUNET_OK != 368 if (GNUNET_OK !=
381 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "OPTIONS", 369 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "OPTIONS",
382 &lopostfix)) 370 &lopostfix))
383 lopostfix = GNUNET_strdup (""); 371 lopostfix = GNUNET_strdup ("");
384 if (GNUNET_OK != 372 if (GNUNET_OK !=
385 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "BINARY", 373 GNUNET_CONFIGURATION_get_value_string (pos->h->cfg, "arm", "BINARY",
386 &binary)) 374 &binary))
387 { 375 {
388 LOG (GNUNET_ERROR_TYPE_WARNING, 376 LOG (GNUNET_ERROR_TYPE_WARNING,
389 _("Configuration failes to specify option `%s' in section `%s'!\n"), 377 _
390 "BINARY", "arm"); 378 ("Configuration failes to specify option `%s' in section `%s'!\n"),
391 if (pos->callback != NULL) 379 "BINARY", "arm");
392 pos->callback (pos->cls, GNUNET_SYSERR); 380 if (pos->callback != NULL)
393 GNUNET_free (pos); 381 pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN);
394 GNUNET_free (loprefix); 382 GNUNET_free (pos);
395 GNUNET_free (lopostfix); 383 GNUNET_free (loprefix);
396 return; 384 GNUNET_free (lopostfix);
397 } 385 return;
386 }
398 if (GNUNET_OK != 387 if (GNUNET_OK !=
399 GNUNET_CONFIGURATION_get_value_filename (pos->h->cfg, "arm", "CONFIG", 388 GNUNET_CONFIGURATION_get_value_filename (pos->h->cfg, "arm", "CONFIG",
400 &config)) 389 &config))
401 { 390 {
402 LOG (GNUNET_ERROR_TYPE_WARNING, 391 LOG (GNUNET_ERROR_TYPE_WARNING,
403 _("Configuration fails to specify option `%s' in section `%s'!\n"), 392 _("Configuration fails to specify option `%s' in section `%s'!\n"),
404 "CONFIG", "arm"); 393 "CONFIG", "arm");
405 if (pos->callback != NULL) 394 if (pos->callback != NULL)
406 pos->callback (pos->cls, GNUNET_SYSERR); 395 pos->callback (pos->cls, GNUNET_ARM_PROCESS_UNKNOWN);
407 GNUNET_free (binary); 396 GNUNET_free (binary);
408 GNUNET_free (pos); 397 GNUNET_free (pos);
409 GNUNET_free (loprefix); 398 GNUNET_free (loprefix);
410 GNUNET_free (lopostfix); 399 GNUNET_free (lopostfix);
411 return; 400 return;
412 } 401 }
413 if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (pos->h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_NO == GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "HOSTFILE")) /* Means we are ONLY running locally */ 402 if ((GNUNET_YES ==
414 ) 403 GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING", "WEAKRANDOM"))
415 { 404 && (GNUNET_YES ==
416 /* we're clearly running a test, don't daemonize */ 405 GNUNET_CONFIGURATION_get_value_yesno (pos->h->cfg, "TESTING",
417 proc = do_start_process (NULL, loprefix, binary, "-c", config, 406 "WEAKRANDOM"))
407 && (GNUNET_NO ==
408 GNUNET_CONFIGURATION_have_value (pos->h->cfg, "TESTING",
409 "HOSTFILE")))
410 {
411 /* Means we are ONLY running locally */
412 /* we're clearly running a test, don't daemonize */
413 proc = do_start_process (NULL, loprefix, binary, "-c", config,
418#if DEBUG_ARM 414#if DEBUG_ARM
419 "-L", "DEBUG", 415 "-L", "DEBUG",
420#endif 416#endif
421 /* no daemonization! */ 417 /* no daemonization! */
422 lopostfix, NULL); 418 lopostfix, NULL);
423 } 419 }
424 else 420 else
425 { 421 {
426 proc = do_start_process (NULL, loprefix, binary, "-c", config, 422 proc = do_start_process (NULL, loprefix, binary, "-c", config,
427#if DEBUG_ARM 423#if DEBUG_ARM
428 "-L", "DEBUG", 424 "-L", "DEBUG",
429#endif 425#endif
430 "-d", lopostfix, NULL); 426 "-d", lopostfix, NULL);
431 } 427 }
432 GNUNET_free (binary); 428 GNUNET_free (binary);
433 GNUNET_free (config); 429 GNUNET_free (config);
434 GNUNET_free (loprefix); 430 GNUNET_free (loprefix);
435 GNUNET_free (lopostfix); 431 GNUNET_free (lopostfix);
436 if (proc == NULL) 432 if (proc == NULL)
437 { 433 {
438 if (pos->callback != NULL) 434 if (pos->callback != NULL)
439 pos->callback (pos->cls, GNUNET_SYSERR); 435 pos->callback (pos->cls, GNUNET_ARM_PROCESS_FAILURE);
440 GNUNET_free (pos); 436 GNUNET_free (pos);
441 return; 437 return;
442 } 438 }
443 if (pos->callback != NULL) 439 if (pos->callback != NULL)
444 pos->callback (pos->cls, GNUNET_YES); 440 pos->callback (pos->cls, GNUNET_ARM_PROCESS_STARTING);
445 GNUNET_free (proc); 441 GNUNET_free (proc);
446 GNUNET_free (pos); 442 GNUNET_free (pos);
447} 443}
@@ -458,45 +454,34 @@ static void
458handle_response (void *cls, const struct GNUNET_MessageHeader *msg) 454handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
459{ 455{
460 struct RequestContext *sc = cls; 456 struct RequestContext *sc = cls;
461 int ret; 457 const struct GNUNET_ARM_ResultMessage *res;
458 enum GNUNET_ARM_ProcessStatus status;
462 459
463 if (msg == NULL) 460 if ((msg == NULL) ||
464 { 461 (ntohs (msg->size) != sizeof (struct GNUNET_ARM_ResultMessage)))
465 LOG (GNUNET_ERROR_TYPE_WARNING, 462 {
466 _ 463 LOG (GNUNET_ERROR_TYPE_WARNING,
467 ("Error receiving response to `%s' request from ARM for service `%s'\n"), 464 _
468 (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) ? "START" : "STOP", 465 ("Error receiving response to `%s' request from ARM for service `%s'\n"),
469 (const char *) &sc[1]); 466 (sc->type == GNUNET_MESSAGE_TYPE_ARM_START) ? "START" : "STOP",
470 GNUNET_CLIENT_disconnect (sc->h->client, GNUNET_NO); 467 (const char *) &sc[1]);
471 sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg); 468 GNUNET_CLIENT_disconnect (sc->h->client, GNUNET_NO);
472 GNUNET_assert (NULL != sc->h->client); 469 sc->h->client = GNUNET_CLIENT_connect ("arm", sc->h->cfg);
473 if (sc->callback != NULL) 470 GNUNET_assert (NULL != sc->h->client);
474 sc->callback (sc->cls, GNUNET_SYSERR); 471 if (sc->callback != NULL)
475 GNUNET_free (sc); 472 sc->callback (sc->cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
476 return; 473 GNUNET_free (sc);
477 } 474 return;
475 }
476 res = (const struct GNUNET_ARM_ResultMessage *) msg;
478#if DEBUG_ARM 477#if DEBUG_ARM
479 LOG (GNUNET_ERROR_TYPE_DEBUG, 478 LOG (GNUNET_ERROR_TYPE_DEBUG,
480 "Received response from ARM for service `%s': %u\n", 479 "Received response from ARM for service `%s': %u\n",
481 (const char *) &sc[1], ntohs (msg->type)); 480 (const char *) &sc[1], ntohs (msg->type));
482#endif 481#endif
483 switch (ntohs (msg->type)) 482 status = (enum GNUNET_ARM_ProcessStatus) ntohl (res->status);
484 {
485 case GNUNET_MESSAGE_TYPE_ARM_IS_UP:
486 ret = GNUNET_YES;
487 break;
488 case GNUNET_MESSAGE_TYPE_ARM_IS_DOWN:
489 ret = GNUNET_NO;
490 break;
491 case GNUNET_MESSAGE_TYPE_ARM_IS_UNKNOWN:
492 ret = GNUNET_SYSERR;
493 break;
494 default:
495 GNUNET_break (0);
496 ret = GNUNET_SYSERR;
497 }
498 if (sc->callback != NULL) 483 if (sc->callback != NULL)
499 sc->callback (sc->cls, ret); 484 sc->callback (sc->cls, status);
500 GNUNET_free (sc); 485 GNUNET_free (sc);
501} 486}
502 487
@@ -513,8 +498,8 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg)
513 */ 498 */
514static void 499static void
515change_service (struct GNUNET_ARM_Handle *h, const char *service_name, 500change_service (struct GNUNET_ARM_Handle *h, const char *service_name,
516 struct GNUNET_TIME_Relative timeout, GNUNET_ARM_Callback cb, 501 struct GNUNET_TIME_Relative timeout, GNUNET_ARM_Callback cb,
517 void *cb_cls, uint16_t type) 502 void *cb_cls, uint16_t type)
518{ 503{
519 struct RequestContext *sctx; 504 struct RequestContext *sctx;
520 size_t slen; 505 size_t slen;
@@ -523,16 +508,16 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name,
523 slen = strlen (service_name) + 1; 508 slen = strlen (service_name) + 1;
524 if (slen + sizeof (struct GNUNET_MessageHeader) >= 509 if (slen + sizeof (struct GNUNET_MessageHeader) >=
525 GNUNET_SERVER_MAX_MESSAGE_SIZE) 510 GNUNET_SERVER_MAX_MESSAGE_SIZE)
526 { 511 {
527 GNUNET_break (0); 512 GNUNET_break (0);
528 if (cb != NULL) 513 if (cb != NULL)
529 cb (cb_cls, GNUNET_NO); 514 cb (cb_cls, GNUNET_NO);
530 return; 515 return;
531 } 516 }
532#if DEBUG_ARM 517#if DEBUG_ARM
533 LOG (GNUNET_ERROR_TYPE_DEBUG, 518 LOG (GNUNET_ERROR_TYPE_DEBUG,
534 (type == 519 (type ==
535 GNUNET_MESSAGE_TYPE_ARM_START) ? 520 GNUNET_MESSAGE_TYPE_ARM_START) ?
536 _("Requesting start of service `%s'.\n") : 521 _("Requesting start of service `%s'.\n") :
537 _("Requesting termination of service `%s'.\n"), service_name); 522 _("Requesting termination of service `%s'.\n"), service_name);
538#endif 523#endif
@@ -549,22 +534,23 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name,
549 memcpy (&msg[1], service_name, slen); 534 memcpy (&msg[1], service_name, slen);
550 if (GNUNET_OK != 535 if (GNUNET_OK !=
551 GNUNET_CLIENT_transmit_and_get_response (sctx->h->client, msg, 536 GNUNET_CLIENT_transmit_and_get_response (sctx->h->client, msg,
552 GNUNET_TIME_absolute_get_remaining 537 GNUNET_TIME_absolute_get_remaining
553 (sctx->timeout), GNUNET_YES, 538 (sctx->timeout), GNUNET_YES,
554 &handle_response, sctx)) 539 &handle_response, sctx))
555 { 540 {
556 LOG (GNUNET_ERROR_TYPE_WARNING, 541 LOG (GNUNET_ERROR_TYPE_WARNING,
557 (type == 542 (type ==
558 GNUNET_MESSAGE_TYPE_ARM_START) ? 543 GNUNET_MESSAGE_TYPE_ARM_START) ?
559 _("Error while trying to transmit request to start `%s' to ARM\n") : 544 _("Error while trying to transmit request to start `%s' to ARM\n")
560 _("Error while trying to transmit request to stop `%s' to ARM\n"), 545 :
561 (const char *) &service_name); 546 _("Error while trying to transmit request to stop `%s' to ARM\n"),
562 if (cb != NULL) 547 (const char *) &service_name);
563 cb (cb_cls, GNUNET_SYSERR); 548 if (cb != NULL)
564 GNUNET_free (sctx); 549 cb (cb_cls, GNUNET_SYSERR);
565 GNUNET_free (msg); 550 GNUNET_free (sctx);
566 return; 551 GNUNET_free (msg);
567 } 552 return;
553 }
568 GNUNET_free (msg); 554 GNUNET_free (msg);
569} 555}
570 556
@@ -579,9 +565,10 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name,
579 * @param cb_cls closure for callback 565 * @param cb_cls closure for callback
580 */ 566 */
581void 567void
582GNUNET_ARM_start_service (struct GNUNET_ARM_Handle *h, const char *service_name, 568GNUNET_ARM_start_service (struct GNUNET_ARM_Handle *h,
583 struct GNUNET_TIME_Relative timeout, 569 const char *service_name,
584 GNUNET_ARM_Callback cb, void *cb_cls) 570 struct GNUNET_TIME_Relative timeout,
571 GNUNET_ARM_Callback cb, void *cb_cls)
585{ 572{
586 struct RequestContext *sctx; 573 struct RequestContext *sctx;
587 struct GNUNET_CLIENT_Connection *client; 574 struct GNUNET_CLIENT_Connection *client;
@@ -593,47 +580,47 @@ GNUNET_ARM_start_service (struct GNUNET_ARM_Handle *h, const char *service_name,
593 (unsigned long long) timeout.rel_value); 580 (unsigned long long) timeout.rel_value);
594#endif 581#endif
595 if (0 == strcasecmp ("arm", service_name)) 582 if (0 == strcasecmp ("arm", service_name))
596 { 583 {
597 slen = strlen ("arm") + 1; 584 slen = strlen ("arm") + 1;
598 sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen); 585 sctx = GNUNET_malloc (sizeof (struct RequestContext) + slen);
599 sctx->h = h; 586 sctx->h = h;
600 sctx->callback = cb; 587 sctx->callback = cb;
601 sctx->cls = cb_cls; 588 sctx->cls = cb_cls;
602 sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); 589 sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
603 memcpy (&sctx[1], service_name, slen); 590 memcpy (&sctx[1], service_name, slen);
604 GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report, 591 GNUNET_CLIENT_service_test ("arm", h->cfg, timeout, &arm_service_report,
605 sctx); 592 sctx);
606 return; 593 return;
607 } 594 }
608 if (h->client == NULL) 595 if (h->client == NULL)
609 {
610 client = GNUNET_CLIENT_connect ("arm", h->cfg);
611 if (client == NULL)
612 { 596 {
597 client = GNUNET_CLIENT_connect ("arm", h->cfg);
598 if (client == NULL)
599 {
600 LOG (GNUNET_ERROR_TYPE_DEBUG,
601 "arm_api, GNUNET_CLIENT_connect returned NULL\n");
602 cb (cb_cls, GNUNET_ARM_PROCESS_COMMUNICATION_ERROR);
603 return;
604 }
613 LOG (GNUNET_ERROR_TYPE_DEBUG, 605 LOG (GNUNET_ERROR_TYPE_DEBUG,
614 "arm_api, GNUNET_CLIENT_connect returned NULL\n"); 606 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n");
615 cb (cb_cls, GNUNET_SYSERR); 607 h->client = client;
616 return;
617 } 608 }
618 LOG (GNUNET_ERROR_TYPE_DEBUG,
619 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n");
620 h->client = client;
621 }
622 LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, h->client non-NULL\n"); 609 LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, h->client non-NULL\n");
623 change_service (h, service_name, timeout, cb, cb_cls, 610 change_service (h, service_name, timeout, cb, cb_cls,
624 GNUNET_MESSAGE_TYPE_ARM_START); 611 GNUNET_MESSAGE_TYPE_ARM_START);
625} 612}
626 613
614
627/** 615/**
628 * Callback from the arm stop service call, indicates that the arm service 616 * Callback from the arm stop service call, indicates that the arm service
629 * is well and truly dead, won't die, or an error occurred. 617 * is well and truly dead, won't die, or an error occurred.
630 * 618 *
631 * @param cls closure for the callback 619 * @param cls closure for the callback
632 * @param reason reason for callback, GNUNET_NO if arm is shutdown 620 * @param reason reason for callback
633 * GNUNET_YES if arm remains running, and GNUNET_SYSERR on error
634 */ 621 */
635void 622static void
636arm_shutdown_callback (void *cls, int reason) 623arm_shutdown_callback (void *cls, enum GNUNET_ARM_ProcessStatus reason)
637{ 624{
638 struct ARM_ShutdownContext *arm_shutdown_ctx = cls; 625 struct ARM_ShutdownContext *arm_shutdown_ctx = cls;
639 626
@@ -654,9 +641,10 @@ arm_shutdown_callback (void *cls, int reason)
654 * @param cb_cls closure for callback 641 * @param cb_cls closure for callback
655 */ 642 */
656void 643void
657GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h, const char *service_name, 644GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h,
658 struct GNUNET_TIME_Relative timeout, 645 const char *service_name,
659 GNUNET_ARM_Callback cb, void *cb_cls) 646 struct GNUNET_TIME_Relative timeout,
647 GNUNET_ARM_Callback cb, void *cb_cls)
660{ 648{
661 struct ARM_ShutdownContext *arm_shutdown_ctx; 649 struct ARM_ShutdownContext *arm_shutdown_ctx;
662 struct GNUNET_CLIENT_Connection *client; 650 struct GNUNET_CLIENT_Connection *client;
@@ -664,27 +652,27 @@ GNUNET_ARM_stop_service (struct GNUNET_ARM_Handle *h, const char *service_name,
664 LOG (GNUNET_ERROR_TYPE_INFO, _("Stopping service `%s' within %llu ms\n"), 652 LOG (GNUNET_ERROR_TYPE_INFO, _("Stopping service `%s' within %llu ms\n"),
665 service_name, (unsigned long long) timeout.rel_value); 653 service_name, (unsigned long long) timeout.rel_value);
666 if (h->client == NULL) 654 if (h->client == NULL)
667 {
668 client = GNUNET_CLIENT_connect ("arm", h->cfg);
669 if (client == NULL)
670 { 655 {
671 cb (cb_cls, GNUNET_SYSERR); 656 client = GNUNET_CLIENT_connect ("arm", h->cfg);
672 return; 657 if (client == NULL)
658 {
659 cb (cb_cls, GNUNET_SYSERR);
660 return;
661 }
662 h->client = client;
673 } 663 }
674 h->client = client;
675 }
676 if (0 == strcasecmp ("arm", service_name)) 664 if (0 == strcasecmp ("arm", service_name))
677 { 665 {
678 arm_shutdown_ctx = GNUNET_malloc (sizeof (struct ARM_ShutdownContext)); 666 arm_shutdown_ctx = GNUNET_malloc (sizeof (struct ARM_ShutdownContext));
679 arm_shutdown_ctx->cb = cb; 667 arm_shutdown_ctx->cb = cb;
680 arm_shutdown_ctx->cb_cls = cb_cls; 668 arm_shutdown_ctx->cb_cls = cb_cls;
681 arm_service_shutdown (h->client, timeout, &arm_shutdown_callback, 669 arm_service_shutdown (h->client, timeout, &arm_shutdown_callback,
682 arm_shutdown_ctx); 670 arm_shutdown_ctx);
683 h->client = NULL; 671 h->client = NULL;
684 return; 672 return;
685 } 673 }
686 change_service (h, service_name, timeout, cb, cb_cls, 674 change_service (h, service_name, timeout, cb, cb_cls,
687 GNUNET_MESSAGE_TYPE_ARM_STOP); 675 GNUNET_MESSAGE_TYPE_ARM_STOP);
688} 676}
689 677
690 678