GNUnet  0.19.0
Helper library

Dealing with SUID helper processes. More...

Collaboration diagram for Helper library:

Typedefs

typedef void(* GNUNET_HELPER_ExceptionCallback) (void *cls)
 Callback that will be called when the helper process dies. More...
 
typedef void(* GNUNET_HELPER_Continuation) (void *cls, int result)
 Continuation function. More...
 

Functions

struct GNUNET_HELPER_HandleGNUNET_HELPER_start (int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
 Starts a helper and begins reading from it. More...
 
int GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill)
 Sends termination signal to the helper process. More...
 
int GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
 Reap the helper process. More...
 
void GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
 Free's the resources occupied by the helper handle. More...
 
void GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill)
 Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process. More...
 
struct GNUNET_HELPER_SendHandleGNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
 Send an message to the helper. More...
 
void GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh)
 Cancel a GNUNET_HELPER_send operation. More...
 

Detailed Description

Dealing with SUID helper processes.

Provides an API for dealing with (SUID) helper processes that communicate via GNUNET_MessageHeaders on STDIN/STDOUT.

Typedef Documentation

◆ GNUNET_HELPER_ExceptionCallback

typedef void(* GNUNET_HELPER_ExceptionCallback) (void *cls)

Callback that will be called when the helper process dies.

This is not called when the helper process is stopped using GNUNET_HELPER_stop()

Parameters
clsthe closure from GNUNET_HELPER_start()

Definition at line 64 of file gnunet_helper_lib.h.

◆ GNUNET_HELPER_Continuation

typedef void(* GNUNET_HELPER_Continuation) (void *cls, int result)

Continuation function.

Parameters
clsclosure
resultGNUNET_OK on success, GNUNET_NO if helper process died GNUNET_SYSERR during GNUNET_HELPER_destroy

Definition at line 147 of file gnunet_helper_lib.h.

Function Documentation

◆ GNUNET_HELPER_start()

struct GNUNET_HELPER_Handle* GNUNET_HELPER_start ( int  with_control_pipe,
const char *  binary_name,
char *const  binary_argv[],
GNUNET_MessageTokenizerCallback  cb,
GNUNET_HELPER_ExceptionCallback  exp_cb,
void *  cb_cls 
)

Starts a helper and begins reading from it.

The helper process is restarted when it dies except when it is stopped using GNUNET_HELPER_stop() or when the exp_cb callback is not NULL.

Parameters
with_control_pipedoes the helper support the use of a control pipe for signalling?
binary_namename of the binary to run
binary_argvNULL-terminated list of arguments to give when starting the binary (this argument must not be modified by the client for the lifetime of the helper handle)
cbfunction to call if we get messages from the helper
exp_cbthe exception callback to call. Set this to NULL if the helper process has to be restarted automatically when it dies/crashes
cb_clsclosure for the above callbacks
Returns
the new Handle, NULL on error

Definition at line 461 of file helper.c.

467 {
468  struct GNUNET_HELPER_Handle *h;
469  unsigned int c;
470 
471  h = GNUNET_new (struct GNUNET_HELPER_Handle);
472  h->with_control_pipe = with_control_pipe;
473  /* Lookup in libexec path only if we are starting gnunet helpers */
474  if (NULL != strstr (binary_name, "gnunet"))
476  else
477  h->binary_name = GNUNET_strdup (binary_name);
478  for (c = 0; NULL != binary_argv[c]; c++)
479  ;
480  h->binary_argv = GNUNET_malloc (sizeof(char *) * (c + 1));
481  for (c = 0; NULL != binary_argv[c]; c++)
482  h->binary_argv[c] = GNUNET_strdup (binary_argv[c]);
483  h->binary_argv[c] = NULL;
484  h->cb_cls = cb_cls;
485  if (NULL != cb)
486  h->mst = GNUNET_MST_create (cb, h->cb_cls);
487  h->exp_cb = exp_cb;
488  h->retry_back_off = 0;
489  start_helper (h);
490  return h;
491 }
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
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 ...
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
static void start_helper(struct GNUNET_HELPER_Handle *h)
Start the helper process.
Definition: helper.c:383
The handle to a helper process.
Definition: helper.c:78
int with_control_pipe
Does the helper support the use of a control pipe for signalling?
Definition: helper.c:157
void * cb_cls
The closure for callbacks.
Definition: helper.c:117
char ** binary_argv
NULL-terminated list of command-line arguments.
Definition: helper.c:137
char * binary_name
Binary to run.
Definition: helper.c:132
static void exp_cb(void *cls)
Callback called if there was an exception during execution of the helper.

References GNUNET_HELPER_Handle::binary_argv, GNUNET_HELPER_Handle::binary_name, GNUNET_HELPER_Handle::cb_cls, exp_cb(), GNUNET_malloc, GNUNET_MST_create(), GNUNET_new, GNUNET_OS_get_libexec_binary_path(), GNUNET_strdup, h, start_helper(), and GNUNET_HELPER_Handle::with_control_pipe.

Referenced by enable(), GNUNET_FS_directory_scan_start(), GNUNET_TESTBED_controller_start(), run(), and start_helper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HELPER_kill()

int GNUNET_HELPER_kill ( struct GNUNET_HELPER_Handle h,
int  soft_kill 
)

Sends termination signal to the helper process.

The helper process is not reaped; call GNUNET_HELPER_wait() for reaping the dead helper process.

Parameters
hthe helper handle
soft_killif GNUNET_YES, signals termination by closing the helper's stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
Returns
GNUNET_OK on success; GNUNET_SYSERR on error

Definition at line 167 of file helper.c.

168 {
170  int ret;
171 
172  while (NULL != (sh = h->sh_head))
173  {
174  GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
175  if (NULL != sh->cont)
176  sh->cont (sh->cont_cls, GNUNET_NO);
177  GNUNET_free (sh);
178  }
179  if (NULL != h->restart_task)
180  {
181  GNUNET_SCHEDULER_cancel (h->restart_task);
182  h->restart_task = NULL;
183  }
184  if (NULL != h->read_task)
185  {
186  GNUNET_SCHEDULER_cancel (h->read_task);
187  h->read_task = NULL;
188  }
189  if (NULL == h->helper_proc)
190  return GNUNET_SYSERR;
191  if (GNUNET_YES == soft_kill)
192  {
193  /* soft-kill only possible with pipes */
194  GNUNET_assert (NULL != h->helper_in);
195  ret = GNUNET_DISK_pipe_close (h->helper_in);
196  h->helper_in = NULL;
197  h->fh_to_helper = NULL;
198  return ret;
199  }
200  if (0 != GNUNET_OS_process_kill (h->helper_proc, GNUNET_TERM_SIG))
201  return GNUNET_SYSERR;
202  return GNUNET_OK;
203 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct SolverHandle * sh
enum GNUNET_GenericReturnValue GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1584
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_free(ptr)
Wrapper around free.
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:210
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:944
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:233
Entry in the queue of messages we need to transmit to the helper.
Definition: helper.c:36

References GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_DISK_pipe_close(), GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_OS_process_kill(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_TERM_SIG, GNUNET_YES, h, ret, and sh.

Referenced by cleanup(), disable(), GNUNET_TESTBED_controller_kill_(), and stop_helper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HELPER_wait()

int GNUNET_HELPER_wait ( struct GNUNET_HELPER_Handle h)

Reap the helper process.

This call is blocking (!). The helper process should either be sent a termination signal before or should be dead before calling this function

Parameters
hthe helper handle
Returns
GNUNET_OK on success; GNUNET_SYSERR on error

Definition at line 207 of file helper.c.

208 {
210  int ret;
211 
212  ret = GNUNET_SYSERR;
213  if (NULL != h->helper_proc)
214  {
215  ret = GNUNET_OS_process_wait (h->helper_proc);
216  GNUNET_OS_process_destroy (h->helper_proc);
217  h->helper_proc = NULL;
218  }
219  if (NULL != h->read_task)
220  {
221  GNUNET_SCHEDULER_cancel (h->read_task);
222  h->read_task = NULL;
223  }
224  if (NULL != h->write_task)
225  {
226  GNUNET_SCHEDULER_cancel (h->write_task);
227  h->write_task = NULL;
228  }
229  if (NULL != h->helper_in)
230  {
231  GNUNET_DISK_pipe_close (h->helper_in);
232  h->helper_in = NULL;
233  h->fh_to_helper = NULL;
234  }
235  if (NULL != h->helper_out)
236  {
237  GNUNET_DISK_pipe_close (h->helper_out);
238  h->helper_out = NULL;
239  h->fh_from_helper = NULL;
240  }
241  while (NULL != (sh = h->sh_head))
242  {
243  GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
244  if (NULL != sh->cont)
245  sh->cont (sh->cont_cls, GNUNET_NO);
246  GNUNET_free (sh);
247  }
248  /* purge MST buffer */
249  if (NULL != h->mst)
250  (void) GNUNET_MST_from_buffer (h->mst, NULL, 0, GNUNET_YES, GNUNET_NO);
251  return ret;
252 }
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:942
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:273
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:101

References GNUNET_CONTAINER_DLL_remove, GNUNET_DISK_pipe_close(), GNUNET_free, GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_OS_process_destroy(), GNUNET_OS_process_wait(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_YES, h, ret, and sh.

Referenced by cleanup(), GNUNET_TESTBED_controller_destroy_(), and stop_helper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HELPER_destroy()

void GNUNET_HELPER_destroy ( struct GNUNET_HELPER_Handle h)

Free's the resources occupied by the helper handle.

Parameters
hthe helper handle to free

Definition at line 500 of file helper.c.

501 {
502  unsigned int c;
504 
505  if (NULL != h->write_task)
506  {
507  GNUNET_SCHEDULER_cancel (h->write_task);
508  h->write_task = NULL;
509  }
510  GNUNET_assert (NULL == h->read_task);
511  GNUNET_assert (NULL == h->restart_task);
512  while (NULL != (sh = h->sh_head))
513  {
514  GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
515  if (NULL != sh->cont)
516  sh->cont (sh->cont_cls, GNUNET_SYSERR);
517  GNUNET_free (sh);
518  }
519  if (NULL != h->mst)
520  GNUNET_MST_destroy (h->mst);
521  GNUNET_free (h->binary_name);
522  for (c = 0; h->binary_argv[c] != NULL; c++)
523  GNUNET_free (h->binary_argv[c]);
524  GNUNET_free (h->binary_argv);
525  GNUNET_free (h);
526 }
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:404

References GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MST_destroy(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, h, and sh.

Referenced by disable(), GNUNET_HELPER_stop(), and GNUNET_TESTBED_controller_destroy_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HELPER_stop()

void GNUNET_HELPER_stop ( struct GNUNET_HELPER_Handle h,
int  soft_kill 
)

Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process.

Parameters
hhandle to helper to stop
soft_killif GNUNET_YES, signals termination by closing the helper's stdin; GNUNET_NO to signal termination by sending SIGTERM to helper

Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process.

Parameters
hhandle to helper to stop
soft_killif GNUNET_YES, signals termination by closing the helper's stdin; GNUNET_NO to signal termination by sending SIGTERM to helper

Definition at line 537 of file helper.c.

538 {
539  h->exp_cb = NULL;
540  stop_helper (h, soft_kill);
542 }
void GNUNET_HELPER_destroy(struct GNUNET_HELPER_Handle *h)
Free's the resources occupied by the helper handle.
Definition: helper.c:500
static void stop_helper(struct GNUNET_HELPER_Handle *h, int soft_kill)
Stop the helper process, we're closing down or had an error.
Definition: helper.c:263

References GNUNET_HELPER_destroy(), h, and stop_helper().

Referenced by cleanup(), cleanup_task(), finish_scan(), GNUNET_FS_directory_scan_abort(), helper_read(), helper_write(), LIBGNUNET_PLUGIN_TRANSPORT_DONE(), and stop_testing_system_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HELPER_send()

struct GNUNET_HELPER_SendHandle* GNUNET_HELPER_send ( struct GNUNET_HELPER_Handle h,
const struct GNUNET_MessageHeader msg,
int  can_drop,
GNUNET_HELPER_Continuation  cont,
void *  cont_cls 
)

Send an message to the helper.

Parameters
hhelper to send message to
msgmessage to send
can_dropcan the message be dropped if there is already one in the queue?
contcontinuation to run once the message is out (GNUNET_OK on success, GNUNET_NO if the helper process died, GNUNET_SYSERR during GNUNET_HELPER_destroy).
cont_clsclosure for cont
Returns
NULL if the message was dropped, otherwise handle to cancel cont (actual transmission may not be abortable)

Definition at line 614 of file helper.c.

619 {
621  uint16_t mlen;
622 
623  if (NULL == h->fh_to_helper)
624  return NULL;
625  if ((GNUNET_YES == can_drop) && (NULL != h->sh_head))
626  return NULL;
627  mlen = ntohs (msg->size);
628  sh = GNUNET_malloc (sizeof(struct GNUNET_HELPER_SendHandle) + mlen);
629  sh->msg = (const struct GNUNET_MessageHeader *) &sh[1];
630  GNUNET_memcpy (&sh[1], msg, mlen);
631  sh->h = h;
632  sh->cont = cont;
633  sh->cont_cls = cont_cls;
634  GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, h->sh_tail, sh);
635  if (NULL == h->write_task)
636  h->write_task =
638  h->fh_to_helper,
639  &helper_write,
640  h);
641 
642  return sh;
643 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_file(struct GNUNET_TIME_Relative delay, const struct GNUNET_DISK_FileHandle *wfd, 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:1658
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void helper_write(void *cls)
Write to the helper-process.
Definition: helper.c:551
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References GNUNET_CONTAINER_DLL_insert_tail, GNUNET_malloc, GNUNET_memcpy, GNUNET_SCHEDULER_add_write_file(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, h, helper_write(), msg, sh, and GNUNET_MessageHeader::size.

Referenced by GNUNET_TESTBED_controller_start(), GNUNET_TESTING_send_message_to_netjail(), handle_icmp_back(), handle_tcp_back(), handle_udp_back(), play(), request_done(), send_ack(), send_hello_beacon(), send_icmp_packet_via_tun(), send_message_to_locals(), send_tcp_packet_via_tun(), send_udp_packet_via_tun(), start_helper(), and transmit_fragment().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HELPER_send_cancel()

void GNUNET_HELPER_send_cancel ( struct GNUNET_HELPER_SendHandle sh)

Cancel a GNUNET_HELPER_send operation.

If possible, transmitting the message is also aborted, but at least 'cont' won't be called.

Parameters
shoperation to cancel

Definition at line 654 of file helper.c.

655 {
656  struct GNUNET_HELPER_Handle *h = sh->h;
657 
658  sh->cont = NULL;
659  sh->cont_cls = NULL;
660  if (0 == sh->wpos)
661  {
662  GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh);
663  GNUNET_free (sh);
664  if (NULL == h->sh_head)
665  {
666  GNUNET_SCHEDULER_cancel (h->write_task);
667  h->write_task = NULL;
668  }
669  }
670 }

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_SCHEDULER_cancel(), h, and sh.

Referenced by free_fragment_message(), and GNUNET_TESTBED_controller_kill_().

Here is the call graph for this function:
Here is the caller graph for this function: