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 
45 
50 
55 
60 
65 
69  void *cont_cls;
70 
75 
79  uint64_t id;
80 
85 
90 };
91 
92 
101 
106 
111 
116 
121 
126 
136 
141 
145  struct GNUNET_TIME_Relative retry_backoff;
146 
152 
157 };
158 
159 
166 static int
168 
169 
175 static void
177 {
178  struct GNUNET_ARM_Handle *h = cls;
179 
180  h->reconnect_task = NULL;
181  reconnect_arm(h);
182 }
183 
184 
191 static void
193 {
194  struct GNUNET_ARM_Operation *op;
195 
196  if (NULL != h->mq)
197  {
198  GNUNET_MQ_destroy(h->mq);
199  h->mq = NULL;
200  }
201  h->currently_up = GNUNET_NO;
202  GNUNET_assert(NULL == h->reconnect_task);
203  h->reconnect_task =
205  while (NULL != (op = h->operation_pending_head))
206  {
207  if (NULL != op->result_cont)
209  if (NULL != op->list_cont)
212  }
215  if (NULL != h->conn_status)
217 }
218 
219 
227 static struct GNUNET_ARM_Operation *
228 find_op_by_id(struct GNUNET_ARM_Handle *h, uint64_t id)
229 {
231 
232  for (result = h->operation_pending_head; NULL != result;
233  result = result->next)
234  if (id == result->id)
235  return result;
236  return NULL;
237 }
238 
239 
246 static void
248 {
249  struct GNUNET_ARM_Handle *h = cls;
250  struct GNUNET_ARM_Operation *op;
251  uint64_t id;
254  void *result_cont_cls;
255 
256  id = GNUNET_ntohll(res->arm_msg.request_id);
257  op = find_op_by_id(h, id);
258  if (NULL == op)
259  {
261  "Message with unknown id %llu\n",
262  (unsigned long long)id);
263  return;
264  }
265 
266  result = (enum GNUNET_ARM_Result)ntohl(res->result);
268  {
269  /* special case: if we are stopping 'gnunet-service-arm', we do not just
270  wait for the result message, but also wait for the service to close
271  the connection (and then we have to close our client handle as well);
272  this is done by installing a different receive handler, waiting for
273  the connection to go down */
274  if (NULL != h->thm)
275  {
276  GNUNET_break(0);
277  op->result_cont(h->thm->cont_cls,
280  GNUNET_free(h->thm);
281  }
284  op);
285  h->thm = op;
286  return;
287  }
288  result_cont = op->result_cont;
289  result_cont_cls = op->cont_cls;
291  if (NULL != result_cont)
292  result_cont(result_cont_cls, GNUNET_ARM_REQUEST_SENT_OK, result);
293 }
294 
295 
303 static int
305  const struct GNUNET_ARM_ListResultMessage *lres)
306 {
307  const char *pos = (const char *)&lres[1];
308  uint16_t rcount = ntohs(lres->count);
309  uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres);
310  uint16_t size_check;
311 
312  (void)cls;
313  size_check = 0;
314  for (unsigned int i = 0; i < rcount; i++)
315  {
316  const char *end = memchr(pos, 0, msize - size_check);
317  if (NULL == end)
318  {
319  GNUNET_break(0);
320  return GNUNET_SYSERR;
321  }
322  size_check += (end - pos) + 1;
323  pos = end + 1;
324  }
325  return GNUNET_OK;
326 }
327 
328 
335 static void
337  const struct GNUNET_ARM_ListResultMessage *lres)
338 {
339  struct GNUNET_ARM_Handle *h = cls;
340  uint16_t rcount = ntohs(lres->count);
341  const char *list[rcount];
342  const char *pos = (const char *)&lres[1];
343  uint16_t msize = ntohs(lres->arm_msg.header.size) - sizeof(*lres);
344  struct GNUNET_ARM_Operation *op;
345  uint16_t size_check;
346  uint64_t id;
347 
348  id = GNUNET_ntohll(lres->arm_msg.request_id);
349  op = find_op_by_id(h, id);
350  if (NULL == op)
351  {
353  "Message with unknown id %llu\n",
354  (unsigned long long)id);
355  return;
356  }
357  size_check = 0;
358  for (unsigned int i = 0; i < rcount; i++)
359  {
360  const char *end = memchr(pos, 0, msize - size_check);
361 
362  /* Assert, as this was already checked in #check_arm_list_result() */
363  GNUNET_assert(NULL != end);
364  list[i] = pos;
365  size_check += (end - pos) + 1;
366  pos = end + 1;
367  }
368  if (NULL != op->list_cont)
369  op->list_cont(op->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, list);
371 }
372 
373 
380 static void
381 handle_confirm(void *cls, const struct GNUNET_MessageHeader *msg)
382 {
383  struct GNUNET_ARM_Handle *h = cls;
384 
385  (void)msg;
386  LOG(GNUNET_ERROR_TYPE_DEBUG, "Got confirmation from ARM that we are up!\n");
387  if (GNUNET_NO == h->currently_up)
388  {
390  if (NULL != h->conn_status)
392  }
393 }
394 
395 
404 static void
405 mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
406 {
407  struct GNUNET_ARM_Handle *h = cls;
408  struct GNUNET_ARM_Operation *op;
409 
410  (void)error;
411  h->currently_up = GNUNET_NO;
412  if (NULL != (op = h->thm))
413  {
414  h->thm = NULL;
415  op->result_cont(op->cont_cls,
418  GNUNET_free(op);
419  }
421 }
422 
423 
430 static int
432 {
433  struct GNUNET_MQ_MessageHandler handlers[] =
434  { GNUNET_MQ_hd_fixed_size(arm_result,
437  h),
438  GNUNET_MQ_hd_var_size(arm_list_result,
441  h),
442  GNUNET_MQ_hd_fixed_size(confirm,
444  struct GNUNET_MessageHeader,
445  h),
447  struct GNUNET_MessageHeader *test;
448  struct GNUNET_MQ_Envelope *env;
449 
450  if (NULL != h->mq)
451  return GNUNET_OK;
453  h->mq = GNUNET_CLIENT_connect(h->cfg, "arm", handlers, &mq_error_handler, h);
454  if (NULL == h->mq)
455  {
456  LOG(GNUNET_ERROR_TYPE_DEBUG, "GNUNET_CLIENT_connect returned NULL\n");
457  if (NULL != h->conn_status)
459  return GNUNET_SYSERR;
460  }
461  LOG(GNUNET_ERROR_TYPE_DEBUG, "Sending TEST message to ARM\n");
463  GNUNET_MQ_send(h->mq, env);
464  return GNUNET_OK;
465 }
466 
467 
479 struct GNUNET_ARM_Handle *
482  void *conn_status_cls)
483 {
484  struct GNUNET_ARM_Handle *h;
485 
486  h = GNUNET_new(struct GNUNET_ARM_Handle);
487  h->cfg = cfg;
490  if (GNUNET_OK != reconnect_arm(h))
491  {
492  GNUNET_free(h);
493  return NULL;
494  }
495  return h;
496 }
497 
498 
504 void
506 {
507  struct GNUNET_ARM_Operation *op;
508 
509  LOG(GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from ARM service\n");
510  while (NULL != (op = h->operation_pending_head))
511  {
514  op);
515  if (NULL != op->result_cont)
517  if (NULL != op->list_cont)
519  if (NULL != op->async)
520  {
522  op->async = NULL;
523  }
524  GNUNET_free(op);
525  }
526  if (NULL != h->mq)
527  {
528  GNUNET_MQ_destroy(h->mq);
529  h->mq = NULL;
530  }
531  if (NULL != h->reconnect_task)
532  {
534  h->reconnect_task = NULL;
535  }
536  GNUNET_free(h);
537 }
538 
539 
548 static enum GNUNET_ARM_Result
550  enum GNUNET_OS_InheritStdioFlags std_inheritance)
551 {
552  struct GNUNET_OS_Process *proc;
553  char *cbinary;
554  char *binary;
555  char *quotedbinary;
556  char *config;
557  char *loprefix;
558  char *lopostfix;
559 
561  "arm",
562  "PREFIX",
563  &loprefix))
564  loprefix = GNUNET_strdup("");
565  else
566  loprefix = GNUNET_CONFIGURATION_expand_dollar(h->cfg, loprefix);
568  "arm",
569  "OPTIONS",
570  &lopostfix))
571  lopostfix = GNUNET_strdup("");
572  else
573  lopostfix = GNUNET_CONFIGURATION_expand_dollar(h->cfg, lopostfix);
574  if (GNUNET_OK !=
575  GNUNET_CONFIGURATION_get_value_string(h->cfg, "arm", "BINARY", &cbinary))
576  {
578  GNUNET_free(loprefix);
579  GNUNET_free(lopostfix);
581  }
583  "arm",
584  "CONFIG",
585  &config))
586  config = NULL;
587  binary = GNUNET_OS_get_libexec_binary_path(cbinary);
588  GNUNET_asprintf(&quotedbinary, "\"%s\"", binary);
589  GNUNET_free(cbinary);
590  if ((GNUNET_YES ==
591  GNUNET_CONFIGURATION_have_value(h->cfg, "TESTING", "WEAKRANDOM")) &&
593  "TESTING",
594  "WEAKRANDOM")) &&
595  (GNUNET_NO ==
596  GNUNET_CONFIGURATION_have_value(h->cfg, "TESTING", "HOSTFILE")))
597  {
598  /* Means we are ONLY running locally */
599  /* we're clearly running a test, don't daemonize */
600  if (NULL == config)
602  std_inheritance,
603  NULL,
604  loprefix,
605  quotedbinary,
606  /* no daemonization! */
607  lopostfix,
608  NULL);
609  else
611  std_inheritance,
612  NULL,
613  loprefix,
614  quotedbinary,
615  "-c",
616  config,
617  /* no daemonization! */
618  lopostfix,
619  NULL);
620  }
621  else
622  {
623  if (NULL == config)
625  std_inheritance,
626  NULL,
627  loprefix,
628  quotedbinary,
629  "-d", /* do daemonize */
630  lopostfix,
631  NULL);
632  else
634  std_inheritance,
635  NULL,
636  loprefix,
637  quotedbinary,
638  "-c",
639  config,
640  "-d", /* do daemonize */
641  lopostfix,
642  NULL);
643  }
644  GNUNET_free(binary);
645  GNUNET_free(quotedbinary);
646  GNUNET_free_non_null(config);
647  GNUNET_free(loprefix);
648  GNUNET_free(lopostfix);
649  if (NULL == proc)
653 }
654 
655 
662 void
664 {
665  struct GNUNET_ARM_Handle *h = op->h;
666 
667  if (h->thm == op)
668  {
669  op->result_cont = NULL;
670  return;
671  }
674  op);
675  GNUNET_free(op);
676 }
677 
678 
689 static struct GNUNET_ARM_Operation *
691  const char *service_name,
693  void *cb_cls,
694  uint16_t type)
695 {
696  struct GNUNET_ARM_Operation *op;
697  size_t slen;
698  struct GNUNET_MQ_Envelope *env;
699  struct GNUNET_ARM_Message *msg;
700 
701  slen = strlen(service_name) + 1;
702  if (slen + sizeof(struct GNUNET_ARM_Message) >= GNUNET_MAX_MESSAGE_SIZE)
703  {
704  GNUNET_break(0);
705  return NULL;
706  }
707  if (0 == h->request_id_counter)
708  h->request_id_counter++;
709  op = GNUNET_new(struct GNUNET_ARM_Operation);
710  op->h = h;
711  op->result_cont = cb;
712  op->cont_cls = cb_cls;
713  op->id = h->request_id_counter++;
716  op);
717  env = GNUNET_MQ_msg_extra(msg, slen, type);
718  msg->reserved = htonl(0);
719  msg->request_id = GNUNET_htonll(op->id);
720  GNUNET_memcpy(&msg[1], service_name, slen);
721  GNUNET_MQ_send(h->mq, env);
722  return op;
723 }
724 
725 
731 static void
732 notify_running(void *cls)
733 {
734  struct GNUNET_ARM_Operation *op = cls;
735  struct GNUNET_ARM_Handle *h = op->h;
736 
737  op->async = NULL;
740  op);
741  if (NULL != op->result_cont)
742  op->result_cont(op->cont_cls,
745  if ((GNUNET_YES == h->currently_up) && (NULL != h->conn_status))
747  GNUNET_free(op);
748 }
749 
750 
756 static void
757 notify_starting(void *cls)
758 {
759  struct GNUNET_ARM_Operation *op = cls;
760  struct GNUNET_ARM_Handle *h = op->h;
761 
762  op->async = NULL;
764  "Notifying client that we started the ARM service\n");
767  op);
768  if (NULL != op->result_cont)
769  op->result_cont(op->cont_cls,
771  op->starting_ret);
772  GNUNET_free(op);
773 }
774 
775 
786 struct GNUNET_ARM_Operation *
788  struct GNUNET_ARM_Handle *h,
789  const char *service_name,
790  enum GNUNET_OS_InheritStdioFlags std_inheritance,
792  void *cont_cls)
793 {
794  struct GNUNET_ARM_Operation *op;
795  enum GNUNET_ARM_Result ret;
796 
797  LOG(GNUNET_ERROR_TYPE_DEBUG, "Starting service `%s'\n", service_name);
798  if (0 != strcasecmp("arm", service_name))
799  return change_service(h,
800  service_name,
801  cont,
802  cont_cls,
804 
805  /* Possible cases:
806  * 1) We're connected to ARM already. Invoke the callback immediately.
807  * 2) We're not connected to ARM.
808  * Cancel any reconnection attempts temporarily, then perform
809  * a service test.
810  */
811  if (GNUNET_YES == h->currently_up)
812  {
813  LOG(GNUNET_ERROR_TYPE_DEBUG, "ARM is already running\n");
814  op = GNUNET_new(struct GNUNET_ARM_Operation);
815  op->h = h;
816  op->result_cont = cont;
817  op->cont_cls = cont_cls;
820  op);
822  return op;
823  }
824  /* This is an inherently uncertain choice, as it is of course
825  theoretically possible that ARM is up and we just did not
826  yet complete the MQ handshake. However, given that users
827  are unlikely to hammer 'gnunet-arm -s' on a busy system,
828  the above check should catch 99.99% of the cases where ARM
829  is already running. */
830  LOG(GNUNET_ERROR_TYPE_DEBUG, "Starting ARM service\n");
831  ret = start_arm_service(h, std_inheritance);
832  if (GNUNET_ARM_RESULT_STARTING == ret)
833  reconnect_arm(h);
834  op = GNUNET_new(struct GNUNET_ARM_Operation);
835  op->h = h;
836  op->result_cont = cont;
837  op->cont_cls = cont_cls;
840  op);
841  op->starting_ret = ret;
843  return op;
844 }
845 
846 
861 struct GNUNET_ARM_Operation *
863  const char *service_name,
865  void *cont_cls)
866 {
867  struct GNUNET_ARM_Operation *op;
868 
869  LOG(GNUNET_ERROR_TYPE_DEBUG, "Stopping service `%s'\n", service_name);
870  op = change_service(h,
871  service_name,
872  cont,
873  cont_cls,
875  if (NULL == op)
876  return NULL;
877  /* If the service is ARM, set a flag as we will use MQ errors
878  to detect that the process is really gone. */
879  if (0 == strcasecmp(service_name, "arm"))
880  op->is_arm_stop = GNUNET_YES;
881  return op;
882 }
883 
884 
893 struct GNUNET_ARM_Operation *
896  void *cont_cls)
897 {
898  struct GNUNET_ARM_Operation *op;
899  struct GNUNET_MQ_Envelope *env;
900  struct GNUNET_ARM_Message *msg;
901 
902  LOG(GNUNET_ERROR_TYPE_DEBUG, "Requesting LIST from ARM service\n");
903  if (0 == h->request_id_counter)
904  h->request_id_counter++;
905  op = GNUNET_new(struct GNUNET_ARM_Operation);
906  op->h = h;
907  op->list_cont = cont;
908  op->cont_cls = cont_cls;
909  op->id = h->request_id_counter++;
912  op);
914  msg->reserved = htonl(0);
915  msg->request_id = GNUNET_htonll(op->id);
916  GNUNET_MQ_send(h->mq, env);
917  return op;
918 }
919 
920 
921 /* 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:757
struct GNUNET_ARM_Operation * next
This is a doubly-linked list.
Definition: arm_api.c:44
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:105
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:75
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:900
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:286
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition: arm_api.c:140
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:304
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:762
#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:107
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:381
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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:96
static void reconnect_arm_task(void *cls)
Task scheduled to try to re-connect to arm.
Definition: arm_api.c:176
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:100
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:663
#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:69
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:68
void GNUNET_ARM_disconnect(struct GNUNET_ARM_Handle *h)
Disconnect from the ARM service (if connected) and destroy the context.
Definition: arm_api.c:505
#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:113
#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:74
static void notify_running(void *cls)
Task run to notify application that ARM is already up.
Definition: arm_api.c:732
GNUNET_ARM_ConnectionStatusCallback conn_status
Callback to invoke on connection/disconnection.
Definition: arm_api.c:120
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:1237
struct GNUNET_ARM_Message arm_msg
Reply to client, of type is GNUNET_MESSAGE_TYPE_ARM_RESULT, with an ID.
Definition: arm.h:88
Tried to start a service, but that failed for some reason.
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:862
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:93
#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:690
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:1264
static void conn_status(void *cls, int connected)
Function called whenever we connect to or disconnect from ARM.
Definition: gnunet-arm.c:296
GNUNET_ARM_ServiceListCallback list_cont
Callback for service list requests.
Definition: arm_api.c:64
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:894
struct GNUNET_MessageHeader header
Reply to client, type is GNUNET_MESSAGE_TYPE_ARM_RESULT or GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT.
Definition: arm.h:63
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:192
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:480
struct GNUNET_ARM_Operation * operation_pending_head
Head of doubly-linked list of pending operations.
Definition: arm_api.c:110
static void handle_arm_result(void *cls, const struct GNUNET_ARM_ResultMessage *res)
Handler for ARM replies.
Definition: arm_api.c:247
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:135
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:549
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:787
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#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:79
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:102
struct GNUNET_ARM_Operation * prev
This is a doubly-linked list.
Definition: arm_api.c:49
#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:125
Message was sent successfully.
Handle to a message queue.
Definition: mq.c:84
struct GNUNET_ARM_Handle * h
ARM handle.
Definition: arm_api.c:54
uint64_t request_id_counter
Counter for request identifiers.
Definition: arm_api.c:151
#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:145
Reply from ARM to client.
Definition: arm.h:84
int currently_up
Have we detected that ARM is up?
Definition: arm_api.c:156
configuration data
Definition: configuration.c:83
enum GNUNET_ARM_Result starting_ret
Result of this operation for notify_starting().
Definition: arm_api.c:84
int is_arm_stop
Is this an operation to stop the ARM service?
Definition: arm_api.c:89
Entry in list of pending tasks.
Definition: scheduler.c:131
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:228
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:821
#define GNUNET_YES
Definition: gnunet_common.h:77
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:351
struct GNUNET_ARM_Operation * operation_pending_tail
Tail of doubly-linked list of pending operations.
Definition: arm_api.c:115
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:431
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:336
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:59
#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:956
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:405