GNUnet  0.11.x
gnunet-cadet-profiler.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011 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  */
25 #include <stdio.h>
26 #include "platform.h"
27 #include "cadet_test_lib.h"
28 #include "gnunet_cadet_service.h"
30 
31 
32 #define PING 1
33 #define PONG 2
34 
35 
39 #define PING_PERIOD 500
40 
44 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
45 
49 #define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
50 
54 #define number_rounds sizeof(rounds) / sizeof(rounds[0])
55 
59 static float rounds[] = { 0.8, 0.6, 0.8, 0.5, 0.3, 0.8, 0.0 };
60 
65 {
70 
74  uint32_t counter;
75 
80 
84  uint32_t round_number;
85 };
86 
90 struct CadetPeer
91 {
96 
101 
106 
111 
116 
121 
126 
131 
135  int up;
136 
140  struct CadetPeer *dest;
141 
146 
151 
155  struct GNUNET_CADET_TransmitHandle *ping_ntr;
156 
157  float mean[number_rounds];
158  float var[number_rounds];
159  unsigned int pongs[number_rounds];
160  unsigned int pings[number_rounds];
161 };
162 
167 
172 
177 
182 
186 static struct CadetPeer *peers;
187 
191 static unsigned int p_ids;
192 
196 static unsigned long long peers_total;
197 
201 static unsigned long long peers_running;
202 
206 static unsigned long long peers_pinging;
207 
212 
217 
222 
226 static unsigned int current_round;
227 
231 static int do_warmup;
232 
236 static unsigned int peers_warmup;
237 
241 static int test_finished;
242 
247 
248 
257 static void
258 start_test (void *cls);
259 
260 
268 static struct GNUNET_TIME_Relative
269 delay_ms_rnd (unsigned int max)
270 {
271  unsigned int rnd;
272 
275 }
276 
277 
285 static unsigned int
287 {
288  return peer - peers;
289 }
290 
291 
295 static void
297 {
298  struct CadetPeer *peer;
299  unsigned int i;
300  unsigned int j;
301 
302  for (i = 0; i < number_rounds; i++)
303  {
304  for (j = 0; j < peers_pinging; j++)
305  {
306  peer = &peers[j];
307  fprintf (stdout,
308  "ROUND %3u PEER %3u: %10.2f / %10.2f, PINGS: %3u, PONGS: %3u\n",
309  i, j, peer->mean[i], sqrt (peer->var[i] / (peer->pongs[i] - 1)),
310  peer->pings[i], peer->pongs[i]);
311  }
312  }
313 }
314 
315 
321 static void
323 {
324  long line = (long) cls;
325  unsigned int i;
326 
328  "disconnecting cadet service, called from line %ld\n",
329  line);
330  disconnect_task = NULL;
331  for (i = 0; i < peers_total; i++)
332  {
333  if (NULL != peers[i].op)
334  GNUNET_TESTBED_operation_done (peers[i].op);
335 
336  if (peers[i].up != GNUNET_YES)
337  continue;
338 
339  if (NULL != peers[i].ch)
340  {
342  "%u: channel %p\n", i, peers[i].ch);
343  GNUNET_CADET_channel_destroy (peers[i].ch);
344  }
345  if (NULL != peers[i].warmup_ch)
346  {
348  "%u: warmup channel %p\n",
349  i, peers[i].warmup_ch);
350  GNUNET_CADET_channel_destroy (peers[i].warmup_ch);
351  }
352  if (NULL != peers[i].incoming_ch)
353  {
355  "%u: incoming channel %p\n",
356  i, peers[i].incoming_ch);
357  GNUNET_CADET_channel_destroy (peers[i].incoming_ch);
358  }
359  }
360  GNUNET_CADET_TEST_cleanup (test_ctx);
362 }
363 
364 
370 static void
371 shutdown_task (void *cls)
372 {
374  "Ending test.\n");
375  if (NULL != disconnect_task)
376  {
377  GNUNET_SCHEDULER_cancel (disconnect_task);
379  (void *) __LINE__);
380  }
381  if (NULL != round_task)
382  {
383  GNUNET_SCHEDULER_cancel (round_task);
384  round_task = NULL;
385  }
386  if (NULL != test_task)
387  {
388  GNUNET_SCHEDULER_cancel (test_task);
389  test_task = NULL;
390  }
391 }
392 
393 
399 static void
401 {
402  if (disconnect_task != NULL)
403  {
404  GNUNET_SCHEDULER_cancel (disconnect_task);
406  (void *) line);
407  }
408 }
409 
410 
420 static void
421 stats_cont (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
422 {
423  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "... collecting statistics done.\n");
425 
426  if (NULL != disconnect_task)
427  GNUNET_SCHEDULER_cancel (disconnect_task);
429  (void *) __LINE__);
430 }
431 
432 
444 static int
445 stats_iterator (void *cls,
446  const struct GNUNET_TESTBED_Peer *peer,
447  const char *subsystem,
448  const char *name,
449  uint64_t value,
450  int is_persistent)
451 {
452  uint32_t i;
453 
454  i = GNUNET_TESTBED_get_index (peer);
456  " STATS %u - %s [%s]: %llu\n",
457  i, subsystem, name,
458  (unsigned long long) value);
459 
460  return GNUNET_OK;
461 }
462 
463 
469 static void
470 collect_stats (void *cls)
471 {
473  "Start collecting statistics...\n");
475  testbed_handles,
476  NULL, NULL,
478  &stats_cont, NULL);
479 }
480 
481 
487 static void
488 finish_profiler (void *cls)
489 {
491  show_end_data ();
493 }
494 
495 
501 static void
502 adjust_running_peers (unsigned int target)
503 {
505  unsigned int delta;
506  unsigned int run;
507  unsigned int i;
508  unsigned int r;
509 
510  GNUNET_assert (target <= peers_total);
511 
512  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "adjust peers to %u\n", target);
513  if (target > peers_running)
514  {
515  delta = target - peers_running;
516  run = GNUNET_YES;
517  }
518  else
519  {
520  delta = peers_running - target;
521  run = GNUNET_NO;
522  }
523 
524  for (i = 0; i < delta; i++)
525  {
526  do
527  {
530  r += peers_pinging;
531  }
532  while (peers[r].up == run || NULL != peers[r].incoming);
533  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "St%s peer %u: %s\n",
534  run ? "arting" : "opping", r, GNUNET_i2s (&peers[r].id));
535 
536  if (NULL != peers[r].ping_task)
537  {
538  GNUNET_SCHEDULER_cancel (peers[r].ping_task);
539  peers[r].ping_task = NULL;
540  }
541  if (NULL != peers[r].ping_ntr)
542  {
543  GNUNET_CADET_notify_transmit_ready_cancel (peers[r].ping_ntr);
544  peers[r].ping_ntr = NULL;
545  }
546  peers[r].up = run;
547 
548  if (NULL != peers[r].ch)
549  GNUNET_CADET_channel_destroy (peers[r].ch);
550  peers[r].ch = NULL;
551  if (NULL != peers[r].dest)
552  {
553  if (NULL != peers[r].dest->incoming_ch)
554  GNUNET_CADET_channel_destroy (peers[r].dest->incoming_ch);
555  peers[r].dest->incoming_ch = NULL;
556  }
557 
558  op = GNUNET_TESTBED_peer_manage_service (&peers[r], testbed_handles[r],
559  "cadet", NULL, NULL, run);
560  GNUNET_break (NULL != op);
561  peers_running += run ? 1 : -1;
563  }
564 }
565 
566 
572 static void
573 next_rnd (void *cls)
574 {
576  "ROUND %u\n",
577  current_round);
578  if (0.0 == rounds[current_round])
579  {
580  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Finishing\n");
582  return;
583  }
584  adjust_running_peers (rounds[current_round] * peers_total);
585  current_round++;
586 
588  &next_rnd,
589  NULL);
590 }
591 
592 
602 static size_t
603 tmt_rdy_ping (void *cls, size_t size, void *buf);
604 
605 
613 static size_t
614 tmt_rdy_pong (void *cls, size_t size, void *buf)
615 {
616  struct CadetPingMessage *ping = cls;
617  struct CadetPingMessage *pong;
618 
619  if ((0 == size) || (NULL == buf))
620  {
621  GNUNET_free (ping);
622  return 0;
623  }
624  pong = (struct CadetPingMessage *) buf;
625  GNUNET_memcpy (pong, ping, sizeof(*ping));
626  pong->header.type = htons (PONG);
627 
628  GNUNET_free (ping);
629  return sizeof(*ping);
630 }
631 
632 
638 static void
639 ping (void *cls)
640 {
641  struct CadetPeer *peer = cls;
642 
643  peer->ping_task = NULL;
644  if (GNUNET_YES == test_finished)
645  return;
647  "%u -> %u (%u)\n",
648  get_index (peer),
649  get_index (peer->dest),
650  peer->data_sent);
651  peer->ping_ntr = GNUNET_CADET_notify_transmit_ready (peer->ch, GNUNET_NO,
653  sizeof(struct
655  &tmt_rdy_ping, peer);
656 }
657 
658 
665 static void
666 pong (struct GNUNET_CADET_Channel *channel,
667  const struct CadetPingMessage *ping)
668 {
669  struct CadetPingMessage *copy;
670 
671  copy = GNUNET_new (struct CadetPingMessage);
672  *copy = *ping;
673  GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
675  sizeof(struct CadetPingMessage),
676  &tmt_rdy_pong, copy);
677 }
678 
679 
687 static size_t
688 tmt_rdy_ping (void *cls, size_t size, void *buf)
689 {
690  struct CadetPeer *peer = cls;
691  struct CadetPingMessage *msg = buf;
692 
693  peer->ping_ntr = NULL;
695  "tmt_rdy called, filling buffer\n");
696  if ((size < sizeof(struct CadetPingMessage)) || (NULL == buf))
697  {
700  "size %u, buf %p, data_sent %u, data_received %u\n",
701  (unsigned int) size,
702  buf,
703  peer->data_sent,
704  peer->data_received);
705 
706  return 0;
707  }
709  "Sending: msg %d\n",
710  peer->data_sent);
711  msg->header.size = htons (size);
712  msg->header.type = htons (PING);
713  msg->counter = htonl (peer->data_sent++);
714  msg->round_number = htonl (current_round);
716  peer->pings[current_round]++;
718  &ping, peer);
719 
720  return sizeof(struct CadetPingMessage);
721 }
722 
723 
734 int
735 ping_handler (void *cls, struct GNUNET_CADET_Channel *channel,
736  void **channel_ctx,
737  const struct GNUNET_MessageHeader *message)
738 {
739  long n = (long) cls;
740 
742  "%u got PING\n",
743  (unsigned int) n);
744  GNUNET_CADET_receive_done (channel);
745  if (GNUNET_NO == test_finished)
746  pong (channel, (struct CadetPingMessage *) message);
747 
748  return GNUNET_OK;
749 }
750 
751 
762 int
763 pong_handler (void *cls, struct GNUNET_CADET_Channel *channel,
764  void **channel_ctx,
765  const struct GNUNET_MessageHeader *message)
766 {
767  long n = (long) cls;
768  struct CadetPeer *peer;
769  struct CadetPingMessage *msg;
770  struct GNUNET_TIME_Absolute send_time;
771  struct GNUNET_TIME_Relative latency;
772  unsigned int r /* Ping round */;
773  float delta;
774 
775  GNUNET_CADET_receive_done (channel);
776  peer = &peers[n];
777 
778  msg = (struct CadetPingMessage *) message;
779 
780  send_time = GNUNET_TIME_absolute_ntoh (msg->timestamp);
781  latency = GNUNET_TIME_absolute_get_duration (send_time);
782  r = ntohl (msg->round_number);
783  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n",
784  get_index (peer),
785  get_index (peer->dest),
786  (uint32_t) ntohl (msg->counter),
788 
789  /* Online variance calculation */
790  peer->pongs[r]++;
791  delta = latency.rel_value_us - peer->mean[r];
792  peer->mean[r] = peer->mean[r] + delta / peer->pongs[r];
793  peer->var[r] += delta * (latency.rel_value_us - peer->mean[r]);
794 
795  return GNUNET_OK;
796 }
797 
798 
802 static struct GNUNET_CADET_MessageHandler handlers[] = {
803  { &ping_handler, PING, sizeof(struct CadetPingMessage) },
804  { &pong_handler, PONG, sizeof(struct CadetPingMessage) },
805  { NULL, 0, 0 }
806 };
807 
808 
821 static void *
822 incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel,
823  const struct GNUNET_PeerIdentity *initiator,
824  const struct GNUNET_HashCode *port,
825  enum GNUNET_CADET_ChannelOption options)
826 {
827  long n = (long) cls;
828  struct CadetPeer *peer;
829 
830  peer = GNUNET_CONTAINER_multipeermap_get (ids, initiator);
831  GNUNET_assert (NULL != peer);
832  if (NULL == peers[n].incoming)
833  {
835  "WARMUP %3u: %u <= %u\n",
836  peers_warmup,
837  (unsigned int) n,
838  get_index (peer));
839  peers_warmup++;
841  return NULL;
842  if (NULL != test_task)
843  {
844  GNUNET_SCHEDULER_cancel (test_task);
846  &start_test, NULL);
847  }
848  return NULL;
849  }
850  GNUNET_assert (peer == peers[n].incoming);
851  GNUNET_assert (peer->dest == &peers[n]);
853  "%u <= %u %p\n",
854  (unsigned int) n,
855  get_index (peer),
856  channel);
857  peers[n].incoming_ch = channel;
858 
859  return NULL;
860 }
861 
862 
872 static void
873 channel_cleaner (void *cls,
874  const struct GNUNET_CADET_Channel *channel,
875  void *channel_ctx)
876 {
877  long n = (long) cls;
878  struct CadetPeer *peer = &peers[n];
879 
881  "Channel %p disconnected at peer %ld\n", channel, n);
882  if (peer->ch == channel)
883  peer->ch = NULL;
884 }
885 
886 
894 static struct CadetPeer *
896 {
897  unsigned int r;
898 
899  do
900  {
902  }
903  while (NULL != peers[r].incoming);
904  peers[r].incoming = peer;
905 
906  return &peers[r];
907 }
908 
909 
918 static void
919 start_test (void *cls)
920 {
921  unsigned long i;
922 
923  test_task = NULL;
924  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start profiler\n");
925 
926 
927  for (i = 0; i < peers_pinging; i++)
928  {
929  peers[i].dest = select_random_peer (&peers[i]);
930  peers[i].ch = GNUNET_CADET_channel_create (peers[i].cadet, NULL,
931  &peers[i].dest->id,
932  GC_u2h (1));
933  if (NULL == peers[i].ch)
934  {
935  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Channel %lu failed\n", i);
936  GNUNET_CADET_TEST_cleanup (test_ctx);
937  return;
938  }
940  "%lu => %u %p\n",
941  i,
942  get_index (peers[i].dest),
943  peers[i].ch);
945  &ping, &peers[i]);
946  }
948  if (NULL != disconnect_task)
949  GNUNET_SCHEDULER_cancel (disconnect_task);
950  disconnect_task =
953  + 1),
955  (void *) __LINE__);
957  &next_rnd,
958  NULL);
959 }
960 
961 
965 static void
966 warmup (void)
967 {
968  struct CadetPeer *peer;
969  unsigned int i;
970 
971  for (i = 0; i < peers_total; i++)
972  {
973  peer = select_random_peer (NULL);
974  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "WARMUP %u => %u\n",
975  i, get_index (peer));
976  peers[i].warmup_ch =
977  GNUNET_CADET_channel_create (peers[i].cadet, NULL, &peer->id,
978  GC_u2h (1));
979  if (NULL == peers[i].warmup_ch)
980  {
981  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Warmup %u failed\n", i);
982  GNUNET_CADET_TEST_cleanup (test_ctx);
983  return;
984  }
985  }
986 }
987 
988 
998 static void
999 peer_id_cb (void *cls,
1000  struct GNUNET_TESTBED_Operation *op,
1001  const struct GNUNET_TESTBED_PeerInformation *pinfo,
1002  const char *emsg)
1003 {
1004  long n = (long) cls;
1005 
1006  if ((NULL == pinfo) || (NULL != emsg))
1007  {
1008  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
1009  abort_test (__LINE__);
1010  return;
1011  }
1012  peers[n].id = *(pinfo->result.id);
1014  "%ld id: %s\n",
1015  n,
1016  GNUNET_i2s (&peers[n].id));
1018  GNUNET_CONTAINER_multipeermap_put (ids, &peers[n].id, &peers[n],
1020 
1021  GNUNET_TESTBED_operation_done (peers[n].op);
1022  peers[n].op = NULL;
1023 
1024  p_ids++;
1025  if (p_ids < peers_total)
1026  return;
1027  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got all IDs, starting profiler\n");
1028  if (do_warmup)
1029  {
1030  struct GNUNET_TIME_Relative delay;
1031 
1032  warmup ();
1034  100 * peers_total);
1035  test_task = GNUNET_SCHEDULER_add_delayed (delay, &start_test, NULL);
1036  return; /* start_test from incoming_channel */
1037  }
1038  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting in a second...\n");
1040  &start_test, NULL);
1041 }
1042 
1043 
1053 static void
1054 tmain (void *cls,
1056  unsigned int num_peers,
1058  struct GNUNET_CADET_Handle **cadetes)
1059 {
1060  unsigned long i;
1061 
1063  "test main\n");
1064  test_ctx = ctx;
1065  GNUNET_assert (peers_total == num_peers);
1067  testbed_handles = testbed_peers;
1068  disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
1070  (void *) __LINE__);
1072  for (i = 0; i < peers_total; i++)
1073  {
1075  "requesting id %ld\n",
1076  i);
1077  peers[i].up = GNUNET_YES;
1078  peers[i].cadet = cadetes[i];
1079  peers[i].op =
1080  GNUNET_TESTBED_peer_get_information (testbed_handles[i],
1082  &peer_id_cb, (void *) i);
1083  }
1084  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "requested peer ids\n");
1085  /* Continues from pi_cb -> do_test */
1086 }
1087 
1088 
1092 int
1093 main (int argc, char *argv[])
1094 {
1095  static const struct GNUNET_HashCode *ports[2];
1096  const char *config_file;
1097 
1098  config_file = ".profiler.conf";
1099 
1100  if (4 > argc)
1101  {
1102  fprintf (stderr,
1103  "usage: %s ROUND_TIME PEERS PINGS [DO_WARMUP]\n",
1104  argv[0]);
1105  fprintf (stderr,
1106  "example: %s 30s 16 1 Y\n",
1107  argv[0]);
1108  return 1;
1109  }
1110 
1111  if (GNUNET_OK !=
1113  &round_time))
1114  {
1115  fprintf (stderr,
1116  "%s is not a valid time\n",
1117  argv[1]);
1118  return 1;
1119  }
1120 
1121  peers_total = atoll (argv[2]);
1122  if (2 > peers_total)
1123  {
1124  fprintf (stderr,
1125  "%s peers is not valid (> 2)\n",
1126  argv[1]);
1127  return 1;
1128  }
1129  peers = GNUNET_new_array (peers_total,
1130  struct CadetPeer);
1131  peers_pinging = atoll (argv[3]);
1132 
1133  if (peers_total < 2 * peers_pinging)
1134  {
1136  "not enough peers, total should be > 2 * peers_pinging\n");
1137  return 1;
1138  }
1139 
1140  do_warmup = (5 > argc || argv[4][0] != 'N');
1141 
1143  GNUNET_YES);
1144  GNUNET_assert (NULL != ids);
1145  p_ids = 0;
1147  ports[0] = GC_u2h (1);
1148  ports[1] = 0;
1149  GNUNET_CADET_TEST_run ("cadet-profiler", config_file, peers_total,
1150  &tmain, NULL, /* tmain cls */
1152  handlers, ports);
1153  GNUNET_free (peers);
1154 
1155  return 0;
1156 }
1157 
1158 
1159 /* end of gnunet-cadet-profiler.c */
static void abort_test(long line)
Finish test normally: schedule disconnect and shutdown.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
static struct GNUNET_TESTBED_Operation * stats_op
Testbed Operation (to get stats).
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_get_statistics(unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, const char *subsystem, const char *name, GNUNET_TESTBED_StatisticsIterator proc, GNUNET_TESTBED_OperationCompletionCallback cont, void *cls)
Convenience method that iterates over all (running) peers and retrieves all statistics from each peer...
Peer description.
static void ping(void *cls)
Send a ping to destination.
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GNUNET_CADET_TEST_cleanup(struct GNUNET_CADET_TEST_Context *ctx)
Clean up the testbed.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
uint64_t rel_value_us
The actual value.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
static unsigned long long peers_pinging
Number of peers doing pings.
static void adjust_running_peers(unsigned int target)
Set the total number of running peers.
static struct GNUNET_TESTBED_Peer ** testbed_handles
Testbed peer handles.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
Opaque handle to the service.
Definition: cadet_api.c:38
struct CadetPeer * incoming
Incoming channel for pings.
int main(int argc, char *argv[])
Main: start profiler.
int ping_handler(void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message)
Function is called whenever a PING message is received.
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
static unsigned int get_index(struct CadetPeer *peer)
Get the index of a peer in the peers array.
struct CadetPeer * dest
Destinaton to ping.
static void next_rnd(void *cls)
Move to next round.
static unsigned int p_ids
Peer ids counter.
static int do_warmup
Do preconnect? (Each peer creates a tunnel to one other peer).
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:351
#define GNUNET_TIME_UNIT_SECONDS
One second.
static int test_finished
Flag to notify callbacks not to generate any new traffic anymore.
static char * config_file
Set to the name of the config file used.
Definition: gnunet-arm.c:84
struct GNUNET_SCHEDULER_Task * ping_task
Task to do the next ping.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static void collect_stats(void *cls)
Task check that keepalives were sent and received.
static struct GNUNET_TIME_Relative round_time
Duration of each round.
#define GNUNET_NO
Definition: gnunet_common.h:78
Opaque handle to a channel.
Definition: cadet_api.c:80
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void finish_profiler(void *cls)
Finish profiler normally.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Test context for a CADET Test.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
static size_t tmt_rdy_ping(void *cls, size_t size, void *buf)
Transmit ping callback.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Opaque handle to an abstract operation to be executed by the testing framework.
const struct GNUNET_HashCode * GC_u2h(uint32_t port)
Transitional function to convert an unsigned int port to a hash value.
static struct GNUNET_SCHEDULER_Task * disconnect_task
Task called to disconnect peers, before shutdown.
static void disconnect_cadet_peers(void *cls)
Disconnect from cadet services af all peers, call shutdown.
struct GNUNET_PeerIdentity * id
The identity of the peer.
static void tmain(void *cls, struct GNUNET_CADET_TEST_Context *ctx, unsigned int num_peers, struct GNUNET_TESTBED_Peer **testbed_peers, struct GNUNET_CADET_Handle **cadetes)
test main: start test when all peers are connected
struct GNUNET_CADET_TransmitHandle * ping_ntr
NTR operation for the next ping.
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:1253
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
static char * line
Desired phone line (string to be converted to a hash).
static size_t tmt_rdy_pong(void *cls, size_t size, void *buf)
Transmit pong callback.
static char * value
Value of the record to add/remove.
static int stats_iterator(void *cls, const struct GNUNET_TESTBED_Peer *peer, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Process statistic values.
unsigned int pings[sizeof(rounds)/sizeof(rounds[0])]
static struct GNUNET_CONTAINER_MultiPeerMap * ids
GNUNET_PeerIdentity -> CadetPeer.
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:1280
uint32_t round_number
Round number.
struct GNUNET_TIME_AbsoluteNBO timestamp
Time the message was sent.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:687
float mean[sizeof(rounds)/sizeof(rounds[0])]
static char buf[2048]
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
static void * incoming_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator, const struct GNUNET_HashCode *port, enum GNUNET_CADET_ChannelOption options)
Method called whenever another peer has added us to a channel the other peer initiated.
static unsigned int peers_warmup
Warmup progress.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:442
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void show_end_data(void)
Show the results of the test (banwidth acheived) and log them to GAUGER.
static unsigned long long peers_total
Total number of peers.
static unsigned long long peers_running
Number of currently running peers.
Internal representation of the hash map.
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:2044
A 512-bit hashcode.
int data_sent
Number of payload packes sent.
int pong_handler(void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message)
Function is called whenever a PONG message is received.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static struct GNUNET_CADET_TEST_Context * test_ctx
Test context (to shut down).
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.
static void stats_cont(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Stats callback.
struct GNUNET_CADET_Channel * warmup_ch
Channel handle for a warmup channel.
static void pong(struct GNUNET_CADET_Channel *channel, const struct CadetPingMessage *ping)
Reply with a pong to origin.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
static unsigned int size
Size of the "table".
Definition: peer.c:67
float var[sizeof(rounds)/sizeof(rounds[0])]
static struct GNUNET_TESTBED_Peer ** testbed_peers
Handles to all of the running peers.
uint32_t counter
Message number.
#define PING_PERIOD
Paximum ping period in milliseconds.
struct GNUNET_CADET_Handle * cadet
Cadet handle for the root peer.
static unsigned int num_peers
struct GNUNET_CADET_Channel * incoming_ch
Channel handle for the dest peer.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static unsigned int current_round
Round number.
static struct GNUNET_SCHEDULER_Task * test_task
Task to perform tests.
The identity of the host (wraps the signing key of the peer).
#define PONG
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:954
What is the identity of the peer? Returns a &#39;const struct GNUNET_PeerIdentity *&#39;. ...
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1068
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
Message type for pings.
const char * name
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:375
static struct CadetPeer * peers
Operation to get peer ids.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
uint32_t GNUNET_TESTBED_get_index(const struct GNUNET_TESTBED_Peer *peer)
Return the index of the peer inside of the total peer array, aka.
Definition: testbed_api.c:2321
int data_received
Number of payload packets received.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_CADET_Channel * ch
Channel handle for the root peer.
struct GNUNET_PeerIdentity id
Peer ID.
struct GNUNET_MessageHeader header
Header.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
Definition: gnunet-abd.c:732
int up
Is peer up?
static struct GNUNET_SCHEDULER_Task * round_task
Task running each round of the benchmark.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
static float rounds[]
Ratio of peers active.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel, void *channel_ctx)
Function called whenever an inbound channel is destroyed.
unsigned int pongs[sizeof(rounds)/sizeof(rounds[0])]
static void peer_id_cb(void *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 struct CadetPeer * select_random_peer(struct CadetPeer *peer)
Select a random peer that has no incoming channel.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static void start_test(void *cls)
START THE TEST ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
A peer controlled by the testing framework.
static void shutdown_task(void *cls)
Shut down peergroup, clean up.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_peer_manage_service(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_OperationCompletionCallback cb, void *cb_cls, unsigned int start)
Start or stop given service at a peer.
struct GNUNET_TESTBED_Operation * op
Testbed Operation (to get peer id, etc).
union GNUNET_TESTBED_PeerInformation::@61 result
The result of the get information operation; Choose according to the pit.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
static void warmup(void)
Do warmup: create some channels to spread information about the topology.
#define number_rounds
Total number of rounds.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:903
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
library for writing CADET tests
#define PING
long long atoll(const char *nptr)
#define GNUNET_free(ptr)
Wrapper around free.
#define SHORT_TIME
Time to wait for stuff that should be rather fast.
Time for relative time used by GNUnet, in microseconds.
Data returned from GNUNET_TESTBED_peer_get_information.
static struct GNUNET_TIME_Relative delay_ms_rnd(unsigned int max)
Calculate a random delay.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966