GNUnet  0.10.x
gnunet-secretsharing-profiler.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2014 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 
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
29 #include "gnunet_testbed_service.h"
30 
34 static unsigned int num_peers = 3;
35 
39 static unsigned int threshold = 2;
40 
44 static int decrypt = GNUNET_NO;
45 
50 
55 
60 
62 
67 
69 
70 
71 static unsigned int num_connected_sessions;
72 
73 static unsigned int num_connected_decrypt;
74 
79 static struct GNUNET_TESTBED_Peer **peers;
80 
82 
83 static unsigned int num_retrieved_peer_ids;
84 
85 static unsigned int num_generated;
86 
87 static unsigned int num_decrypted;
88 
90 
91 static unsigned int verbose;
92 
94 
96 
98 
100 
101 
103 
105 
110 
114 static int in_shutdown;
115 
116 
124 static void
125 controller_cb(void *cls,
126  const struct GNUNET_TESTBED_EventInformation *event)
127 {
128  GNUNET_assert(0);
129 }
130 
131 
141 static void
144  void *ca_result,
145  const char *emsg)
146 {
147  if (NULL != emsg)
148  {
150  "testbed connect emsg: %s\n",
151  emsg);
152  GNUNET_assert(0);
153  }
154 
156 
158  "dkg: session connect complete\n");
159 
161  {
163  "dkg: all peers connected\n");
164  }
165 }
166 
167 
177 static void
180  void *ca_result,
181  const char *emsg)
182 {
183  if (NULL != emsg)
184  {
186  "testbed connect emsg: %s\n",
187  emsg);
188  GNUNET_assert(0);
189  }
190 
192 
194  "decrypt: session connect complete\n");
195 
197  {
199  "decrypt: all peers connected\n");
200  }
201 }
202 
203 
210 static void decrypt_cb(void *cls,
211  const struct GNUNET_SECRETSHARING_Plaintext *plaintext)
212 {
213  struct GNUNET_SECRETSHARING_DecryptionHandle **dhp = cls;
214  unsigned int n = dhp - decrypt_handles;
215 
216  num_decrypted++;
217 
218  *dhp = NULL;
219 
220  // we should still be connected if this is called
221  GNUNET_assert(NULL != connect_ops[n]);
222 
223  GNUNET_TESTBED_operation_done(connect_ops[n]);
224 
225  if (NULL == plaintext)
226  {
227  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "decrypt failed for peer %u\n", n);
228  return;
229  }
230  else if (0 == GNUNET_memcmp(&reference_plaintext, plaintext))
231  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "decrypt got correct result for peer %u\n", n);
232  else
233  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "decrypt got wrong result for peer %u\n", n);
234 
235  if (num_decrypted == num_peers)
236  {
237  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "every peer decrypted\n");
239  }
240 
241  *dhp = NULL;
242 }
243 
244 
245 
256 static void *
258  const struct GNUNET_CONFIGURATION_Handle *cfg)
259 {
260  struct GNUNET_SECRETSHARING_DecryptionHandle **hp = cls;
261  unsigned int n = hp - decrypt_handles;
262 
264  "decrypt connect adapter, %d peers\n",
265  num_peers);
266  *hp = GNUNET_SECRETSHARING_decrypt(cfg, shares[n], &ciphertext,
268  decrypt_cb,
269  hp);
270 
271  return *hp;
272 }
273 
274 
282 static void
284 {
285  struct GNUNET_SECRETSHARING_DecryptionHandle **dh = cls;
286  unsigned int n = dh - decrypt_handles;
287 
288  GNUNET_assert(*dh == decrypt_handles[n]);
289 
290  if (NULL != *dh)
291  {
293  *dh = NULL;
294  }
295 
296  GNUNET_assert(NULL != connect_ops[n]);
297  connect_ops[n] = NULL;
298 }
299 
300 
301 static void
302 secret_ready_cb(void *cls,
303  struct GNUNET_SECRETSHARING_Share *my_share,
304  struct GNUNET_SECRETSHARING_PublicKey *public_key,
305  unsigned int num_ready_peers,
306  const struct GNUNET_PeerIdentity *ready_peers)
307 {
308  struct GNUNET_SECRETSHARING_Session **sp = cls;
309  unsigned int n = sp - session_handles;
310  char pubkey_str[1024];
311  char *ret;
312 
313  num_generated++;
314  *sp = NULL;
315  shares[n] = my_share;
316  if (NULL == my_share)
317  {
318  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "key generation failed for peer #%u\n", n);
319  }
320  else
321  {
322  ret = GNUNET_STRINGS_data_to_string(public_key, sizeof *public_key, pubkey_str, 1024);
323  GNUNET_assert(NULL != ret);
324  *ret = '\0';
325  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "key generation successful for peer #%u, pubkey %s\n", n,
326  pubkey_str);
327 
328  /* we're the first to get the key -> store it */
329  if (num_generated == 1)
330  {
331  common_pubkey = *public_key;
332  }
333  else if (0 != GNUNET_memcmp(public_key, &common_pubkey))
334  {
335  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "generated public keys do not match\n");
337  return;
338  }
339  }
340 
341  // we should still be connected
342  GNUNET_assert(NULL != connect_ops[n]);
343 
344  // disconnect from the service, will call the disconnect callback
345  GNUNET_TESTBED_operation_done(connect_ops[n]);
346 }
347 
348 
359 static void *
361  const struct GNUNET_CONFIGURATION_Handle *cfg)
362 {
363  struct GNUNET_SECRETSHARING_Session **sp = cls;
364 
366  "connect adapter, %d peers\n",
367  num_peers);
369  num_peers,
370  peer_ids,
371  &session_id,
372  dkg_start,
373  dkg_deadline,
374  threshold,
375  &secret_ready_cb, sp);
376  return *sp;
377 }
378 
379 
380 
388 static void
390 {
391  struct GNUNET_SECRETSHARING_Session **sp = cls;
392  unsigned int n = (sp - session_handles);
393 
394  GNUNET_assert(*sp == session_handles[n]);
395 
396  if (NULL != *sp)
397  {
399  *sp = NULL;
400  }
401 
402  GNUNET_assert(NULL != connect_ops[n]);
403  connect_ops[n] = NULL;
404 
405  if (GNUNET_YES == in_shutdown)
406  return;
407 
408  // all peers received their secret
409  if (num_generated == num_peers)
410  {
411  int i;
412 
413  // only do decryption if requested by the user
414  if (GNUNET_NO == decrypt)
415  {
417  return;
418  }
419 
422 
423  // compute g^42 as the plaintext which we will decrypt and then
424  // cooperatively decrypt
427 
428  for (i = 0; i < num_peers; i++)
429  connect_ops[i] =
430  GNUNET_TESTBED_service_connect(NULL, peers[i], "secretsharing", &decrypt_connect_complete, NULL,
431  &decrypt_connect_adapter, &decrypt_disconnect_adapter, &decrypt_handles[i]);
432  }
433 }
434 
435 
445 static void
446 peer_info_cb(void *cb_cls,
448  const struct GNUNET_TESTBED_PeerInformation *pinfo,
449  const char *emsg)
450 {
451  struct GNUNET_PeerIdentity *p;
452  int i;
453 
454  GNUNET_assert(NULL == emsg);
455 
456  p = (struct GNUNET_PeerIdentity *)cb_cls;
457 
458  if (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY)
459  {
460  *p = *pinfo->result.id;
463  for (i = 0; i < num_peers; i++)
464  connect_ops[i] =
465  GNUNET_TESTBED_service_connect(NULL, peers[i], "secretsharing", session_connect_complete, NULL,
467  }
468  else
469  {
470  GNUNET_assert(0);
471  }
472 
474 }
475 
476 
482 static void
483 handle_shutdown(void *cls)
484 {
486 
487  if (NULL != connect_ops)
488  {
489  unsigned int i;
490  for (i = 0; i < num_peers; i++)
491  if (NULL != connect_ops[i])
492  {
493  // the disconnect callback will set the op to NULL
494  GNUNET_TESTBED_operation_done(connect_ops[i]);
495  }
496  GNUNET_free(connect_ops);
497  }
498 
499  // killing the testbed operation will take care of remaining
500  // service handles in the disconnect callback
501 }
502 
503 
517 static void
518 test_master(void *cls,
519  struct GNUNET_TESTBED_RunHandle *h,
520  unsigned int num_peers,
521  struct GNUNET_TESTBED_Peer **started_peers,
522  unsigned int links_succeeded,
523  unsigned int links_failed)
524 {
525  int i;
526 
527  GNUNET_log_setup("gnunet-secretsharing-profiler", "INFO", NULL);
528 
529  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "test master\n");
530 
532 
533  peers = started_peers;
534 
535  peer_ids = GNUNET_malloc(num_peers * sizeof(struct GNUNET_PeerIdentity));
536 
537  session_handles = GNUNET_new_array(num_peers, struct GNUNET_SECRETSHARING_Session *);
538  decrypt_handles = GNUNET_new_array(num_peers, struct GNUNET_SECRETSHARING_DecryptionHandle *);
539  connect_ops = GNUNET_new_array(num_peers, struct GNUNET_TESTBED_Operation *);
540  shares = GNUNET_new_array(num_peers, struct GNUNET_SECRETSHARING_Share *);
541 
542  for (i = 0; i < num_peers; i++)
543  {
544  // we do not store the returned operation, as peer_info_cb
545  // will receive it as a parameter and call GNUNET_TESTBED_operation_done.
548  peer_info_cb,
549  &peer_ids[i]);
550  }
551 }
552 
553 
554 static void
555 run(void *cls, char *const *args, const char *cfgfile,
556  const struct GNUNET_CONFIGURATION_Handle *cfg)
557 {
558  static char *session_str = "gnunet-secretsharing/test";
559  char *topology;
560  int topology_cmp_result;
561 
564 
565  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "testbed", "OVERLAY_TOPOLOGY", &topology))
566  {
567  fprintf(stderr,
568  "'OVERLAY_TOPOLOGY' not found in 'testbed' config section, "
569  "seems like you passed the wrong configuration file\n");
570  return;
571  }
572 
573  topology_cmp_result = strcasecmp(topology, "NONE");
574  GNUNET_free(topology);
575 
576  if (0 == topology_cmp_result)
577  {
578  fprintf(stderr,
579  "'OVERLAY_TOPOLOGY' set to 'NONE', "
580  "seems like you passed the wrong configuration file\n");
581  return;
582  }
583 
585  "running gnunet-secretsharing-profiler\n");
586 
587  GNUNET_CRYPTO_hash(session_str, strlen(session_str), &session_id);
588 
589  (void)GNUNET_TESTBED_test_run("gnunet-secretsharing-profiler",
590  cfgfile,
591  num_peers,
592  0,
594  NULL,
595  test_master,
596  NULL);
597 }
598 
599 
600 int
601 main(int argc, char **argv)
602 {
603  struct GNUNET_GETOPT_CommandLineOption options[] = {
605  "num-peers",
606  NULL,
607  gettext_noop("number of peers in consensus"),
608  &num_peers),
609 
611  "delay",
612  NULL,
613  gettext_noop("dkg start delay"),
614  &delay),
615 
617  "timeout",
618  NULL,
619  gettext_noop("dkg timeout"),
620  &timeout),
621 
623  "threshold",
624  NULL,
625  gettext_noop("threshold"),
626  &threshold),
627 
629  "descrypt",
630  gettext_noop("also profile decryption"),
631  &decrypt),
632 
633 
635 
637  };
638 
641  GNUNET_PROGRAM_run2(argc, argv, "gnunet-secretsharing-profiler",
642  "help",
643  options, &run, NULL, GNUNET_YES);
644  return 0;
645 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time)...
static struct GNUNET_SECRETSHARING_Plaintext reference_plaintext
static int decrypt
Should we try to decrypt a value after the key generation?
static unsigned int threshold
What should the threshold for then key be?
static unsigned int verbose
static void peer_info_cb(void *cb_cls, struct GNUNET_TESTBED_Operation *op, const struct GNUNET_TESTBED_PeerInformation *pinfo, const char *emsg)
Callback to be called when the requested peer information is available.
static unsigned int num_peers
How many peers should participate in the key generation?
static void * session_connect_adapter(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Adapter function called to establish a connection to a service.
int GNUNET_PROGRAM_run2(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls, int run_without_scheduler)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:140
union GNUNET_TESTBED_PeerInformation::@64 result
The result of the get information operation; Choose according to the pit.
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:1284
#define GNUNET_TIME_UNIT_MINUTES
One minute.
static struct GNUNET_SECRETSHARING_Session ** session_handles
Handles for secretsharing sessions.
int GNUNET_TESTBED_test_run(const char *testname, const char *cfg_filename, unsigned int num_peers, uint64_t event_mask, GNUNET_TESTBED_ControllerCallback cc, void *cc_cls, GNUNET_TESTBED_TestMaster test_master, void *test_master_cls)
Convenience method for running a "simple" test on the local system with a single call from &#39;main&#39;...
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the &#39;-V&#39; verbosity option.
enum GNUNET_TESTBED_PeerInformationType pit
Peer information type; captures which of the types in the &#39;op_result&#39; is actually in use...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int op_result(struct GNUNET_OP_Handle *h, uint64_t op_id, int64_t result_code, const void *data, uint16_t data_size, void **ctx, uint8_t cancel)
Remove an operation, and call its result callback (unless it was cancelled).
Definition: op.c:243
static void session_disconnect_adapter(void *cls, void *op_result)
Adapter function called to destroy a connection to a service.
Argument to GNUNET_TESTBED_ControllerCallback with details about the event.
A share, with all values in in host byte order.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
enum GNUNET_TESTBED_TopologyOption topology
The topology to generate.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:393
Definition of a command line option.
static void decrypt_connect_complete(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Callback to be called when a service connect operation is completed.
static void decrypt_disconnect_adapter(void *cls, void *op_result)
Adapter function called to destroy a connection to a service.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
static int ret
Final status code.
Definition: gnunet-arm.c:89
struct GNUNET_SECRETSHARING_DecryptionHandle * GNUNET_SECRETSHARING_decrypt(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SECRETSHARING_Share *share, const struct GNUNET_SECRETSHARING_Ciphertext *ciphertext, struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute deadline, GNUNET_SECRETSHARING_DecryptCallback decrypt_cb, void *decrypt_cb_cls)
Publish the given ciphertext for decryption.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
Opaque handle to an abstract operation to be executed by the testing framework.
Public key of a group sharing a secret.
struct GNUNET_PeerIdentity * id
The identity of the peer.
static struct GNUNET_TIME_Absolute dkg_start
void GNUNET_SECRETSHARING_session_destroy(struct GNUNET_SECRETSHARING_Session *s)
Destroy a secret sharing session.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_service_connect(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_ServiceConnectCompletionCallback cb, void *cb_cls, GNUNET_TESTBED_ConnectAdapter ca, GNUNET_TESTBED_DisconnectAdapter da, void *cada_cls)
Connect to a service offered by the given peer.
static unsigned int num_decrypted
int GNUNET_SECRETSHARING_plaintext_generate_i(struct GNUNET_SECRETSHARING_Plaintext *plaintext, int64_t exponent)
static struct GNUNET_TESTBED_Peer ** peers
Handles to the running peers.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
static unsigned int num_retrieved_peer_ids
static struct GNUNET_PeerIdentity * peer_ids
static void session_connect_complete(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Callback to be called when a service connect operation is completed.
static struct GNUNET_TIME_Absolute decrypt_deadline
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
static struct GNUNET_TIME_Relative timeout
When would we like to see the operation finished?
static void controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
Signature of the event handler function called by the respective event controller.
struct GNUNET_SECRETSHARING_Session * GNUNET_SECRETSHARING_create_session(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int num_peers, const struct GNUNET_PeerIdentity *peers, const struct GNUNET_HashCode *session_id, struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Absolute deadline, unsigned int threshold, GNUNET_SECRETSHARING_SecretReadyCallback cb, void *cls)
Create a session that will eventually establish a shared secret with the other peers.
void GNUNET_SECRETSHARING_decrypt_cancel(struct GNUNET_SECRETSHARING_DecryptionHandle *dh)
Cancel a decryption.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
static unsigned int num_generated
static void handle_shutdown(void *cls)
Signature of the main function of a task.
static struct GNUNET_SECRETSHARING_Share ** shares
Shares we got from the distributed key generation.
static struct GNUNET_SECRETSHARING_Ciphertext ciphertext
void GNUNET_TESTBED_operation_done(struct GNUNET_TESTBED_Operation *operation)
This function is used to signal that the event information (struct GNUNET_TESTBED_EventInformation) f...
Definition: testbed_api.c:2037
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
Session that will eventually establish a shared secred between the involved peers and allow encryptio...
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_peer_get_information(struct GNUNET_TESTBED_Peer *peer, enum GNUNET_TESTBED_PeerInformationType pit, GNUNET_TESTBED_PeerInfoCallback cb, void *cb_cls)
Request information about a peer.
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
int GNUNET_SECRETSHARING_encrypt(const struct GNUNET_SECRETSHARING_PublicKey *public_key, const struct GNUNET_SECRETSHARING_Plaintext *plaintext, struct GNUNET_SECRETSHARING_Ciphertext *result_ciphertext)
Encrypt a value.
Handle to cancel a cooperative decryption operation.
static struct GNUNET_TESTBED_Operation ** connect_ops
Connect operations, one for every peer.
static int in_shutdown
Are we performing a shutdown right now?
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int main(int argc, char **argv)
The identity of the host (wraps the signing key of the peer).
What is the identity of the peer? Returns a &#39;const struct GNUNET_PeerIdentity *&#39;. ...
static unsigned int num_connected_decrypt
configuration data
Definition: configuration.c:83
static void secret_ready_cb(void *cls, struct GNUNET_SECRETSHARING_Share *my_share, struct GNUNET_SECRETSHARING_PublicKey *public_key, unsigned int num_ready_peers, const struct GNUNET_PeerIdentity *ready_peers)
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
static unsigned int num_connected_sessions
Plain, unencrypted message that can be encrypted with a group public key.
#define GNUNET_log(kind,...)
static struct GNUNET_HashCode session_id
static struct GNUNET_SECRETSHARING_PublicKey common_pubkey
Time for absolute times used by GNUnet, in microseconds.
static void decrypt_cb(void *cls, const struct GNUNET_SECRETSHARING_Plaintext *plaintext)
Called when a decryption has succeeded.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void * decrypt_connect_adapter(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Adapter function called to establish a connection to a service.
static struct GNUNET_TIME_Absolute dkg_deadline
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
A peer controlled by the testing framework.
static struct GNUNET_SECRETSHARING_DecryptionHandle ** decrypt_handles
#define GNUNET_malloc(size)
Wrapper around malloc.
static void test_master(void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num_peers, struct GNUNET_TESTBED_Peer **started_peers, unsigned int links_succeeded, unsigned int links_failed)
Signature of a main function for a testcase.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:857
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Data returned from GNUNET_TESTBED_peer_get_information.
#define gettext_noop(String)
Definition: gettext.h:69
static struct GNUNET_TIME_Absolute decrypt_start