GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-helper-testbed.c File Reference

Helper binary that is started from a remote controller to start gnunet-service-testbed. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_testing_lib.h"
#include "gnunet_testbed_service.h"
#include "testbed_helper.h"
#include "testbed_api.h"
#include <zlib.h>
Include dependency graph for gnunet-helper-testbed.c:

Go to the source code of this file.

Data Structures

struct  WriteContext
 Context for a single write on a chunk of memory. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log (kind, __VA_ARGS__)
 Generic logging shortcut. More...
 
#define LOG_DEBUG(...)   LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
 Debug logging shorthand. More...
 
#define PIPE_CONTROL   GNUNET_NO
 We need pipe control only on WINDOWS. More...
 

Functions

static void shutdown_task (void *cls)
 Task to shut down cleanly. More...
 
static void write_task (void *cls)
 Task to write to the standard out. More...
 
static void child_death_task (void *cls)
 Task triggered whenever we receive a SIGCHLD (child process died). More...
 
static int tokenizer_cb (void *cls, const struct GNUNET_MessageHeader *message)
 Functions with this signature are called whenever a complete message is received by the tokenizer. More...
 
static void read_task (void *cls)
 Task to read from stdin. More...
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
 Main function that will be run. More...
 
static void sighandler_child_death ()
 Signal handler called for SIGCHLD. More...
 
int main (int argc, char **argv)
 Main function. More...
 

Variables

static struct GNUNET_TESTING_Systemtest_system
 Handle to the testing system. More...
 
struct GNUNET_MessageStreamTokenizertokenizer
 Our message stream tokenizer. More...
 
static struct GNUNET_DISK_FileHandlestdin_fd
 Disk handle from stdin. More...
 
static struct GNUNET_DISK_FileHandlestdout_fd
 Disk handle for stdout. More...
 
static struct GNUNET_OS_Processtestbed
 The process handle to the testbed service. More...
 
static struct GNUNET_DISK_PipeHandlesigpipe
 Pipe used to communicate shutdown via signal. More...
 
static struct GNUNET_SCHEDULER_Taskread_task_id
 Task identifier for the read task. More...
 
static struct GNUNET_SCHEDULER_Taskwrite_task_id
 Task identifier for the write task. More...
 
static struct GNUNET_SCHEDULER_Taskchild_death_task_id
 Task to kill the child. More...
 
static int done_reading
 Are we done reading messages from stdin? More...
 
static int status
 Result to return in case we fail. More...
 

Detailed Description

Helper binary that is started from a remote controller to start gnunet-service-testbed.

This binary also receives configuration from the remove controller which is put in a temporary location with ports and paths fixed so that gnunet-service-testbed runs without any hurdles.

This helper monitors for three termination events. They are: (1)The stdin of the helper is closed for reading; (2)the helper received SIGTERM/SIGINT; (3)the testbed crashed. In case of events 1 and 2 the helper kills the testbed service. When testbed crashed (event 3), the helper should send a SIGTERM to its own process group; this behaviour will help terminate any child processes (peers) testbed has started and prevents them from leaking and running forever.

Author
Sree Harsha Totakura sreeh.nosp@m.arsh.nosp@m.a@tot.nosp@m.akur.nosp@m.a.in

Definition in file gnunet-helper-testbed.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log (kind, __VA_ARGS__)

Generic logging shortcut.

Definition at line 52 of file gnunet-helper-testbed.c.

Referenced by tokenizer_cb(), and write_task().

◆ LOG_DEBUG

#define LOG_DEBUG (   ...)    LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)

Debug logging shorthand.

Definition at line 57 of file gnunet-helper-testbed.c.

Referenced by child_death_task(), read_task(), run(), shutdown_task(), and tokenizer_cb().

◆ PIPE_CONTROL

#define PIPE_CONTROL   GNUNET_NO

We need pipe control only on WINDOWS.

Definition at line 63 of file gnunet-helper-testbed.c.

Referenced by tokenizer_cb().

Function Documentation

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Task to shut down cleanly.

Parameters
clsNULL

Definition at line 150 of file gnunet-helper-testbed.c.

References WriteContext::data, GNUNET_break, GNUNET_DISK_file_close(), GNUNET_free, GNUNET_MST_destroy(), GNUNET_OK, GNUNET_OS_process_destroy(), GNUNET_OS_process_kill(), GNUNET_OS_process_wait(), GNUNET_SCHEDULER_cancel(), GNUNET_TERM_SIG, GNUNET_TESTING_system_destroy(), GNUNET_YES, and LOG_DEBUG.

Referenced by run().

151 {
152  LOG_DEBUG ("Shutting down\n");
153  if (NULL != testbed)
154  {
155  LOG_DEBUG ("Killing testbed\n");
157  }
158  if (NULL != read_task_id)
159  {
161  read_task_id = NULL;
162  }
163  if (NULL != write_task_id)
164  {
165  struct WriteContext *wc;
166 
168  write_task_id = NULL;
169  GNUNET_free (wc->data);
170  GNUNET_free (wc);
171  }
172  if (NULL != child_death_task_id)
173  {
175  child_death_task_id = NULL;
176  }
177  if (NULL != stdin_fd)
179  if (NULL != stdout_fd)
182  tokenizer = NULL;
183  if (NULL != testbed)
184  {
187  testbed = NULL;
188  }
189  if (NULL != test_system)
190  {
192  test_system = NULL;
193  }
194 }
static struct GNUNET_OS_Process * testbed
The process handle to the testbed service.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1345
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:287
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_DISK_FileHandle * stdout_fd
Disk handle for stdout.
static struct GNUNET_DISK_FileHandle * stdin_fd
Disk handle from stdin.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:411
static struct GNUNET_TESTING_System * test_system
Handle to the testing system.
static struct GNUNET_SCHEDULER_Task * write_task_id
Task identifier for the write task.
#define LOG_DEBUG(...)
Debug logging shorthand.
void GNUNET_TESTING_system_destroy(struct GNUNET_TESTING_System *system, int remove_paths)
Free system resources.
Definition: testing.c:534
static struct GNUNET_SCHEDULER_Task * read_task_id
Task identifier for the read task.
int GNUNET_OS_process_wait(struct GNUNET_OS_Process *proc)
Wait for a process to terminate.
Definition: os_priority.c:1000
struct GNUNET_MessageStreamTokenizer * tokenizer
Our message stream tokenizer.
#define GNUNET_YES
Definition: gnunet_common.h:77
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:242
#define GNUNET_free(ptr)
Wrapper around free.
void * data
The data to write.
int GNUNET_OS_process_kill(struct GNUNET_OS_Process *proc, int sig)
Sends a signal to the process.
Definition: os_priority.c:225
static struct GNUNET_SCHEDULER_Task * child_death_task_id
Task to kill the child.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Context for a single write on a chunk of memory.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_task()

static void write_task ( void *  cls)
static

Task to write to the standard out.

Parameters
clsthe WriteContext

Definition at line 203 of file gnunet-helper-testbed.c.

References WriteContext::data, GNUNET_assert, GNUNET_DISK_file_write(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_SCHEDULER_add_write_file(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, WriteContext::length, LOG, and WriteContext::pos.

Referenced by tokenizer_cb().

204 {
205  struct WriteContext *wc = cls;
206  ssize_t bytes_wrote;
207 
208  GNUNET_assert (NULL != wc);
209  write_task_id = NULL;
210  bytes_wrote = GNUNET_DISK_file_write (stdout_fd,
211  wc->data + wc->pos,
212  wc->length - wc->pos);
213  if (GNUNET_SYSERR == bytes_wrote)
214  {
215  LOG (GNUNET_ERROR_TYPE_WARNING, "Cannot reply back configuration\n");
216  GNUNET_free (wc->data);
217  GNUNET_free (wc);
218  return;
219  }
220  wc->pos += bytes_wrote;
221  if (wc->pos == wc->length)
222  {
223  GNUNET_free (wc->data);
224  GNUNET_free (wc);
225  return;
226  }
228  stdout_fd,
229  &write_task,
230  wc);
231 }
size_t pos
The current position from where the write operation should begin.
#define LOG(kind,...)
Generic logging shortcut.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1669
static struct GNUNET_DISK_FileHandle * stdout_fd
Disk handle for stdout.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:820
static void write_task(void *cls)
Task to write to the standard out.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static struct GNUNET_SCHEDULER_Task * write_task_id
Task identifier for the write task.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
size_t length
The length of the data.
#define GNUNET_free(ptr)
Wrapper around free.
void * data
The data to write.
Context for a single write on a chunk of memory.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ child_death_task()

static void child_death_task ( void *  cls)
static

Task triggered whenever we receive a SIGCHLD (child process died).

Parameters
clsclosure, NULL if we need to self-restart

Definition at line 241 of file gnunet-helper-testbed.c.

References GNUNET_break, GNUNET_DISK_file_read(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log_strerror, GNUNET_NO, GNUNET_OS_process_destroy(), GNUNET_OS_process_status(), GNUNET_SCHEDULER_add_read_file(), GNUNET_SCHEDULER_shutdown(), GNUNET_SYSERR, GNUNET_TERM_SIG, GNUNET_TIME_UNIT_FOREVER_REL, LOG_DEBUG, ret, and type.

Referenced by tokenizer_cb().

242 {
243  const struct GNUNET_DISK_FileHandle *pr;
244  char c[16];
246  unsigned long code;
247  int ret;
248 
250  child_death_task_id = NULL;
251  /* consume the signal */
252  GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c)));
253  LOG_DEBUG ("Got SIGCHLD\n");
254  if (NULL == testbed)
255  {
256  GNUNET_break (0);
257  return;
258  }
260  (ret = GNUNET_OS_process_status (testbed, &type, &code)));
261  if (GNUNET_NO != ret)
262  {
264  testbed = NULL;
265  /* Send SIGTERM to our process group */
266  if (0 != kill (0, GNUNET_TERM_SIG))
267  {
269  GNUNET_SCHEDULER_shutdown (); /* Couldn't send the signal, we shutdown frowning */
270  }
271  return;
272  }
273  LOG_DEBUG ("Child hasn't died. Resuming to monitor its status\n");
276  pr,
278  NULL);
279 }
static struct GNUNET_OS_Process * testbed
The process handle to the testbed service.
void GNUNET_OS_process_destroy(struct GNUNET_OS_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition: os_priority.c:287
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:732
int GNUNET_OS_process_status(struct GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Retrieve the status of a process, waiting on it if dead.
Definition: os_priority.c:963
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
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:1636
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1753
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
GNUNET_OS_ProcessStatusType
Process status types.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
The reading-end of a pipe.
#define LOG_DEBUG(...)
Debug logging shorthand.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate shutdown via signal.
static void child_death_task(void *cls)
Task triggered whenever we receive a SIGCHLD (child process died).
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:242
Handle used to access files (and pipes).
static struct GNUNET_SCHEDULER_Task * child_death_task_id
Task to kill the child.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tokenizer_cb()

static int tokenizer_cb ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Functions with this signature are called whenever a complete message is received by the tokenizer.

Do not call #GNUNET_mst_destroy() in this callback

Parameters
clsidentification of the client
messagethe actual message
Returns
GNUNET_OK on success, GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 295 of file gnunet-helper-testbed.c.

References cfg, child_death_task(), config, GNUNET_TESTBED_HelperInit::config_size, WriteContext::data, done_reading, ENV_TESTBED_CONFIG, getenv(), GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_CONFIGURATION_create(), GNUNET_CONFIGURATION_deserialize(), GNUNET_CONFIGURATION_destroy(), GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_serialize(), GNUNET_CONFIGURATION_write(), GNUNET_DISK_PIPE_END_READ, GNUNET_DISK_pipe_handle(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_non_null, GNUNET_malloc, GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT, GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY, GNUNET_new, GNUNET_OK, GNUNET_OS_get_libexec_binary_path(), GNUNET_OS_INHERIT_STD_ERR, GNUNET_OS_start_process(), GNUNET_realloc, GNUNET_SCHEDULER_add_read_file(), GNUNET_SCHEDULER_add_write_file(), GNUNET_SCHEDULER_shutdown(), GNUNET_strdup, GNUNET_strlcpy(), GNUNET_SYSERR, GNUNET_TESTBED_compress_config_(), GNUNET_TESTING_configuration_create(), GNUNET_TESTING_PREFIX, GNUNET_TESTING_system_create(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, hostname, GNUNET_TESTBED_HelperInit::hostname_size, WriteContext::length, LOG, LOG_DEBUG, msg, PIPE_CONTROL, ret, GNUNET_MessageHeader::size, status, GNUNET_TESTBED_HelperInit::trusted_ip_size, GNUNET_MessageHeader::type, and write_task().

Referenced by run().

296 {
297  const struct GNUNET_TESTBED_HelperInit *msg;
298  struct GNUNET_TESTBED_HelperReply *reply;
300  struct WriteContext *wc;
301  char *binary;
302  char *trusted_ip;
303  char *hostname;
304  char *config;
305  char *xconfig;
306  char *evstr;
307  // char *str;
308  size_t config_size;
309  uLongf ul_config_size;
310  size_t xconfig_size;
311  uint16_t trusted_ip_size;
312  uint16_t hostname_size;
313  uint16_t msize;
314 
315  msize = ntohs (message->size);
316  if ((sizeof(struct GNUNET_TESTBED_HelperInit) >= msize) ||
317  (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT != ntohs (message->type)))
318  {
319  LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
320  goto error;
321  }
322  msg = (const struct GNUNET_TESTBED_HelperInit *) message;
323  trusted_ip_size = ntohs (msg->trusted_ip_size);
324  trusted_ip = (char *) &msg[1];
325  if ('\0' != trusted_ip[trusted_ip_size])
326  {
327  LOG (GNUNET_ERROR_TYPE_WARNING, "Trusted IP cannot be empty -- exiting\n");
328  goto error;
329  }
330  hostname_size = ntohs (msg->hostname_size);
331  if ((sizeof(struct GNUNET_TESTBED_HelperInit) + trusted_ip_size + 1
332  + hostname_size) >= msize)
333  {
334  GNUNET_break (0);
335  LOG (GNUNET_ERROR_TYPE_WARNING, "Received unexpected message -- exiting\n");
336  goto error;
337  }
338  ul_config_size = (uLongf) ntohs (msg->config_size);
339  config = GNUNET_malloc (ul_config_size);
340  xconfig_size = msize - (trusted_ip_size + 1 + hostname_size
341  + sizeof(struct GNUNET_TESTBED_HelperInit));
342  int ret = uncompress ((Bytef *) config,
343  &ul_config_size,
344  (const Bytef *) (trusted_ip + trusted_ip_size + 1
345  + hostname_size),
346  (uLongf) xconfig_size);
347  if (Z_OK != ret)
348  {
349  switch (ret)
350  {
351  case Z_MEM_ERROR:
352  LOG (GNUNET_ERROR_TYPE_ERROR, "Not enough memory for decompression\n");
353  break;
354 
355  case Z_BUF_ERROR:
356  LOG (GNUNET_ERROR_TYPE_ERROR, "Output buffer too small\n");
357  break;
358 
359  case Z_DATA_ERROR:
360  LOG (GNUNET_ERROR_TYPE_ERROR, "Data corrupted/incomplete\n");
361  break;
362 
363  default:
364  GNUNET_break (0);
365  }
367  "Error while uncompressing config -- exiting\n");
368  GNUNET_free (config);
369  goto error;
370  }
372  if (GNUNET_OK !=
373  GNUNET_CONFIGURATION_deserialize (cfg, config, ul_config_size, NULL))
374  {
375  LOG (GNUNET_ERROR_TYPE_ERROR, "Unable to deserialize config -- exiting\n");
376  GNUNET_free (config);
377  goto error;
378  }
379  GNUNET_free (config);
380  hostname = NULL;
381  if (0 != hostname_size)
382  {
383  hostname = GNUNET_malloc (hostname_size + 1);
384  GNUNET_strlcpy (hostname,
385  ((char *) &msg[1]) + trusted_ip_size + 1,
386  hostname_size + 1);
387  }
388  /* unset GNUNET_TESTING_PREFIX if present as it is more relevant for testbed */
389  evstr = getenv (GNUNET_TESTING_PREFIX);
390  if (NULL != evstr)
391  {
392  /* unsetting the variable will invalidate the pointer! */
393  evstr = GNUNET_strdup (evstr);
394  GNUNET_break (0 == unsetenv (GNUNET_TESTING_PREFIX));
395  }
396  test_system =
397  GNUNET_TESTING_system_create ("testbed-helper", trusted_ip, hostname, NULL);
398  if (NULL != evstr)
399  {
400  char *evar;
401 
402  GNUNET_asprintf (&evar, GNUNET_TESTING_PREFIX "=%s", evstr);
403  GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
404  see putenv(): becomes part of envrionment! */
405  GNUNET_free (evstr);
406  evstr = NULL;
407  }
408  GNUNET_free_non_null (hostname);
409  hostname = NULL;
410  GNUNET_assert (NULL != test_system);
415  "PATHS",
416  "DEFAULTCONFIG",
417  &config));
418  if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config))
419  {
421  "Unable to write config file: %s -- exiting\n",
422  config);
424  GNUNET_free (config);
425  goto error;
426  }
427  LOG_DEBUG ("Staring testbed with config: %s\n", config);
428  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-testbed");
429  {
430  char *evar;
431 
432  /* expose testbed configuration through env variable */
433  GNUNET_asprintf (&evar, "%s=%s", ENV_TESTBED_CONFIG, config);
434  GNUNET_assert (0 == putenv (evar)); /* consumes 'evar',
435  see putenv(): becomes part of envrionment! */
436  evstr = NULL;
437  }
439  GNUNET_OS_INHERIT_STD_ERR /*verbose? */,
440  NULL,
441  NULL,
442  NULL,
443  binary,
444  "gnunet-service-testbed",
445  "-c",
446  config,
447  NULL);
448  GNUNET_free (binary);
449  GNUNET_free (config);
450  if (NULL == testbed)
451  {
453  "Error starting gnunet-service-testbed -- exiting\n");
455  goto error;
456  }
458  config = GNUNET_CONFIGURATION_serialize (cfg, &config_size);
460  cfg = NULL;
461  xconfig_size =
462  GNUNET_TESTBED_compress_config_ (config, config_size, &xconfig);
463  GNUNET_free (config);
464  wc = GNUNET_new (struct WriteContext);
465  wc->length = xconfig_size + sizeof(struct GNUNET_TESTBED_HelperReply);
466  reply = GNUNET_realloc (xconfig, wc->length);
467  memmove (&reply[1], reply, xconfig_size);
468  reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY);
469  reply->header.size = htons ((uint16_t) wc->length);
470  reply->config_size = htons ((uint16_t) config_size);
471  wc->data = reply;
473  stdout_fd,
474  &write_task,
475  wc);
480  NULL);
481  return GNUNET_OK;
482 
483 error:
486  return GNUNET_SYSERR;
487 }
When this flag is set, the child process will inherit stderr of the parent.
Definition: gnunet_os_lib.h:91
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_OS_Process * testbed
The process handle to the testbed service.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
int GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
#define LOG(kind,...)
Generic logging shortcut.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_OS_Process * GNUNET_OS_start_process(int pipe_control, enum GNUNET_OS_InheritStdioFlags std_inheritance, struct GNUNET_DISK_PipeHandle *pipe_stdin, struct GNUNET_DISK_PipeHandle *pipe_stdout, struct GNUNET_DISK_PipeHandle *pipe_stderr, const char *filename,...)
Start a process.
Definition: os_priority.c:687
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_TESTING_PREFIX
The environmental variable, if set, that dictates where testing should place generated peer configura...
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:1669
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:1636
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_DISK_FileHandle * stdout_fd
Disk handle for stdout.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Initialization message for gnunet-helper-testbed to start testbed service.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_TESTING_configuration_create(struct GNUNET_TESTING_System *system, struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new configuration using the given configuration as a template; ports and paths will be modif...
Definition: testing.c:1145
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1753
static int status
Result to return in case we fail.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
static void write_task(void *cls)
Task to write to the standard out.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
static const struct GNUNET_CONFIGURATION_Handle * config
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
The reading-end of a pipe.
static struct GNUNET_TESTING_System * test_system
Handle to the testing system.
uint16_t hostname_size
The hostname size excluding the NULL termination character - strlen (hostname); cannot be zero...
Reply message from helper process.
static struct GNUNET_SCHEDULER_Task * write_task_id
Task identifier for the write task.
#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_INIT
The initialization message towards gnunet-testbed-helper.
#define LOG_DEBUG(...)
Debug logging shorthand.
struct GNUNET_TESTING_System * GNUNET_TESTING_system_create(const char *testdir, const char *trusted_ip, const char *hostname, const struct GNUNET_TESTING_SharedService *shared_services)
Create a system handle.
Definition: testing.c:453
#define GNUNET_MESSAGE_TYPE_TESTBED_HELPER_REPLY
The reply message from gnunet-testbed-helper.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
char * getenv()
#define PIPE_CONTROL
We need pipe control only on WINDOWS.
size_t GNUNET_TESTBED_compress_config_(const char *config, size_t size, char **xconfig)
Compresses given configuration using zlib compress.
Definition: testbed_api.c:1757
char * GNUNET_CONFIGURATION_serialize(const struct GNUNET_CONFIGURATION_Handle *cfg, size_t *size)
Serializes the given configuration.
static char * hostname
Our hostname; we give this to all the peers we start.
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate shutdown via signal.
configuration data
Definition: configuration.c:85
uint16_t trusted_ip_size
The controller hostname size excluding the NULL termination character - strlen (hostname); cannot be ...
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 void child_death_task(void *cls)
Task triggered whenever we receive a SIGCHLD (child process died).
#define GNUNET_YES
Definition: gnunet_common.h:77
int GNUNET_CONFIGURATION_deserialize(struct GNUNET_CONFIGURATION_Handle *cfg, const char *mem, size_t size, const char *basedir)
De-serializes configuration.
size_t length
The length of the data.
static int done_reading
Are we done reading messages from stdin?
uint16_t config_size
The size of the uncompressed configuration.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:219
#define ENV_TESTBED_CONFIG
The environmental variable which when available refers to the configuration file the local testbed co...
Definition: testbed.h:776
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void * data
The data to write.
static struct GNUNET_SCHEDULER_Task * child_death_task_id
Task to kill the child.
Context for a single write on a chunk of memory.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_task()

static void read_task ( void *  cls)
static

Task to read from stdin.

Parameters
clsNULL

Definition at line 496 of file gnunet-helper-testbed.c.

References buf, done_reading, GNUNET_break, GNUNET_break_op, GNUNET_DISK_file_read(), GNUNET_MAX_MESSAGE_SIZE, GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_file(), GNUNET_SCHEDULER_shutdown(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, and LOG_DEBUG.

Referenced by run().

497 {
499  ssize_t sread;
500 
501  read_task_id = NULL;
502  sread = GNUNET_DISK_file_read (stdin_fd, buf, sizeof(buf));
503  if ((GNUNET_SYSERR == sread) || (0 == sread))
504  {
505  LOG_DEBUG ("STDIN closed\n");
507  return;
508  }
509  if (GNUNET_YES == done_reading)
510  {
511  /* didn't expect any more data! */
512  GNUNET_break_op (0);
514  return;
515  }
516  LOG_DEBUG ("Read %u bytes\n", (unsigned int) sread);
517  /* FIXME: could introduce a GNUNET_MST_read2 to read
518  directly from 'stdin_fd' and save a memcpy() here */
519  if (GNUNET_OK !=
521  {
522  GNUNET_break (0);
524  return;
525  }
526  read_task_id /* No timeout while reading */
528  stdin_fd,
529  &read_task,
530  NULL);
531 }
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:732
#define GNUNET_NO
Definition: gnunet_common.h:78
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:1636
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_DISK_FileHandle * stdin_fd
Disk handle from stdin.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static char buf[2048]
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
int 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:114
#define LOG_DEBUG(...)
Debug logging shorthand.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static struct GNUNET_SCHEDULER_Task * read_task_id
Task identifier for the read task.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct GNUNET_MessageStreamTokenizer * tokenizer
Our message stream tokenizer.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int done_reading
Are we done reading messages from stdin?
static void read_task(void *cls)
Task to read from stdin.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Main function that will be run.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cfgconfiguration

Definition at line 543 of file gnunet-helper-testbed.c.

References GNUNET_DISK_get_handle_from_native(), GNUNET_MST_create(), GNUNET_SCHEDULER_add_read_file(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_TIME_UNIT_FOREVER_REL, LOG_DEBUG, read_task(), shutdown_task(), and tokenizer_cb().

Referenced by main().

547 {
548  LOG_DEBUG ("Starting testbed helper...\n");
553  stdin_fd,
554  &read_task,
555  NULL);
557 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
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:1636
static struct GNUNET_DISK_FileHandle * stdout_fd
Disk handle for stdout.
static struct GNUNET_DISK_FileHandle * stdin_fd
Disk handle from stdin.
static int tokenizer_cb(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer...
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:85
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void shutdown_task(void *cls)
Task to shut down cleanly.
#define LOG_DEBUG(...)
Debug logging shorthand.
static struct GNUNET_SCHEDULER_Task * read_task_id
Task identifier for the read task.
struct GNUNET_MessageStreamTokenizer * tokenizer
Our message stream tokenizer.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_get_handle_from_native(FILE *fd)
Get a handle from a native FD.
Definition: disk.c:1397
static void read_task(void *cls)
Task to read from stdin.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sighandler_child_death()

static void sighandler_child_death ( )
static

Signal handler called for SIGCHLD.

Definition at line 564 of file gnunet-helper-testbed.c.

References GNUNET_break, GNUNET_DISK_file_write(), GNUNET_DISK_PIPE_END_WRITE, and GNUNET_DISK_pipe_handle().

Referenced by main().

565 {
566  static char c;
567  int old_errno; /* back-up errno */
568 
569  old_errno = errno;
570  GNUNET_break (
571  1 ==
574  &c,
575  sizeof(c)));
576  errno = old_errno;
577 }
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_DISK_FileHandle * GNUNET_DISK_pipe_handle(const struct GNUNET_DISK_PipeHandle *p, enum GNUNET_DISK_PipeEnd n)
Get the handle to a particular pipe end.
Definition: disk.c:1753
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:820
The writing-end of a pipe.
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate shutdown via signal.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Main function.

Parameters
argcthe number of command line arguments
argvcommand line arg array
Returns
return code

Definition at line 588 of file gnunet-helper-testbed.c.

References GNUNET_break, GNUNET_DISK_pipe(), GNUNET_DISK_pipe_close(), GNUNET_GETOPT_OPTION_END, GNUNET_NO, GNUNET_OK, GNUNET_PROGRAM_run(), GNUNET_SIGCHLD, GNUNET_SIGNAL_handler_install(), GNUNET_SIGNAL_handler_uninstall(), ret, run(), sighandler_child_death(), and status.

589 {
590  struct GNUNET_SIGNAL_Context *shc_chld;
593  int ret;
594 
595  status = GNUNET_OK;
596  if (NULL ==
598  {
599  GNUNET_break (0);
600  return 1;
601  }
602  shc_chld =
604  ret = GNUNET_PROGRAM_run (argc,
605  argv,
606  "gnunet-helper-testbed",
607  "Helper for starting gnunet-service-testbed",
608  options,
609  &run,
610  NULL);
612  shc_chld = NULL;
614  if (GNUNET_OK != ret)
615  return 1;
616  return (GNUNET_OK == status) ? 0 : 1;
617 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define GNUNET_SIGCHLD
Definition: platform.h:42
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void GNUNET_SIGNAL_handler_uninstall(struct GNUNET_SIGNAL_Context *ctx)
Uninstall a previously installed signal hander.
Definition: signal.c:77
Definition of a command line option.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static int status
Result to return in case we fail.
struct GNUNET_DISK_PipeHandle * GNUNET_DISK_pipe(int blocking_read, int blocking_write, int inherit_read, int inherit_write)
Creates an interprocess channel.
Definition: disk.c:1526
struct GNUNET_SIGNAL_Context * GNUNET_SIGNAL_handler_install(int signal, GNUNET_SIGNAL_Handler handler)
Install a signal handler that will be run if the given signal is received.
Definition: signal.c:51
int GNUNET_DISK_pipe_close(struct GNUNET_DISK_PipeHandle *p)
Closes an interprocess channel.
Definition: disk.c:1715
static struct GNUNET_DISK_PipeHandle * sigpipe
Pipe used to communicate shutdown via signal.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
static void sighandler_child_death()
Signal handler called for SIGCHLD.
Here is the call graph for this function:

Variable Documentation

◆ test_system

struct GNUNET_TESTING_System* test_system
static

Handle to the testing system.

Definition at line 91 of file gnunet-helper-testbed.c.

◆ tokenizer

struct GNUNET_MessageStreamTokenizer* tokenizer

Our message stream tokenizer.

Definition at line 96 of file gnunet-helper-testbed.c.

◆ stdin_fd

struct GNUNET_DISK_FileHandle* stdin_fd
static

Disk handle from stdin.

Definition at line 101 of file gnunet-helper-testbed.c.

◆ stdout_fd

struct GNUNET_DISK_FileHandle* stdout_fd
static

Disk handle for stdout.

Definition at line 106 of file gnunet-helper-testbed.c.

◆ testbed

struct GNUNET_OS_Process* testbed
static

The process handle to the testbed service.

Definition at line 111 of file gnunet-helper-testbed.c.

◆ sigpipe

struct GNUNET_DISK_PipeHandle* sigpipe
static

Pipe used to communicate shutdown via signal.

Definition at line 116 of file gnunet-helper-testbed.c.

◆ read_task_id

struct GNUNET_SCHEDULER_Task* read_task_id
static

Task identifier for the read task.

Definition at line 121 of file gnunet-helper-testbed.c.

◆ write_task_id

struct GNUNET_SCHEDULER_Task* write_task_id
static

Task identifier for the write task.

Definition at line 126 of file gnunet-helper-testbed.c.

◆ child_death_task_id

struct GNUNET_SCHEDULER_Task* child_death_task_id
static

Task to kill the child.

Definition at line 131 of file gnunet-helper-testbed.c.

◆ done_reading

int done_reading
static

Are we done reading messages from stdin?

Definition at line 136 of file gnunet-helper-testbed.c.

Referenced by read_task(), and tokenizer_cb().

◆ status

int status
static

Result to return in case we fail.

Definition at line 141 of file gnunet-helper-testbed.c.

Referenced by main(), and tokenizer_cb().