GNUnet 0.22.2
arm_api.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2012, 2013, 2016, 2019 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_arm_service.h"
30#include "gnunet_protocols.h"
31#include "arm.h"
32
33#define LOG(kind, ...) GNUNET_log_from (kind, "arm-api", __VA_ARGS__)
34
35
41{
46
51
56
61
66
70 void *cont_cls;
71
76
80 uint64_t id;
81
86
91
96};
97
98
103{
108
113
118
123
128
133
143
148
153
159
164};
165
166
175
176
182static void
184{
185 struct GNUNET_ARM_Handle *h = cls;
186
187 h->reconnect_task = NULL;
189}
190
191
198static void
200{
201 struct GNUNET_ARM_Operation *op;
202
203 if (NULL != h->mq)
204 {
206 h->mq = NULL;
207 }
209 GNUNET_assert (NULL == h->reconnect_task);
213 h);
214 while (NULL != (op = h->operation_pending_head))
215 {
216 if (NULL != op->result_cont)
219 0);
220 if (NULL != op->list_cont)
223 0,
224 NULL);
226 }
229 if (NULL != h->conn_status)
231 GNUNET_NO);
232}
233
234
242static struct GNUNET_ARM_Operation *
244 uint64_t id)
245{
247 NULL != result;
248 result = result->next)
249 if (id == result->id)
250 return result;
251 return NULL;
252}
253
254
261static void
263 const struct GNUNET_ARM_ResultMessage *res)
264{
265 struct GNUNET_ARM_Handle *h = cls;
266 struct GNUNET_ARM_Operation *op;
267 uint64_t id;
270 void *result_cont_cls;
271
272 id = GNUNET_ntohll (res->arm_msg.request_id);
273 op = find_op_by_id (h,
274 id);
275 if (NULL == op)
276 {
278 "Message with unknown id %llu\n",
279 (unsigned long long) id);
280 return;
281 }
282
283 result = ntohl (res->result);
284 if ( (GNUNET_YES == op->is_arm_stop) &&
286 {
287 /* special case: if we are stopping 'gnunet-service-arm', we do not just
288 wait for the result message, but also wait for the service to close
289 the connection (and then we have to close our client handle as well);
290 this is done by installing a different receive handler, waiting for
291 the connection to go down */if (NULL != h->thm)
292 {
293 GNUNET_break (0);
297 GNUNET_free (h->thm);
298 }
301 op);
302 h->thm = op;
303 return;
304 }
306 result_cont_cls = op->cont_cls;
308 if (NULL != result_cont)
309 result_cont (result_cont_cls,
311 result);
312}
313
314
324static const char *
325pool_get (const char *pool_start,
326 size_t pool_size,
327 size_t str_index)
328{
329 const char *str_start;
330 const char *end;
331
332 if (str_index >= pool_size)
333 return NULL;
334 str_start = pool_start + str_index;
335 end = memchr (str_start, 0, pool_size - str_index);
336 if (NULL == end)
337 return NULL;
338 return str_start;
339}
340
341
351 const struct GNUNET_ARM_ListResultMessage *lres)
352{
353 uint16_t rcount = ntohs (lres->count);
354 uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof(*lres);
356 size_t pool_size;
357 char *pool_start;
358
359 (void) cls;
360 if ((rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage) > msize))
361 {
362 GNUNET_break_op (0);
363 return GNUNET_NO;
364 }
365 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &lres[1];
366 pool_start = (char *) (ssm + rcount);
367 pool_size = msize - (rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage));
368 for (unsigned int i = 0; i < rcount; i++)
369 {
370 uint16_t name_index = ntohs (ssm->name_index);
371 uint16_t binary_index = ntohs (ssm->binary_index);
372 if (NULL == pool_get (pool_start,
373 pool_size,
374 name_index))
375 {
376 GNUNET_break_op (0);
377 return GNUNET_NO;
378 }
379 if (NULL == pool_get (pool_start,
380 pool_size,
382 {
383 GNUNET_break_op (0);
384 return GNUNET_NO;
385 }
386 ssm++;
387 }
388 return GNUNET_OK;
389}
390
391
398static void
400 const struct GNUNET_ARM_ListResultMessage *lres)
401{
402 struct GNUNET_ARM_Handle *h = cls;
403 uint16_t rcount = ntohs (lres->count);
404 uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof(*lres);
405 struct GNUNET_ARM_ServiceInfo list[rcount];
407 struct GNUNET_ARM_Operation *op;
408 uint64_t id;
409 size_t pool_size;
410 char *pool_start;
411
412 id = GNUNET_ntohll (lres->arm_msg.request_id);
413 op = find_op_by_id (h, id);
414 if (NULL == op)
415 {
417 "Message with unknown id %llu\n",
418 (unsigned long long) id);
419 return;
420 }
421
422 GNUNET_assert ((rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage) <=
423 msize));
424
425 ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &lres[1];
426 pool_start = (char *) (ssm + rcount);
427 pool_size = msize - (rcount * sizeof (struct GNUNET_ARM_ServiceInfoMessage));
428
429 for (unsigned int i = 0; i < rcount; i++)
430 {
431 uint16_t name_index = ntohs (ssm->name_index);
432 uint16_t binary_index = ntohs (ssm->binary_index);
433 const char *name;
434 const char *binary;
435
436 name = pool_get (pool_start, pool_size, name_index);
437 binary = pool_get (pool_start, pool_size, binary_index);
438 GNUNET_assert (NULL != name);
439 GNUNET_assert (NULL != binary);
440 list[i] = (struct GNUNET_ARM_ServiceInfo) {
441 .name = name,
442 .binary = binary,
443 .status = ntohl (ssm->status),
444 .last_started_at = GNUNET_TIME_absolute_ntoh (ssm->last_started_at),
445 .restart_at = GNUNET_TIME_absolute_ntoh (ssm->restart_at),
446 .last_exit_status = ntohs (ssm->last_exit_status),
447 };
448 ssm++;
449 }
450 if (NULL != op->list_cont)
453 rcount,
454 list);
456}
457
458
465static void
466handle_confirm (void *cls,
467 const struct GNUNET_MessageHeader *msg)
468{
469 struct GNUNET_ARM_Handle *h = cls;
470
471 (void) msg;
473 "Got confirmation from ARM that we are up!\n");
474 if (GNUNET_NO == h->currently_up)
475 {
477 if (NULL != h->conn_status)
479 }
480}
481
482
491static void
493 enum GNUNET_MQ_Error error)
494{
495 struct GNUNET_ARM_Handle *h = cls;
496 struct GNUNET_ARM_Operation *op;
497
498 (void) error;
500 if (NULL != (op = h->thm))
501 {
502 h->thm = NULL;
506 GNUNET_free (op);
507 }
509}
510
511
520{
522 GNUNET_MQ_hd_fixed_size (arm_result,
525 h),
526 GNUNET_MQ_hd_var_size (arm_list_result,
529 h),
533 h),
535 };
536 struct GNUNET_MessageHeader *test;
537 struct GNUNET_MQ_Envelope *env;
538
539 if (NULL != h->mq)
540 return GNUNET_OK;
543 "arm",
544 handlers,
546 h);
547 if (NULL == h->mq)
548 {
550 "GNUNET_CLIENT_connect returned NULL\n");
551 if (NULL != h->conn_status)
554 return GNUNET_SYSERR;
555 }
557 "Sending TEST message to ARM\n");
558 env = GNUNET_MQ_msg (test,
561 return GNUNET_OK;
562}
563
564
576struct GNUNET_ARM_Handle *
578 const struct GNUNET_CONFIGURATION_Handle *cfg,
580 void *conn_status_cls)
581{
582 struct GNUNET_ARM_Handle *h;
583
584 h = GNUNET_new (struct GNUNET_ARM_Handle);
585 h->cfg = cfg;
588 if (GNUNET_OK != reconnect_arm (h))
589 {
590 GNUNET_free (h);
591 return NULL;
592 }
593 return h;
594}
595
596
602void
604{
605 struct GNUNET_ARM_Operation *op;
606
608 "Disconnecting from ARM service\n");
609 while (NULL != (op = h->operation_pending_head))
610 {
613 op);
614 if (NULL != op->result_cont)
617 0);
618 if (NULL != op->list_cont)
621 0,
622 NULL);
623 if (NULL != op->async)
624 {
626 op->async = NULL;
627 }
628 GNUNET_free (op);
629 }
630 if (NULL != h->mq)
631 {
633 h->mq = NULL;
634 }
635 if (NULL != h->reconnect_task)
636 {
638 h->reconnect_task = NULL;
639 }
640 GNUNET_free (h);
641}
642
643
653static enum GNUNET_ARM_Result
655 enum GNUNET_OS_InheritStdioFlags std_inheritance,
656 struct GNUNET_DISK_FileHandle *sigfd)
657{
658 struct GNUNET_OS_Process *proc;
659 char *cbinary;
660 char *binary;
661 char *quotedbinary;
662 char *config;
663 char *loprefix;
664 char *lopostfix;
665 int ld[2];
666 int *lsocks;
667
668 if (NULL == sigfd)
669 {
670 lsocks = NULL;
671 }
672 else
673 {
674 ld[0] = sigfd->fd;
675 ld[1] = -1;
676 lsocks = ld;
677 }
678 if (GNUNET_OK !=
680 "arm",
681 "PREFIX",
682 &loprefix))
683 loprefix = GNUNET_strdup ("");
684 else
685 loprefix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, loprefix);
686 if (GNUNET_OK !=
688 "arm",
689 "OPTIONS",
690 &lopostfix))
691 lopostfix = GNUNET_strdup ("");
692 else
694 lopostfix);
695 if (GNUNET_OK !=
697 "arm",
698 "BINARY",
699 &cbinary))
700 {
702 "arm",
703 "BINARY");
704 GNUNET_free (loprefix);
705 GNUNET_free (lopostfix);
707 }
708 if (GNUNET_OK !=
710 "arm",
711 "CONFIG",
712 &config))
713 config = NULL;
715 cbinary);
716 GNUNET_asprintf (&quotedbinary,
717 "\"%s\"",
718 binary);
719 GNUNET_free (cbinary);
720 if ( (GNUNET_YES ==
722 "TESTING",
723 "WEAKRANDOM")) &&
724 (GNUNET_YES ==
726 "TESTING",
727 "WEAKRANDOM")) &&
728 (GNUNET_NO ==
730 "TESTING",
731 "HOSTFILE")) )
732 {
733 /* Means we are ONLY running locally */
734 /* we're clearly running a test, don't daemonize */
735 if (NULL == config)
736 proc = GNUNET_OS_start_process_s (std_inheritance,
737 lsocks,
738 loprefix,
739 quotedbinary,
740 /* no daemonization! */
741 lopostfix,
742 NULL);
743 else
744 proc = GNUNET_OS_start_process_s (std_inheritance,
745 lsocks,
746 loprefix,
747 quotedbinary,
748 "-c",
749 config,
750 /* no daemonization! */
751 lopostfix,
752 NULL);
753 }
754 else
755 {
756 if (NULL == config)
757 proc = GNUNET_OS_start_process_s (std_inheritance,
758 lsocks,
759 loprefix,
760 quotedbinary,
761 "-d", /* do daemonize */
762 lopostfix,
763 NULL);
764 else
765 proc = GNUNET_OS_start_process_s (std_inheritance,
766 lsocks,
767 loprefix,
768 quotedbinary,
769 "-c",
770 config,
771 "-d", /* do daemonize */
772 lopostfix,
773 NULL);
774 }
775 GNUNET_free (binary);
776 GNUNET_free (quotedbinary);
777 if (NULL != config)
779 GNUNET_free (loprefix);
780 GNUNET_free (lopostfix);
781 if (NULL == proc)
785}
786
787
794void
796{
797 struct GNUNET_ARM_Handle *h = op->h;
798
799 if (NULL != op->async)
800 {
802 op->async = NULL;
803 }
804 if (NULL != op->rfd)
805 {
807 op->rfd = NULL;
808 }
809 if (h->thm == op)
810 {
811 op->result_cont = NULL;
812 return;
813 }
816 op);
817 GNUNET_free (op);
818}
819
820
831static struct GNUNET_ARM_Operation *
833 const char *service_name,
835 void *cb_cls,
836 uint16_t type)
837{
838 struct GNUNET_ARM_Operation *op;
839 size_t slen;
840 struct GNUNET_MQ_Envelope *env;
841 struct GNUNET_ARM_Message *msg;
842
843 slen = strlen (service_name) + 1;
844 if (slen + sizeof(struct GNUNET_ARM_Message) >= GNUNET_MAX_MESSAGE_SIZE)
845 {
846 GNUNET_break (0);
847 return NULL;
848 }
849 if (0 == h->request_id_counter)
852 op->h = h;
853 op->result_cont = cb;
854 op->cont_cls = cb_cls;
858 op);
860 slen,
861 type);
862 msg->reserved = htonl (0);
863 msg->request_id = GNUNET_htonll (op->id);
864 GNUNET_memcpy (&msg[1],
866 slen);
868 return op;
869}
870
871
877static void
878notify_running (void *cls)
879{
880 struct GNUNET_ARM_Operation *op = cls;
881 struct GNUNET_ARM_Handle *h = op->h;
882
883 op->async = NULL;
886 op);
887 if (NULL != op->result_cont)
891 if ( (GNUNET_YES == h->currently_up) &&
892 (NULL != h->conn_status) )
894 GNUNET_YES);
895 GNUNET_free (op);
896}
897
898
904static void
906{
907 struct GNUNET_ARM_Operation *op = cls;
908 struct GNUNET_ARM_Handle *h = op->h;
909
910 op->async = NULL;
912 "Notifying client that we started the ARM service\n");
915 op);
916 if (NULL != op->result_cont)
921 GNUNET_free (op);
922}
923
924
937 struct GNUNET_ARM_Handle *h,
938 const char *service_name,
940 std_inheritance,
942 void *cont_cls)
943{
944 struct GNUNET_ARM_Operation *op;
946 struct GNUNET_DISK_PipeHandle *sig;
947 struct GNUNET_DISK_FileHandle *wsig;
948
950 "Starting service `%s'\n",
952 if (0 != strcasecmp ("arm",
954 return change_service (h,
956 cont,
957 cont_cls,
959
960 /* Possible cases:
961 * 1) We're connected to ARM already. Invoke the callback immediately.
962 * 2) We're not connected to ARM.
963 * Cancel any reconnection attempts temporarily, then perform
964 * a service test.
965 */
966 if (GNUNET_YES == h->currently_up)
967 {
969 "ARM is already running\n");
971 op->h = h;
972 op->result_cont = cont;
973 op->cont_cls = cont_cls;
976 op);
978 op);
979 return op;
980 }
981 /* This is an inherently uncertain choice, as it is of course
982 theoretically possible that ARM is up and we just did not
983 yet complete the MQ handshake. However, given that users
984 are unlikely to hammer 'gnunet-arm -s' on a busy system,
985 the above check should catch 99.99% of the cases where ARM
986 is already running. */
988 "Starting ARM service\n");
989 if (NULL == (sig = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE)))
990 {
992 "pipe");
994 }
995 else
996 {
997 wsig = GNUNET_DISK_pipe_detach_end (sig,
1000 std_inheritance,
1001 wsig);
1004 reconnect_arm (h);
1005 }
1007 op->h = h;
1008 op->result_cont = cont;
1009 op->cont_cls = cont_cls;
1012 op);
1013 op->starting_ret = ret;
1014 if (NULL != sig)
1015 {
1018 /* Wait at most a minute for gnunet-service-arm to be up, as beyond
1019 that something clearly just went wrong */
1021 op->rfd,
1023 op);
1025 }
1026 else
1027 {
1029 op);
1030 }
1031 return op;
1032}
1033
1034
1049struct GNUNET_ARM_Operation *
1051 struct GNUNET_ARM_Handle *h,
1052 const char *service_name,
1054 void *cont_cls)
1055{
1056 struct GNUNET_ARM_Operation *op;
1057
1059 "Stopping service `%s'\n",
1060 service_name);
1061 op = change_service (h,
1063 cont,
1064 cont_cls,
1066 if (NULL == op)
1067 return NULL;
1068 /* If the service is ARM, set a flag as we will use MQ errors
1069 to detect that the process is really gone. */
1070 if (0 == strcasecmp (service_name,
1071 "arm"))
1073 return op;
1074}
1075
1076
1085struct GNUNET_ARM_Operation *
1087 struct GNUNET_ARM_Handle *h,
1089 void *cont_cls)
1090{
1091 struct GNUNET_ARM_Operation *op;
1092 struct GNUNET_MQ_Envelope *env;
1093 struct GNUNET_ARM_Message *msg;
1094
1096 "Requesting LIST from ARM service\n");
1097 if (0 == h->request_id_counter)
1100 op->h = h;
1101 op->list_cont = cont;
1102 op->cont_cls = cont_cls;
1103 op->id = h->request_id_counter++;
1106 op);
1109 msg->reserved = htonl (0);
1110 msg->request_id = GNUNET_htonll (op->id);
1111 GNUNET_MQ_send (h->mq, env);
1112 return op;
1113}
1114
1115
1116/* end of arm_api.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static void handle_arm_list_result(void *cls, const struct GNUNET_ARM_ListResultMessage *lres)
Handler for ARM list replies.
Definition: arm_api.c:399
static enum GNUNET_GenericReturnValue check_arm_list_result(void *cls, const struct GNUNET_ARM_ListResultMessage *lres)
Check that list result message is well-formed.
Definition: arm_api.c:350
static void reconnect_arm_later(struct GNUNET_ARM_Handle *h)
Close down any existing connection to the ARM service and try re-establishing it later.
Definition: arm_api.c:199
static void reconnect_arm_task(void *cls)
Task scheduled to try to re-connect to arm.
Definition: arm_api.c:183
static void handle_confirm(void *cls, const struct GNUNET_MessageHeader *msg)
Receive confirmation from test, ARM service is up.
Definition: arm_api.c:466
static struct GNUNET_ARM_Operation * change_service(struct GNUNET_ARM_Handle *h, const char *service_name, GNUNET_ARM_ResultCallback cb, void *cb_cls, uint16_t type)
Start or stop a service.
Definition: arm_api.c:832
static void handle_arm_result(void *cls, const struct GNUNET_ARM_ResultMessage *res)
Handler for ARM replies.
Definition: arm_api.c:262
static struct GNUNET_ARM_Operation * find_op_by_id(struct GNUNET_ARM_Handle *h, uint64_t id)
Find a control message by its unique ID.
Definition: arm_api.c:243
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: arm_api.c:492
static enum GNUNET_ARM_Result start_arm_service(struct GNUNET_ARM_Handle *h, enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_FileHandle *sigfd)
A client specifically requested starting of ARM itself.
Definition: arm_api.c:654
static const char * pool_get(const char *pool_start, size_t pool_size, size_t str_index)
Read from a string pool.
Definition: arm_api.c:325
static void notify_running(void *cls)
Task run to notify application that ARM is already up.
Definition: arm_api.c:878
#define LOG(kind,...)
Definition: arm_api.c:33
static enum GNUNET_GenericReturnValue reconnect_arm(struct GNUNET_ARM_Handle *h)
Connect to arm.
Definition: arm_api.c:519
static void notify_starting(void *cls)
Task run to notify application that ARM is being started.
Definition: arm_api.c:905
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:143
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:98
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:68
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
static void conn_status(void *cls, int connected)
Function called whenever we connect to or disconnect from ARM.
Definition: gnunet-arm.c:301
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
const struct GNUNET_CONFIGURATION_Handle * config
static char * name
Name (label) of the records to list.
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
static uint32_t type
Type string converted to DNS type value.
static int result
Global testing status.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:50
Constants for network protocols.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
void(* GNUNET_ARM_ServiceListCallback)(void *cls, enum GNUNET_ARM_RequestStatus rs, unsigned int count, const struct GNUNET_ARM_ServiceInfo *list)
Callback function invoked when list operation is complete.
struct GNUNET_ARM_Handle * GNUNET_ARM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_ARM_ConnectionStatusCallback conn_status, void *conn_status_cls)
Set up a context for communicating with ARM, then start connecting to the ARM service using that cont...
Definition: arm_api.c:577
struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_start(struct GNUNET_ARM_Handle *h, const char *service_name, enum GNUNET_OS_InheritStdioFlags std_inheritance, GNUNET_ARM_ResultCallback cont, void *cont_cls)
Request for a service to be started.
Definition: arm_api.c:936
struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_list(struct GNUNET_ARM_Handle *h, GNUNET_ARM_ServiceListCallback cont, void *cont_cls)
Request a list of running services.
Definition: arm_api.c:1086
void(* GNUNET_ARM_ResultCallback)(void *cls, enum GNUNET_ARM_RequestStatus rs, enum GNUNET_ARM_Result result)
Function called in response to a start/stop request.
struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_stop(struct GNUNET_ARM_Handle *h, const char *service_name, GNUNET_ARM_ResultCallback cont, void *cont_cls)
Request a service to be stopped.
Definition: arm_api.c:1050
void(* GNUNET_ARM_ConnectionStatusCallback)(void *cls, enum GNUNET_GenericReturnValue connected)
Function called whenever we connect to or disconnect from ARM.
void GNUNET_ARM_disconnect(struct GNUNET_ARM_Handle *h)
Disconnect from the ARM service (if connected) and destroy the context.
Definition: arm_api.c:603
GNUNET_ARM_Result
Replies to ARM requests.
void GNUNET_ARM_operation_cancel(struct GNUNET_ARM_Operation *op)
Abort an operation.
Definition: arm_api.c:795
@ GNUNET_ARM_RESULT_IS_NOT_KNOWN
Asked to start or stop a service, but it's not known.
@ GNUNET_ARM_RESULT_STARTING
Service starting was initiated.
@ GNUNET_ARM_RESULT_IS_STARTED_ALREADY
Asked to start it, but it's already started.
@ GNUNET_ARM_RESULT_STOPPING
ARM stopping was initiated (there's no "stopped" for ARM itself).
@ GNUNET_ARM_RESULT_STOPPED
Service was stopped (never sent for ARM itself).
@ GNUNET_ARM_RESULT_START_FAILED
Tried to start a service, but that failed for some reason.
@ GNUNET_ARM_REQUEST_DISCONNECTED
We disconnected from ARM, and request was not sent.
@ GNUNET_ARM_REQUEST_SENT_OK
Message was sent successfully.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1060
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
char * GNUNET_CONFIGURATION_expand_dollar(const struct GNUNET_CONFIGURATION_Handle *cfg, char *orig)
Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where either in the "PATHS" section or...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_detach_end(struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd end)
Detaches one of the ends from the pipe.
Definition: disk.c:1564
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(enum GNUNET_DISK_PipeFlags pf)
Creates an interprocess channel.
Definition: disk.c:1444
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1591
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
@ GNUNET_DISK_PF_NONE
No special options, use non-blocking read/write operations.
@ GNUNET_DISK_PIPE_END_WRITE
The writing-end of a pipe.
@ GNUNET_DISK_PIPE_END_READ
The reading-end of a pipe.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:37
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:61
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:76
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:700
GNUNET_OS_InheritStdioFlags
Flags that determine which of the standard streams should be inherited by the child process.
Definition: gnunet_os_lib.h:73
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
struct GNUNET_OS_Process * GNUNET_OS_start_process_s(enum GNUNET_OS_InheritStdioFlags std_inheritance, const int *lsocks, const char *filename,...)
Start a process.
Definition: os_priority.c:659
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:260
char * GNUNET_OS_get_libexec_binary_path(const struct GNUNET_OS_ProjectData *pd, const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
#define GNUNET_MESSAGE_TYPE_ARM_STOP
Request to ARM to stop a service.
#define GNUNET_MESSAGE_TYPE_ARM_RESULT
Response from ARM.
#define GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT
Response from ARM for listing currently running services.
#define GNUNET_MESSAGE_TYPE_ARM_TEST
Test if ARM service is online.
#define GNUNET_MESSAGE_TYPE_ARM_START
Request to ARM to start a service.
#define GNUNET_MESSAGE_TYPE_ARM_LIST
Request to ARM to list all currently running services.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1661
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1304
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1277
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:741
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
Handle for interacting with ARM.
Definition: arm_api.c:103
uint64_t request_id_counter
Counter for request identifiers.
Definition: arm_api.c:158
void * conn_status_cls
Closure for conn_status.
Definition: arm_api.c:132
struct GNUNET_ARM_Operation * operation_pending_head
Head of doubly-linked list of pending operations.
Definition: arm_api.c:117
int currently_up
Have we detected that ARM is up?
Definition: arm_api.c:163
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:107
struct GNUNET_ARM_Operation * operation_pending_tail
Tail of doubly-linked list of pending operations.
Definition: arm_api.c:122
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition: arm_api.c:112
struct GNUNET_ARM_Operation * thm
ARM operation where the goal is to wait for ARM shutdown to complete.
Definition: arm_api.c:142
struct GNUNET_TIME_Relative retry_backoff
Current delay we use for re-trying to connect to core.
Definition: arm_api.c:152
GNUNET_ARM_ConnectionStatusCallback conn_status
Callback to invoke on connection/disconnection.
Definition: arm_api.c:127
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition: arm_api.c:147
Reply from ARM to client for the GNUNET_MESSAGE_TYPE_ARM_LIST request followed by count '\0' terminat...
Definition: arm.h:145
uint16_t count
Number of 'struct GNUNET_ARM_ServiceInfoMessage' that are at the end of this message.
Definition: arm.h:156
struct GNUNET_ARM_Message arm_msg
Reply to client, of type is GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT, with an ID.
Definition: arm.h:150
uint64_t request_id
ID of a request that is being replied to.
Definition: arm.h:77
struct GNUNET_MessageHeader header
Reply to client, type is GNUNET_MESSAGE_TYPE_ARM_RESULT or GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT.
Definition: arm.h:65
Entry in a doubly-linked list of operations awaiting for replies (in-order) from the ARM service.
Definition: arm_api.c:41
int is_arm_stop
Is this an operation to stop the ARM service?
Definition: arm_api.c:95
void * cont_cls
Closure for result_cont or list_cont.
Definition: arm_api.c:70
struct GNUNET_ARM_Operation * prev
This is a doubly-linked list.
Definition: arm_api.c:50
struct GNUNET_DISK_FileHandle * rfd
File descriptor to close on operation stop, if not NULL.
Definition: arm_api.c:90
struct GNUNET_SCHEDULER_Task * async
Task for async completion.
Definition: arm_api.c:75
uint64_t id
Unique ID for the request.
Definition: arm_api.c:80
GNUNET_ARM_ServiceListCallback list_cont
Callback for service list requests.
Definition: arm_api.c:65
enum GNUNET_ARM_Result starting_ret
Result of this operation for notify_starting().
Definition: arm_api.c:85
GNUNET_ARM_ResultCallback result_cont
Callback for service state change requests.
Definition: arm_api.c:60
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
struct GNUNET_ARM_Handle * h
ARM handle.
Definition: arm_api.c:55
Reply from ARM to client.
Definition: arm.h:87
struct GNUNET_TIME_AbsoluteNBO last_started_at
Time when the service was first started, if applicable.
Definition: arm.h:135
uint16_t binary_index
String pool index for the service's binary.
Definition: arm.h:109
struct GNUNET_TIME_AbsoluteNBO restart_at
Time when the service will be restarted, if applicable to the current status.
Definition: arm.h:130
uint32_t status
Status from the 'enum GNUNET_ARM_ServiceStatus'.
Definition: arm.h:124
int16_t last_exit_status
Last process exit status.
Definition: arm.h:114
uint16_t name_index
String pool index for the service's name.
Definition: arm.h:104
Information about a service managed by ARM.
const char * name
The name of the service.
const char * binary
The binary used to execute the service.
Handle used to access files (and pipes).
int fd
File handle on Unix-like systems.
Handle used to manage a pipe.
Definition: disk.c:69
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for relative time used by GNUnet, in microseconds.