GNUnet  0.10.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 };
163 
168 
173 
178 
183 
187 static struct CadetPeer *peers;
188 
192 static unsigned int p_ids;
193 
197 static unsigned long long peers_total;
198 
202 static unsigned long long peers_running;
203 
207 static unsigned long long peers_pinging;
208 
213 
218 
223 
227 static unsigned int current_round;
228 
232 static int do_warmup;
233 
237 static unsigned int peers_warmup;
238 
242 static int test_finished;
243 
248 
249 
258 static void
259 start_test (void *cls);
260 
261 
269 static struct GNUNET_TIME_Relative
270 delay_ms_rnd (unsigned int max)
271 {
272  unsigned int rnd;
273 
276 }
277 
278 
286 static unsigned int
288 {
289  return peer - peers;
290 }
291 
292 
296 static void
298 {
299  struct CadetPeer *peer;
300  unsigned int i;
301  unsigned int j;
302 
303  for (i = 0; i < number_rounds; i++)
304  {
305  for (j = 0; j < peers_pinging; j++)
306  {
307  peer = &peers[j];
308  FPRINTF (stdout,
309  "ROUND %3u PEER %3u: %10.2f / %10.2f, PINGS: %3u, PONGS: %3u\n",
310  i, j, peer->mean[i], sqrt (peer->var[i] / (peer->pongs[i] - 1)),
311  peer->pings[i], peer->pongs[i]);
312  }
313  }
314 }
315 
316 
322 static void
324 {
325  long line = (long) cls;
326  unsigned int i;
327 
329  "disconnecting cadet service, called from line %ld\n",
330  line);
331  disconnect_task = NULL;
332  for (i = 0; i < peers_total; i++)
333  {
334  if (NULL != peers[i].op)
335  GNUNET_TESTBED_operation_done (peers[i].op);
336 
337  if (peers[i].up != GNUNET_YES)
338  continue;
339 
340  if (NULL != peers[i].ch)
341  {
343  "%u: channel %p\n", i, peers[i].ch);
344  GNUNET_CADET_channel_destroy (peers[i].ch);
345  }
346  if (NULL != peers[i].warmup_ch)
347  {
349  "%u: warmup channel %p\n",
350  i, peers[i].warmup_ch);
351  GNUNET_CADET_channel_destroy (peers[i].warmup_ch);
352  }
353  if (NULL != peers[i].incoming_ch)
354  {
356  "%u: incoming channel %p\n",
357  i, peers[i].incoming_ch);
358  GNUNET_CADET_channel_destroy (peers[i].incoming_ch);
359  }
360  }
361  GNUNET_CADET_TEST_cleanup (test_ctx);
363 }
364 
365 
371 static void
372 shutdown_task (void *cls)
373 {
375  "Ending test.\n");
376  if (NULL != disconnect_task)
377  {
378  GNUNET_SCHEDULER_cancel (disconnect_task);
380  (void *) __LINE__);
381  }
382  if (NULL != round_task)
383  {
384  GNUNET_SCHEDULER_cancel (round_task);
385  round_task = NULL;
386  }
387  if (NULL != test_task)
388  {
389  GNUNET_SCHEDULER_cancel (test_task);
390  test_task = NULL;
391  }
392 }
393 
394 
400 static void
402 {
403  if (disconnect_task != NULL)
404  {
405  GNUNET_SCHEDULER_cancel (disconnect_task);
407  (void *) line);
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 
433 
445 static int
446 stats_iterator (void *cls,
447  const struct GNUNET_TESTBED_Peer *peer,
448  const char *subsystem,
449  const char *name,
450  uint64_t value,
451  int is_persistent)
452 {
453  uint32_t i;
454 
455  i = GNUNET_TESTBED_get_index (peer);
457  " STATS %u - %s [%s]: %llu\n",
458  i, subsystem, name,
459  (unsigned long long) value);
460 
461  return GNUNET_OK;
462 }
463 
464 
470 static void
471 collect_stats (void *cls)
472 {
474  "Start collecting statistics...\n");
476  testbed_handles,
477  NULL, NULL,
479  &stats_cont, NULL);
480 }
481 
482 
488 static void
489 finish_profiler (void *cls)
490 {
492  show_end_data ();
494 }
495 
496 
502 static void
503 adjust_running_peers (unsigned int target)
504 {
506  unsigned int delta;
507  unsigned int run;
508  unsigned int i;
509  unsigned int r;
510 
511  GNUNET_assert (target <= peers_total);
512 
513  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "adjust peers to %u\n", target);
514  if (target > peers_running)
515  {
516  delta = target - peers_running;
517  run = GNUNET_YES;
518  }
519  else
520  {
521  delta = peers_running - target;
522  run = GNUNET_NO;
523  }
524 
525  for (i = 0; i < delta; i++)
526  {
527  do {
530  r += peers_pinging;
531  } while (peers[r].up == run || NULL != peers[r].incoming);
532  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "St%s peer %u: %s\n",
533  run ? "arting" : "opping", r, GNUNET_i2s (&peers[r].id));
534 
535  if (NULL != peers[r].ping_task)
536  {
537  GNUNET_SCHEDULER_cancel (peers[r].ping_task);
538  peers[r].ping_task = NULL;
539  }
540  if (NULL != peers[r].ping_ntr)
541  {
542  GNUNET_CADET_notify_transmit_ready_cancel (peers[r].ping_ntr);
543  peers[r].ping_ntr = NULL;
544  }
545  peers[r].up = run;
546 
547  if (NULL != peers[r].ch)
548  GNUNET_CADET_channel_destroy (peers[r].ch);
549  peers[r].ch = NULL;
550  if (NULL != peers[r].dest)
551  {
552  if (NULL != peers[r].dest->incoming_ch)
553  GNUNET_CADET_channel_destroy (peers[r].dest->incoming_ch);
554  peers[r].dest->incoming_ch = NULL;
555  }
556 
557  op = GNUNET_TESTBED_peer_manage_service (&peers[r], testbed_handles[r],
558  "cadet", NULL, NULL, run);
559  GNUNET_break (NULL != op);
560  peers_running += run ? 1 : -1;
562  }
563 }
564 
565 
571 static void
572 next_rnd (void *cls)
573 {
575  "ROUND %u\n",
576  current_round);
577  if (0.0 == rounds[current_round])
578  {
579  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Finishing\n");
581  return;
582  }
583  adjust_running_peers (rounds[current_round] * peers_total);
584  current_round++;
585 
587  &next_rnd,
588  NULL);
589 }
590 
591 
601 static size_t
602 tmt_rdy_ping (void *cls, size_t size, void *buf);
603 
604 
612 static size_t
613 tmt_rdy_pong (void *cls, size_t size, void *buf)
614 {
615  struct CadetPingMessage *ping = cls;
616  struct CadetPingMessage *pong;
617 
618  if (0 == size || NULL == buf)
619  {
620  GNUNET_free (ping);
621  return 0;
622  }
623  pong = (struct CadetPingMessage *) buf;
624  GNUNET_memcpy (pong, ping, sizeof (*ping));
625  pong->header.type = htons (PONG);
626 
627  GNUNET_free (ping);
628  return sizeof (*ping);
629 }
630 
631 
637 static void
638 ping (void *cls)
639 {
640  struct CadetPeer *peer = cls;
641 
642  peer->ping_task = NULL;
643  if (GNUNET_YES == test_finished)
644  return;
646  "%u -> %u (%u)\n",
647  get_index (peer),
648  get_index (peer->dest),
649  peer->data_sent);
650  peer->ping_ntr = GNUNET_CADET_notify_transmit_ready (peer->ch, GNUNET_NO,
652  sizeof (struct CadetPingMessage),
653  &tmt_rdy_ping, peer);
654 }
655 
662 static void
663 pong (struct GNUNET_CADET_Channel *channel,
664  const struct CadetPingMessage *ping)
665 {
666  struct CadetPingMessage *copy;
667 
668  copy = GNUNET_new (struct CadetPingMessage);
669  *copy = *ping;
670  GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
672  sizeof (struct CadetPingMessage),
673  &tmt_rdy_pong, copy);
674 }
675 
676 
684 static size_t
685 tmt_rdy_ping (void *cls, size_t size, void *buf)
686 {
687  struct CadetPeer *peer = cls;
688  struct CadetPingMessage *msg = buf;
689 
690  peer->ping_ntr = NULL;
692  "tmt_rdy called, filling buffer\n");
693  if (size < sizeof (struct CadetPingMessage) || NULL == buf)
694  {
697  "size %u, buf %p, data_sent %u, data_received %u\n",
698  (unsigned int) size,
699  buf,
700  peer->data_sent,
701  peer->data_received);
702 
703  return 0;
704  }
706  "Sending: msg %d\n",
707  peer->data_sent);
708  msg->header.size = htons (size);
709  msg->header.type = htons (PING);
710  msg->counter = htonl (peer->data_sent++);
711  msg->round_number = htonl (current_round);
713  peer->pings[current_round]++;
715  &ping, peer);
716 
717  return sizeof (struct CadetPingMessage);
718 }
719 
720 
731 int
732 ping_handler (void *cls, struct GNUNET_CADET_Channel *channel,
733  void **channel_ctx,
734  const struct GNUNET_MessageHeader *message)
735 {
736  long n = (long) cls;
737 
739  "%u got PING\n",
740  (unsigned int) n);
741  GNUNET_CADET_receive_done (channel);
742  if (GNUNET_NO == test_finished)
743  pong (channel, (struct CadetPingMessage *) message);
744 
745  return GNUNET_OK;
746 }
747 
748 
759 int
760 pong_handler (void *cls, struct GNUNET_CADET_Channel *channel,
761  void **channel_ctx,
762  const struct GNUNET_MessageHeader *message)
763 {
764  long n = (long) cls;
765  struct CadetPeer *peer;
766  struct CadetPingMessage *msg;
767  struct GNUNET_TIME_Absolute send_time;
768  struct GNUNET_TIME_Relative latency;
769  unsigned int r /* Ping round */;
770  float delta;
771 
772  GNUNET_CADET_receive_done (channel);
773  peer = &peers[n];
774 
775  msg = (struct CadetPingMessage *) message;
776 
777  send_time = GNUNET_TIME_absolute_ntoh (msg->timestamp);
778  latency = GNUNET_TIME_absolute_get_duration (send_time);
779  r = ntohl (msg->round_number);
780  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n",
781  get_index (peer),
782  get_index (peer->dest),
783  (uint32_t) ntohl (msg->counter),
785 
786  /* Online variance calculation */
787  peer->pongs[r]++;
788  delta = latency.rel_value_us - peer->mean[r];
789  peer->mean[r] = peer->mean[r] + delta/peer->pongs[r];
790  peer->var[r] += delta * (latency.rel_value_us - peer->mean[r]);
791 
792  return GNUNET_OK;
793 }
794 
795 
799 static struct GNUNET_CADET_MessageHandler handlers[] = {
800  {&ping_handler, PING, sizeof (struct CadetPingMessage)},
801  {&pong_handler, PONG, sizeof (struct CadetPingMessage)},
802  {NULL, 0, 0}
803 };
804 
805 
818 static void *
819 incoming_channel (void *cls, struct GNUNET_CADET_Channel *channel,
820  const struct GNUNET_PeerIdentity *initiator,
821  const struct GNUNET_HashCode *port,
822  enum GNUNET_CADET_ChannelOption options)
823 {
824  long n = (long) cls;
825  struct CadetPeer *peer;
826 
827  peer = GNUNET_CONTAINER_multipeermap_get (ids, initiator);
828  GNUNET_assert (NULL != peer);
829  if (NULL == peers[n].incoming)
830  {
832  "WARMUP %3u: %u <= %u\n",
833  peers_warmup,
834  (unsigned int) n,
835  get_index (peer));
836  peers_warmup++;
838  return NULL;
839  if (NULL != test_task)
840  {
841  GNUNET_SCHEDULER_cancel (test_task);
843  &start_test, NULL);
844  }
845  return NULL;
846  }
847  GNUNET_assert (peer == peers[n].incoming);
848  GNUNET_assert (peer->dest == &peers[n]);
850  "%u <= %u %p\n",
851  (unsigned int) n,
852  get_index (peer),
853  channel);
854  peers[n].incoming_ch = channel;
855 
856  return NULL;
857 }
858 
868 static void
869 channel_cleaner (void *cls,
870  const struct GNUNET_CADET_Channel *channel,
871  void *channel_ctx)
872 {
873  long n = (long) cls;
874  struct CadetPeer *peer = &peers[n];
875 
877  "Channel %p disconnected at peer %ld\n", channel, n);
878  if (peer->ch == channel)
879  peer->ch = NULL;
880 }
881 
882 
890 static struct CadetPeer *
892 {
893  unsigned int r;
894 
895  do
896  {
898  } while (NULL != peers[r].incoming);
899  peers[r].incoming = peer;
900 
901  return &peers[r];
902 }
903 
912 static void
913 start_test (void *cls)
914 {
915  unsigned long i;
916 
917  test_task = NULL;
918  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Start profiler\n");
919 
920 
921  for (i = 0; i < peers_pinging; i++)
922  {
923  peers[i].dest = select_random_peer (&peers[i]);
924  peers[i].ch = GNUNET_CADET_channel_create (peers[i].cadet, NULL,
925  &peers[i].dest->id,
926  GC_u2h (1));
927  if (NULL == peers[i].ch)
928  {
929  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Channel %lu failed\n", i);
930  GNUNET_CADET_TEST_cleanup (test_ctx);
931  return;
932  }
934  "%lu => %u %p\n",
935  i,
936  get_index (peers[i].dest),
937  peers[i].ch);
939  &ping, &peers[i]);
940  }
942  if (NULL != disconnect_task)
943  GNUNET_SCHEDULER_cancel (disconnect_task);
944  disconnect_task =
946  number_rounds + 1),
948  (void *) __LINE__);
950  &next_rnd,
951  NULL);
952 }
953 
954 
958 static void
959 warmup (void)
960 {
961  struct CadetPeer *peer;
962  unsigned int i;
963 
964  for (i = 0; i < peers_total; i++)
965  {
966  peer = select_random_peer (NULL);
967  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "WARMUP %u => %u\n",
968  i, get_index (peer));
969  peers[i].warmup_ch =
970  GNUNET_CADET_channel_create (peers[i].cadet, NULL, &peer->id,
971  GC_u2h (1));
972  if (NULL == peers[i].warmup_ch)
973  {
974  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Warmup %u failed\n", i);
975  GNUNET_CADET_TEST_cleanup (test_ctx);
976  return;
977  }
978  }
979 }
980 
981 
991 static void
992 peer_id_cb (void *cls,
994  const struct GNUNET_TESTBED_PeerInformation *pinfo,
995  const char *emsg)
996 {
997  long n = (long) cls;
998 
999  if (NULL == pinfo || NULL != emsg)
1000  {
1001  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
1002  abort_test (__LINE__);
1003  return;
1004  }
1005  peers[n].id = *(pinfo->result.id);
1007  "%ld id: %s\n",
1008  n,
1009  GNUNET_i2s (&peers[n].id));
1011  GNUNET_CONTAINER_multipeermap_put (ids, &peers[n].id, &peers[n],
1013 
1014  GNUNET_TESTBED_operation_done (peers[n].op);
1015  peers[n].op = NULL;
1016 
1017  p_ids++;
1018  if (p_ids < peers_total)
1019  return;
1020  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got all IDs, starting profiler\n");
1021  if (do_warmup)
1022  {
1023  struct GNUNET_TIME_Relative delay;
1024 
1025  warmup();
1027  100 * peers_total);
1028  test_task = GNUNET_SCHEDULER_add_delayed (delay, &start_test, NULL);
1029  return; /* start_test from incoming_channel */
1030  }
1031  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting in a second...\n");
1033  &start_test, NULL);
1034 }
1035 
1036 
1046 static void
1047 tmain (void *cls,
1049  unsigned int num_peers,
1051  struct GNUNET_CADET_Handle **cadetes)
1052 {
1053  unsigned long i;
1054 
1056  "test main\n");
1057  test_ctx = ctx;
1058  GNUNET_assert (peers_total == num_peers);
1060  testbed_handles = testbed_peers;
1061  disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
1063  (void *) __LINE__);
1065  for (i = 0; i < peers_total; i++)
1066  {
1068  "requesting id %ld\n",
1069  i);
1070  peers[i].up = GNUNET_YES;
1071  peers[i].cadet = cadetes[i];
1072  peers[i].op =
1073  GNUNET_TESTBED_peer_get_information (testbed_handles[i],
1075  &peer_id_cb, (void *) i);
1076  }
1077  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "requested peer ids\n");
1078  /* Continues from pi_cb -> do_test */
1079 }
1080 
1081 
1085 int
1086 main (int argc, char *argv[])
1087 {
1088  static const struct GNUNET_HashCode *ports[2];
1089  const char *config_file;
1090 
1091  config_file = ".profiler.conf";
1092 
1093  if (4 > argc)
1094  {
1095  fprintf (stderr,
1096  "usage: %s ROUND_TIME PEERS PINGS [DO_WARMUP]\n",
1097  argv[0]);
1098  fprintf (stderr,
1099  "example: %s 30s 16 1 Y\n",
1100  argv[0]);
1101  return 1;
1102  }
1103 
1104  if (GNUNET_OK !=
1106  &round_time))
1107  {
1108  fprintf (stderr,
1109  "%s is not a valid time\n",
1110  argv[1]);
1111  return 1;
1112  }
1113 
1114  peers_total = atoll (argv[2]);
1115  if (2 > peers_total)
1116  {
1117  fprintf (stderr,
1118  "%s peers is not valid (> 2)\n",
1119  argv[1]);
1120  return 1;
1121  }
1122  peers = GNUNET_new_array (peers_total,
1123  struct CadetPeer);
1124  peers_pinging = atoll (argv[3]);
1125 
1126  if (peers_total < 2 * peers_pinging)
1127  {
1129  "not enough peers, total should be > 2 * peers_pinging\n");
1130  return 1;
1131  }
1132 
1133  do_warmup = (5 > argc || argv[4][0] != 'N');
1134 
1136  GNUNET_YES);
1137  GNUNET_assert (NULL != ids);
1138  p_ids = 0;
1140  ports[0] = GC_u2h (1);
1141  ports[1] = 0;
1142  GNUNET_CADET_TEST_run ("cadet-profiler", config_file, peers_total,
1143  &tmain, NULL, /* tmain cls */
1145  handlers, ports);
1146  GNUNET_free (peers);
1147 
1148  return 0;
1149 }
1150 
1151 /* 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
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run by the scheduler.
Definition: gnunet-arm.c:700
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:670
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
union GNUNET_TESTBED_PeerInformation::@64 result
The result of the get information operation; Choose according to the pit.
struct CadetPeer * incoming
Incoming channel for pings.
#define FPRINTF
Definition: plibc.h:683
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:1293
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:353
#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:79
struct GNUNET_SCHEDULER_Task * ping_task
Task to do the next ping.
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:81
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:78
#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:524
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:1246
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
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:1273
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:727
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:439
#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:2020
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.
const char * name
#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:955
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:1070
static uint16_t port
Port number.
Definition: gnunet-bcd.c:79
Message type for pings.
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:373
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:2289
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.
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:80
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:139
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).
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
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:905
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)
Definition: winproc.c:335
#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:965