GNUnet  0.10.x
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 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 };
92 
93 
98 {
103 
108 
113 
118 
123 
128 
138 
143 
147  struct GNUNET_TIME_Relative retry_backoff;
148 
154 
159 };
160 
161 
168 static int
170 
171 
177 static void
179 {
180  struct GNUNET_ARM_Handle *h = cls;
181 
182  h->reconnect_task = NULL;
183  reconnect_arm (h);
184 }
185 
186 
193 static void
195 {
196  struct GNUNET_ARM_Operation *op;
197 
198  if (NULL != h->mq)
199  {
200  GNUNET_MQ_destroy (h->mq);
201  h->mq = NULL;
202  }
203  h->currently_up = GNUNET_NO;
204  GNUNET_assert (NULL == h->reconnect_task);
205  h->reconnect_task =
207  while (NULL != (op = h->operation_pending_head))
208  {
209  if (NULL != op->result_cont)
211  if (NULL != op->list_cont)
214  }
217  if (NULL != h->conn_status)
219 }
220 
221 
229 static struct GNUNET_ARM_Operation *
230 find_op_by_id (struct GNUNET_ARM_Handle *h, uint64_t id)
231 {
233 
234  for (result = h->operation_pending_head; NULL != result;
235  result = result->next)
236  if (id == result->id)
237  return result;
238  return NULL;
239 }
240 
241 
248 static void
250 {
251  struct GNUNET_ARM_Handle *h = cls;
252  struct GNUNET_ARM_Operation *op;
253  uint64_t id;
256  void *result_cont_cls;
257 
258  id = GNUNET_ntohll (res->arm_msg.request_id);
259  op = find_op_by_id (h, id);
260  if (NULL == op)
261  {
263  "Message with unknown id %llu\n",
264  (unsigned long long) id);
265  return;
266  }
267 
268  result = (enum GNUNET_ARM_Result) ntohl (res->result);
270  {
271  /* special case: if we are stopping 'gnunet-service-arm', we do not just
272  wait for the result message, but also wait for the service to close
273  the connection (and then we have to close our client handle as well);
274  this is done by installing a different receive handler, waiting for
275  the connection to go down */
276  if (NULL != h->thm)
277  {
278  GNUNET_break (0);
279  op->result_cont (h->thm->cont_cls,
282  GNUNET_free (h->thm);
283  }
286  op);
287  h->thm = op;
288  return;
289  }
290  result_cont = op->result_cont;
291  result_cont_cls = op->cont_cls;
293  if (NULL != result_cont)
294  result_cont (result_cont_cls, GNUNET_ARM_REQUEST_SENT_OK, result);
295 }
296 
297 
305 static int
307  const struct GNUNET_ARM_ListResultMessage *lres)
308 {
309  const char *pos = (const char *) &lres[1];
310  uint16_t rcount = ntohs (lres->count);
311  uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof (*lres);
312  uint16_t size_check;
313 
314  (void) cls;
315  size_check = 0;
316  for (unsigned int i = 0; i < rcount; i++)
317  {
318  const char *end = memchr (pos, 0, msize - size_check);
319  if (NULL == end)
320  {
321  GNUNET_break (0);
322  return GNUNET_SYSERR;
323  }
324  size_check += (end - pos) + 1;
325  pos = end + 1;
326  }
327  return GNUNET_OK;
328 }
329 
330 
337 static void
339  const struct GNUNET_ARM_ListResultMessage *lres)
340 {
341  struct GNUNET_ARM_Handle *h = cls;
342  uint16_t rcount = ntohs (lres->count);
343  const char *list[rcount];
344  const char *pos = (const char *) &lres[1];
345  uint16_t msize = ntohs (lres->arm_msg.header.size) - sizeof (*lres);
346  struct GNUNET_ARM_Operation *op;
347  uint16_t size_check;
348  uint64_t id;
349 
350  id = GNUNET_ntohll (lres->arm_msg.request_id);
351  op = find_op_by_id (h, id);
352  if (NULL == op)
353  {
355  "Message with unknown id %llu\n",
356  (unsigned long long) id);
357  return;
358  }
359  size_check = 0;
360  for (unsigned int i = 0; i < rcount; i++)
361  {
362  const char *end = memchr (pos, 0, msize - size_check);
363 
364  /* Assert, as this was already checked in #check_arm_list_result() */
365  GNUNET_assert (NULL != end);
366  list[i] = pos;
367  size_check += (end - pos) + 1;
368  pos = end + 1;
369  }
370  if (NULL != op->list_cont)
371  op->list_cont (op->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, list);
373 }
374 
375 
382 static void
383 handle_confirm (void *cls, const struct GNUNET_MessageHeader *msg)
384 {
385  struct GNUNET_ARM_Handle *h = cls;
386 
387  (void) msg;
388  LOG (GNUNET_ERROR_TYPE_DEBUG, "Got confirmation from ARM that we are up!\n");
389  if (GNUNET_NO == h->currently_up)
390  {
392  if (NULL != h->conn_status)
394  }
395 }
396 
397 
406 static void
407 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
408 {
409  struct GNUNET_ARM_Handle *h = cls;
410  struct GNUNET_ARM_Operation *op;
411 
412  (void) error;
413  h->currently_up = GNUNET_NO;
414  if (NULL != (op = h->thm))
415  {
416  h->thm = NULL;
417  op->result_cont (op->cont_cls,
420  GNUNET_free (op);
421  }
423 }
424 
425 
432 static int
434 {
435  struct GNUNET_MQ_MessageHandler handlers[] =
436  {GNUNET_MQ_hd_fixed_size (arm_result,
439  h),
440  GNUNET_MQ_hd_var_size (arm_list_result,
443  h),
444  GNUNET_MQ_hd_fixed_size (confirm,
446  struct GNUNET_MessageHeader,
447  h),
449  struct GNUNET_MessageHeader *test;
450  struct GNUNET_MQ_Envelope *env;
451 
452  if (NULL != h->mq)
453  return GNUNET_OK;
455  h->mq = GNUNET_CLIENT_connect (h->cfg, "arm", handlers, &mq_error_handler, h);
456  if (NULL == h->mq)
457  {
458  LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CLIENT_connect returned NULL\n");
459  if (NULL != h->conn_status)
461  return GNUNET_SYSERR;
462  }
463  LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending TEST message to ARM\n");
465  GNUNET_MQ_send (h->mq, env);
466  return GNUNET_OK;
467 }
468 
469 
481 struct GNUNET_ARM_Handle *
484  void *conn_status_cls)
485 {
486  struct GNUNET_ARM_Handle *h;
487 
488  h = GNUNET_new (struct GNUNET_ARM_Handle);
489  h->cfg = cfg;
492  if (GNUNET_OK != reconnect_arm (h))
493  {
494  GNUNET_free (h);
495  return NULL;
496  }
497  return h;
498 }
499 
500 
506 void
508 {
509  struct GNUNET_ARM_Operation *op;
510 
511  LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from ARM service\n");
512  while (NULL != (op = h->operation_pending_head))
513  {
516  op);
517  if (NULL != op->result_cont)
519  if (NULL != op->list_cont)
521  if (NULL != op->async)
522  {
524  op->async = NULL;
525  }
526  GNUNET_free (op);
527  }
528  if (NULL != h->mq)
529  {
530  GNUNET_MQ_destroy (h->mq);
531  h->mq = NULL;
532  }
533  if (NULL != h->reconnect_task)
534  {
536  h->reconnect_task = NULL;
537  }
538  GNUNET_free (h);
539 }
540 
541 
550 static enum GNUNET_ARM_Result
552  enum GNUNET_OS_InheritStdioFlags std_inheritance)
553 {
554  struct GNUNET_OS_Process *proc;
555  char *cbinary;
556  char *binary;
557  char *quotedbinary;
558  char *config;
559  char *loprefix;
560  char *lopostfix;
561 
563  "arm",
564  "PREFIX",
565  &loprefix))
566  loprefix = GNUNET_strdup ("");
567  else
568  loprefix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, loprefix);
570  "arm",
571  "OPTIONS",
572  &lopostfix))
573  lopostfix = GNUNET_strdup ("");
574  else
575  lopostfix = GNUNET_CONFIGURATION_expand_dollar (h->cfg, lopostfix);
576  if (GNUNET_OK !=
577  GNUNET_CONFIGURATION_get_value_string (h->cfg, "arm", "BINARY", &cbinary))
578  {
580  GNUNET_free (loprefix);
581  GNUNET_free (lopostfix);
583  }
585  "arm",
586  "CONFIG",
587  &config))
588  config = NULL;
589  binary = GNUNET_OS_get_libexec_binary_path (cbinary);
590  GNUNET_asprintf (&quotedbinary, "\"%s\"", binary);
591  GNUNET_free (cbinary);
592  if ((GNUNET_YES ==
593  GNUNET_CONFIGURATION_have_value (h->cfg, "TESTING", "WEAKRANDOM")) &&
595  "TESTING",
596  "WEAKRANDOM")) &&
597  (GNUNET_NO ==
598  GNUNET_CONFIGURATION_have_value (h->cfg, "TESTING", "HOSTFILE")))
599  {
600  /* Means we are ONLY running locally */
601  /* we're clearly running a test, don't daemonize */
602  if (NULL == config)
604  std_inheritance,
605  NULL,
606  loprefix,
607  quotedbinary,
608  /* no daemonization! */
609  lopostfix,
610  NULL);
611  else
613  std_inheritance,
614  NULL,
615  loprefix,
616  quotedbinary,
617  "-c",
618  config,
619  /* no daemonization! */
620  lopostfix,
621  NULL);
622  }
623  else
624  {
625  if (NULL == config)
627  std_inheritance,
628  NULL,
629  loprefix,
630  quotedbinary,
631  "-d", /* do daemonize */
632  lopostfix,
633  NULL);
634  else
636  std_inheritance,
637  NULL,
638  loprefix,
639  quotedbinary,
640  "-c",
641  config,
642  "-d", /* do daemonize */
643  lopostfix,
644  NULL);
645  }
646  GNUNET_free (binary);
647  GNUNET_free (quotedbinary);
648  GNUNET_free_non_null (config);
649  GNUNET_free (loprefix);
650  GNUNET_free (lopostfix);
651  if (NULL == proc)
655 }
656 
657 
664 void
666 {
667  struct GNUNET_ARM_Handle *h = op->h;
668 
669  if (h->thm == op)
670  {
671  op->result_cont = NULL;
672  return;
673  }
676  op);
677  GNUNET_free (op);
678 }
679 
680 
691 static struct GNUNET_ARM_Operation *
693  const char *service_name,
695  void *cb_cls,
696  uint16_t type)
697 {
698  struct GNUNET_ARM_Operation *op;
699  size_t slen;
700  struct GNUNET_MQ_Envelope *env;
701  struct GNUNET_ARM_Message *msg;
702 
703  slen = strlen (service_name) + 1;
704  if (slen + sizeof (struct GNUNET_ARM_Message) >= GNUNET_MAX_MESSAGE_SIZE)
705  {
706  GNUNET_break (0);
707  return NULL;
708  }
709  if (0 == h->request_id_counter)
710  h->request_id_counter++;
711  op = GNUNET_new (struct GNUNET_ARM_Operation);
712  op->h = h;
713  op->result_cont = cb;
714  op->cont_cls = cb_cls;
715  op->id = h->request_id_counter++;
718  op);
719  env = GNUNET_MQ_msg_extra (msg, slen, type);
720  msg->reserved = htonl (0);
721  msg->request_id = GNUNET_htonll (op->id);
722  GNUNET_memcpy (&msg[1], service_name, slen);
723  GNUNET_MQ_send (h->mq, env);
724  return op;
725 }
726 
727 
733 static void
734 notify_running (void *cls)
735 {
736  struct GNUNET_ARM_Operation *op = cls;
737  struct GNUNET_ARM_Handle *h = op->h;
738 
739  op->async = NULL;
742  op);
743  if (NULL != op->result_cont)
744  op->result_cont (op->cont_cls,
747  if ((GNUNET_YES == h->currently_up) && (NULL != h->conn_status))
749  GNUNET_free (op);
750 }
751 
752 
758 static void
759 notify_starting (void *cls)
760 {
761  struct GNUNET_ARM_Operation *op = cls;
762  struct GNUNET_ARM_Handle *h = op->h;
763 
764  op->async = NULL;
766  "Notifying client that we started the ARM service\n");
769  op);
770  if (NULL != op->result_cont)
771  op->result_cont (op->cont_cls,
773  op->starting_ret);
774  GNUNET_free (op);
775 }
776 
777 
788 struct GNUNET_ARM_Operation *
790  struct GNUNET_ARM_Handle *h,
791  const char *service_name,
792  enum GNUNET_OS_InheritStdioFlags std_inheritance,
794  void *cont_cls)
795 {
796  struct GNUNET_ARM_Operation *op;
797  enum GNUNET_ARM_Result ret;
798 
799  LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting service `%s'\n", service_name);
800  if (0 != strcasecmp ("arm", service_name))
801  return change_service (h,
802  service_name,
803  cont,
804  cont_cls,
806 
807  /* Possible cases:
808  * 1) We're connected to ARM already. Invoke the callback immediately.
809  * 2) We're not connected to ARM.
810  * Cancel any reconnection attempts temporarily, then perform
811  * a service test.
812  */
813  if (GNUNET_YES == h->currently_up)
814  {
815  LOG (GNUNET_ERROR_TYPE_DEBUG, "ARM is already running\n");
816  op = GNUNET_new (struct GNUNET_ARM_Operation);
817  op->h = h;
818  op->result_cont = cont;
819  op->cont_cls = cont_cls;
822  op);
824  return op;
825  }
826  /* This is an inherently uncertain choice, as it is of course
827  theoretically possible that ARM is up and we just did not
828  yet complete the MQ handshake. However, given that users
829  are unlikely to hammer 'gnunet-arm -s' on a busy system,
830  the above check should catch 99.99% of the cases where ARM
831  is already running. */
832  LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting ARM service\n");
833  ret = start_arm_service (h, std_inheritance);
834  if (GNUNET_ARM_RESULT_STARTING == ret)
835  reconnect_arm (h);
836  op = GNUNET_new (struct GNUNET_ARM_Operation);
837  op->h = h;
838  op->result_cont = cont;
839  op->cont_cls = cont_cls;
842  op);
843  op->starting_ret = ret;
845  return op;
846 }
847 
848 
863 struct GNUNET_ARM_Operation *
865  const char *service_name,
867  void *cont_cls)
868 {
869  struct GNUNET_ARM_Operation *op;
870 
871  LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping service `%s'\n", service_name);
872  op = change_service (h,
873  service_name,
874  cont,
875  cont_cls,
877  if (NULL == op)
878  return NULL;
879  /* If the service is ARM, set a flag as we will use MQ errors
880  to detect that the process is really gone. */
881  if (0 == strcasecmp (service_name, "arm"))
882  op->is_arm_stop = GNUNET_YES;
883  return op;
884 }
885 
886 
895 struct GNUNET_ARM_Operation *
898  void *cont_cls)
899 {
900  struct GNUNET_ARM_Operation *op;
901  struct GNUNET_MQ_Envelope *env;
902  struct GNUNET_ARM_Message *msg;
903 
904  LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting LIST from ARM service\n");
905  if (0 == h->request_id_counter)
906  h->request_id_counter++;
907  op = GNUNET_new (struct GNUNET_ARM_Operation);
908  op->h = h;
909  op->list_cont = cont;
910  op->cont_cls = cont_cls;
911  op->id = h->request_id_counter++;
914  op);
916  msg->reserved = htonl (0);
917  msg->request_id = GNUNET_htonll (op->id);
918  GNUNET_MQ_send (h->mq, env);
919  return op;
920 }
921 
922 
923 /* end of arm_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void notify_starting(void *cls)
Task run to notify application that ARM is being started.
Definition: arm_api.c:759
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:45
GNUNET_OS_InheritStdioFlags
Flags that determine which of the standard streams should be inherited by the child process...
Definition: gnunet_os_lib.h:68
ARM stopping was initiated (there&#39;s no "stopped" for ARM itself).
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition: arm_api.c:107
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT
Response from ARM for listing currently running services.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
uint64_t request_id
ID of a request that is being replied to.
Definition: arm.h:78
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:901
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:364
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition: arm_api.c:142
GNUNET_MQ_Error
Error codes for the queue.
#define LOG(kind,...)
Definition: arm_api.c:33
#define GNUNET_MESSAGE_TYPE_ARM_RESULT
Response from ARM.
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...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int check_arm_list_result(void *cls, const struct GNUNET_ARM_ListResultMessage *lres)
Checked that list result message is well-formed.
Definition: arm_api.c:306
Entry in a doubly-linked list of operations awaiting for replies (in-order) from the ARM service...
Definition: arm_api.c:40
#define GNUNET_MESSAGE_TYPE_ARM_START
Request to ARM to start a service.
struct GNUNET_OS_Process * GNUNET_OS_start_process_s(int pipe_control, unsigned int std_inheritance, const SOCKTYPE *lsocks, const char *filename,...)
Start a process.
Definition: os_priority.c:1474
#define GNUNET_MESSAGE_TYPE_ARM_STOP
Request to ARM to stop a service.
struct GNUNET_ARM_Message arm_msg
Reply to client, of type is GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT, with an ID.
Definition: arm.h:113
We disconnected from ARM, and request was not sent.
static void handle_confirm(void *cls, const struct GNUNET_MessageHeader *msg)
Receive confirmation from test, ARM service is up.
Definition: arm_api.c:383
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
Handle for interacting with ARM.
Definition: arm_api.c:97
static void reconnect_arm_task(void *cls)
Task scheduled to try to re-connect to arm.
Definition: arm_api.c:178
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:102
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
void GNUNET_ARM_operation_cancel(struct GNUNET_ARM_Operation *op)
Abort an operation.
Definition: arm_api.c:665
#define GNUNET_new(type)
Allocate a struct or union of the given type.
GNUNET_ARM_Result
Replies to ARM requests.
void * cont_cls
Closure for result_cont or list_cont.
Definition: arm_api.c:70
Asked to start it, but it&#39;s already started.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
uint32_t reserved
For alignment.
Definition: arm.h:71
void GNUNET_ARM_disconnect(struct GNUNET_ARM_Handle *h)
Disconnect from the ARM service (if connected) and destroy the context.
Definition: arm_api.c:507
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint16_t count
Number of &#39;\0&#39; terminated strings that follow this message.
Definition: arm.h:119
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * async
Task for async completion.
Definition: arm_api.c:75
static void notify_running(void *cls)
Task run to notify application that ARM is already up.
Definition: arm_api.c:734
GNUNET_ARM_ConnectionStatusCallback conn_status
Callback to invoke on connection/disconnection.
Definition: arm_api.c:122
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#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:52
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:1246
struct GNUNET_ARM_Message arm_msg
Reply to client, of type is GNUNET_MESSAGE_TYPE_ARM_RESULT, with an ID.
Definition: arm.h:93
Tried to start a service, but that failed for some reason.
#define GNUNET_memcpy(dst, src, n)
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:864
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
Service starting was initiated.
uint32_t result
Result from the enum GNUNET_ARM_Result
Definition: arm.h:98
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
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:692
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:1273
static void conn_status(void *cls, int connected)
Function called whenever we connect to or disconnect from ARM.
Definition: gnunet-arm.c:286
GNUNET_ARM_ServiceListCallback list_cont
Callback for service list requests.
Definition: arm_api.c:65
int 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.
static char * service_name
Option -s: service name (hash to get service descriptor)
Definition: gnunet-vpn.c:51
static const struct GNUNET_CONFIGURATION_Handle * config
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:896
struct GNUNET_MessageHeader header
Reply to client, type is GNUNET_MESSAGE_TYPE_ARM_RESULT or GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT.
Definition: arm.h:66
static int result
Global testing status.
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:194
void(* GNUNET_ARM_ConnectionStatusCallback)(void *cls, int connected)
Function called whenever we connect to or disconnect from ARM.
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:482
struct GNUNET_ARM_Operation * operation_pending_head
Head of doubly-linked list of pending operations.
Definition: arm_api.c:112
static void handle_arm_result(void *cls, const struct GNUNET_ARM_ResultMessage *res)
Handler for ARM replies.
Definition: arm_api.c:249
Message handler for a specific message type.
static int res
struct GNUNET_ARM_Operation * thm
ARM operation where the goal is to wait for ARM shutdown to complete.
Definition: arm_api.c:137
static enum GNUNET_ARM_Result start_arm_service(struct GNUNET_ARM_Handle *h, enum GNUNET_OS_InheritStdioFlags std_inheritance)
A client specifically requested starting of ARM itself.
Definition: arm_api.c:551
int 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.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
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.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
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:789
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define GNUNET_MESSAGE_TYPE_ARM_LIST
Request to ARM to list all currently running services.
uint64_t id
Unique ID for the request.
Definition: arm_api.c:80
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Reply from ARM to client for the GNUNET_MESSAGE_TYPE_ARM_LIST request followed by count &#39;\0&#39; terminat...
Definition: arm.h:107
struct GNUNET_ARM_Operation * prev
This is a doubly-linked list.
Definition: arm_api.c:50
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
void * conn_status_cls
Closure for conn_status.
Definition: arm_api.c:127
Message was sent successfully.
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_ARM_Handle * h
ARM handle.
Definition: arm_api.c:55
uint64_t request_id_counter
Counter for request identifiers.
Definition: arm_api.c:153
#define GNUNET_MESSAGE_TYPE_ARM_TEST
Test if ARM service is online.
struct GNUNET_TIME_Relative retry_backoff
Current delay we use for re-trying to connect to core.
Definition: arm_api.c:147
Reply from ARM to client.
Definition: arm.h:87
int currently_up
Have we detected that ARM is up?
Definition: arm_api.c:158
configuration data
Definition: configuration.c:85
enum GNUNET_ARM_Result starting_ret
Result of this operation for notify_starting().
Definition: arm_api.c:85
int is_arm_stop
Is this an operation to stop the ARM service?
Definition: arm_api.c:90
Entry in list of pending tasks.
Definition: scheduler.c:134
Asked to start or stop a service, but it&#39;s not known.
int 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.
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
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:230
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
struct GNUNET_ARM_Operation * operation_pending_tail
Tail of doubly-linked list of pending operations.
Definition: arm_api.c:117
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
static int reconnect_arm(struct GNUNET_ARM_Handle *h)
Connect to arm.
Definition: arm_api.c:433
int 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".
Service was stopped (never sent for ARM itself).
static void handle_arm_list_result(void *cls, const struct GNUNET_ARM_ListResultMessage *lres)
Handler for ARM list replies.
Definition: arm_api.c:338
void(* GNUNET_ARM_ServiceListCallback)(void *cls, enum GNUNET_ARM_RequestStatus rs, unsigned int count, const char *const *list)
Callback function invoked when list operation is complete.
GNUNET_ARM_ResultCallback result_cont
Callback for service state change requests.
Definition: arm_api.c:60
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:64
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:48
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
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:407