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 
69 
73  uint32_t counter;
74 
79 
83  uint32_t round_number;
84 };
85 
89 struct CadetPeer {
94 
99 
104 
109 
114 
119 
124 
129 
133  int up;
134 
138  struct CadetPeer *dest;
139 
144 
149 
153  struct GNUNET_CADET_TransmitHandle *ping_ntr;
154 
155  float mean[number_rounds];
156  float var[number_rounds];
157  unsigned int pongs[number_rounds];
158  unsigned int pings[number_rounds];
159 };
160 
165 
170 
175 
180 
184 static struct CadetPeer *peers;
185 
189 static unsigned int p_ids;
190 
194 static unsigned long long peers_total;
195 
199 static unsigned long long peers_running;
200 
204 static unsigned long long peers_pinging;
205 
210 
215 
220 
224 static unsigned int current_round;
225 
229 static int do_warmup;
230 
234 static unsigned int peers_warmup;
235 
239 static int test_finished;
240 
245 
246 
255 static void
256 start_test(void *cls);
257 
258 
266 static struct GNUNET_TIME_Relative
267 delay_ms_rnd(unsigned int max)
268 {
269  unsigned int rnd;
270 
273 }
274 
275 
283 static unsigned int
285 {
286  return peer - peers;
287 }
288 
289 
293 static void
295 {
296  struct CadetPeer *peer;
297  unsigned int i;
298  unsigned int j;
299 
300  for (i = 0; i < number_rounds; i++)
301  {
302  for (j = 0; j < peers_pinging; j++)
303  {
304  peer = &peers[j];
305  fprintf(stdout,
306  "ROUND %3u PEER %3u: %10.2f / %10.2f, PINGS: %3u, PONGS: %3u\n",
307  i, j, peer->mean[i], sqrt(peer->var[i] / (peer->pongs[i] - 1)),
308  peer->pings[i], peer->pongs[i]);
309  }
310  }
311 }
312 
313 
319 static void
321 {
322  long line = (long)cls;
323  unsigned int i;
324 
326  "disconnecting cadet service, called from line %ld\n",
327  line);
328  disconnect_task = NULL;
329  for (i = 0; i < peers_total; i++)
330  {
331  if (NULL != peers[i].op)
332  GNUNET_TESTBED_operation_done(peers[i].op);
333 
334  if (peers[i].up != GNUNET_YES)
335  continue;
336 
337  if (NULL != peers[i].ch)
338  {
340  "%u: channel %p\n", i, peers[i].ch);
341  GNUNET_CADET_channel_destroy(peers[i].ch);
342  }
343  if (NULL != peers[i].warmup_ch)
344  {
346  "%u: warmup channel %p\n",
347  i, peers[i].warmup_ch);
348  GNUNET_CADET_channel_destroy(peers[i].warmup_ch);
349  }
350  if (NULL != peers[i].incoming_ch)
351  {
353  "%u: incoming channel %p\n",
354  i, peers[i].incoming_ch);
355  GNUNET_CADET_channel_destroy(peers[i].incoming_ch);
356  }
357  }
358  GNUNET_CADET_TEST_cleanup(test_ctx);
360 }
361 
362 
368 static void
369 shutdown_task(void *cls)
370 {
372  "Ending test.\n");
373  if (NULL != disconnect_task)
374  {
375  GNUNET_SCHEDULER_cancel(disconnect_task);
377  (void *)__LINE__);
378  }
379  if (NULL != round_task)
380  {
381  GNUNET_SCHEDULER_cancel(round_task);
382  round_task = NULL;
383  }
384  if (NULL != test_task)
385  {
386  GNUNET_SCHEDULER_cancel(test_task);
387  test_task = NULL;
388  }
389 }
390 
391 
397 static void
399 {
400  if (disconnect_task != NULL)
401  {
402  GNUNET_SCHEDULER_cancel(disconnect_task);
404  (void *)line);
405  }
406 }
407 
417 static void
418 stats_cont(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
419 {
420  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "... collecting statistics done.\n");
422 
423  if (NULL != disconnect_task)
424  GNUNET_SCHEDULER_cancel(disconnect_task);
426  (void *)__LINE__);
427 }
428 
429 
441 static int
442 stats_iterator(void *cls,
443  const struct GNUNET_TESTBED_Peer *peer,
444  const char *subsystem,
445  const char *name,
446  uint64_t value,
447  int is_persistent)
448 {
449  uint32_t i;
450 
451  i = GNUNET_TESTBED_get_index(peer);
453  " STATS %u - %s [%s]: %llu\n",
454  i, subsystem, name,
455  (unsigned long long)value);
456 
457  return GNUNET_OK;
458 }
459 
460 
466 static void
467 collect_stats(void *cls)
468 {
470  "Start collecting statistics...\n");
472  testbed_handles,
473  NULL, NULL,
475  &stats_cont, NULL);
476 }
477 
478 
484 static void
485 finish_profiler(void *cls)
486 {
488  show_end_data();
490 }
491 
492 
498 static void
499 adjust_running_peers(unsigned int target)
500 {
502  unsigned int delta;
503  unsigned int run;
504  unsigned int i;
505  unsigned int r;
506 
507  GNUNET_assert(target <= peers_total);
508 
509  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "adjust peers to %u\n", target);
510  if (target > peers_running)
511  {
512  delta = target - peers_running;
513  run = GNUNET_YES;
514  }
515  else
516  {
517  delta = peers_running - target;
518  run = GNUNET_NO;
519  }
520 
521  for (i = 0; i < delta; i++)
522  {
523  do
524  {
527  r += peers_pinging;
528  }
529  while (peers[r].up == run || NULL != peers[r].incoming);
530  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "St%s peer %u: %s\n",
531  run ? "arting" : "opping", r, GNUNET_i2s(&peers[r].id));
532 
533  if (NULL != peers[r].ping_task)
534  {
535  GNUNET_SCHEDULER_cancel(peers[r].ping_task);
536  peers[r].ping_task = NULL;
537  }
538  if (NULL != peers[r].ping_ntr)
539  {
540  GNUNET_CADET_notify_transmit_ready_cancel(peers[r].ping_ntr);
541  peers[r].ping_ntr = NULL;
542  }
543  peers[r].up = run;
544 
545  if (NULL != peers[r].ch)
546  GNUNET_CADET_channel_destroy(peers[r].ch);
547  peers[r].ch = NULL;
548  if (NULL != peers[r].dest)
549  {
550  if (NULL != peers[r].dest->incoming_ch)
552  peers[r].dest->incoming_ch = NULL;
553  }
554 
555  op = GNUNET_TESTBED_peer_manage_service(&peers[r], testbed_handles[r],
556  "cadet", NULL, NULL, run);
557  GNUNET_break(NULL != op);
558  peers_running += run ? 1 : -1;
560  }
561 }
562 
563 
569 static void
570 next_rnd(void *cls)
571 {
573  "ROUND %u\n",
574  current_round);
575  if (0.0 == rounds[current_round])
576  {
577  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Finishing\n");
579  return;
580  }
581  adjust_running_peers(rounds[current_round] * peers_total);
582  current_round++;
583 
585  &next_rnd,
586  NULL);
587 }
588 
589 
599 static size_t
600 tmt_rdy_ping(void *cls, size_t size, void *buf);
601 
602 
610 static size_t
611 tmt_rdy_pong(void *cls, size_t size, void *buf)
612 {
613  struct CadetPingMessage *ping = cls;
614  struct CadetPingMessage *pong;
615 
616  if (0 == size || NULL == buf)
617  {
618  GNUNET_free(ping);
619  return 0;
620  }
621  pong = (struct CadetPingMessage *)buf;
622  GNUNET_memcpy(pong, ping, sizeof(*ping));
623  pong->header.type = htons(PONG);
624 
625  GNUNET_free(ping);
626  return sizeof(*ping);
627 }
628 
629 
635 static void
636 ping(void *cls)
637 {
638  struct CadetPeer *peer = cls;
639 
640  peer->ping_task = NULL;
641  if (GNUNET_YES == test_finished)
642  return;
644  "%u -> %u (%u)\n",
645  get_index(peer),
646  get_index(peer->dest),
647  peer->data_sent);
648  peer->ping_ntr = GNUNET_CADET_notify_transmit_ready(peer->ch, GNUNET_NO,
650  sizeof(struct CadetPingMessage),
651  &tmt_rdy_ping, peer);
652 }
653 
660 static void
661 pong(struct GNUNET_CADET_Channel *channel,
662  const struct CadetPingMessage *ping)
663 {
664  struct CadetPingMessage *copy;
665 
666  copy = GNUNET_new(struct CadetPingMessage);
667  *copy = *ping;
668  GNUNET_CADET_notify_transmit_ready(channel, GNUNET_NO,
670  sizeof(struct CadetPingMessage),
671  &tmt_rdy_pong, copy);
672 }
673 
674 
682 static size_t
683 tmt_rdy_ping(void *cls, size_t size, void *buf)
684 {
685  struct CadetPeer *peer = cls;
686  struct CadetPingMessage *msg = buf;
687 
688  peer->ping_ntr = NULL;
690  "tmt_rdy called, filling buffer\n");
691  if (size < sizeof(struct CadetPingMessage) || NULL == buf)
692  {
695  "size %u, buf %p, data_sent %u, data_received %u\n",
696  (unsigned int)size,
697  buf,
698  peer->data_sent,
699  peer->data_received);
700 
701  return 0;
702  }
704  "Sending: msg %d\n",
705  peer->data_sent);
706  msg->header.size = htons(size);
707  msg->header.type = htons(PING);
708  msg->counter = htonl(peer->data_sent++);
709  msg->round_number = htonl(current_round);
711  peer->pings[current_round]++;
713  &ping, peer);
714 
715  return sizeof(struct CadetPingMessage);
716 }
717 
718 
729 int
730 ping_handler(void *cls, struct GNUNET_CADET_Channel *channel,
731  void **channel_ctx,
732  const struct GNUNET_MessageHeader *message)
733 {
734  long n = (long)cls;
735 
737  "%u got PING\n",
738  (unsigned int)n);
739  GNUNET_CADET_receive_done(channel);
740  if (GNUNET_NO == test_finished)
741  pong(channel, (struct CadetPingMessage *)message);
742 
743  return GNUNET_OK;
744 }
745 
746 
757 int
758 pong_handler(void *cls, struct GNUNET_CADET_Channel *channel,
759  void **channel_ctx,
760  const struct GNUNET_MessageHeader *message)
761 {
762  long n = (long)cls;
763  struct CadetPeer *peer;
764  struct CadetPingMessage *msg;
765  struct GNUNET_TIME_Absolute send_time;
766  struct GNUNET_TIME_Relative latency;
767  unsigned int r /* Ping round */;
768  float delta;
769 
770  GNUNET_CADET_receive_done(channel);
771  peer = &peers[n];
772 
773  msg = (struct CadetPingMessage *)message;
774 
775  send_time = GNUNET_TIME_absolute_ntoh(msg->timestamp);
776  latency = GNUNET_TIME_absolute_get_duration(send_time);
777  r = ntohl(msg->round_number);
778  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n",
779  get_index(peer),
780  get_index(peer->dest),
781  (uint32_t)ntohl(msg->counter),
783 
784  /* Online variance calculation */
785  peer->pongs[r]++;
786  delta = latency.rel_value_us - peer->mean[r];
787  peer->mean[r] = peer->mean[r] + delta / peer->pongs[r];
788  peer->var[r] += delta * (latency.rel_value_us - peer->mean[r]);
789 
790  return GNUNET_OK;
791 }
792 
793 
797 static struct GNUNET_CADET_MessageHandler handlers[] = {
798  { &ping_handler, PING, sizeof(struct CadetPingMessage) },
799  { &pong_handler, PONG, sizeof(struct CadetPingMessage) },
800  { NULL, 0, 0 }
801 };
802 
803 
816 static void *
817 incoming_channel(void *cls, struct GNUNET_CADET_Channel *channel,
818  const struct GNUNET_PeerIdentity *initiator,
819  const struct GNUNET_HashCode *port,
820  enum GNUNET_CADET_ChannelOption options)
821 {
822  long n = (long)cls;
823  struct CadetPeer *peer;
824 
825  peer = GNUNET_CONTAINER_multipeermap_get(ids, initiator);
826  GNUNET_assert(NULL != peer);
827  if (NULL == peers[n].incoming)
828  {
830  "WARMUP %3u: %u <= %u\n",
831  peers_warmup,
832  (unsigned int)n,
833  get_index(peer));
834  peers_warmup++;
836  return NULL;
837  if (NULL != test_task)
838  {
839  GNUNET_SCHEDULER_cancel(test_task);
841  &start_test, NULL);
842  }
843  return NULL;
844  }
845  GNUNET_assert(peer == peers[n].incoming);
846  GNUNET_assert(peer->dest == &peers[n]);
848  "%u <= %u %p\n",
849  (unsigned int)n,
850  get_index(peer),
851  channel);
852  peers[n].incoming_ch = channel;
853 
854  return NULL;
855 }
856 
866 static void
867 channel_cleaner(void *cls,
868  const struct GNUNET_CADET_Channel *channel,
869  void *channel_ctx)
870 {
871  long n = (long)cls;
872  struct CadetPeer *peer = &peers[n];
873 
875  "Channel %p disconnected at peer %ld\n", channel, n);
876  if (peer->ch == channel)
877  peer->ch = NULL;
878 }
879 
880 
888 static struct CadetPeer *
890 {
891  unsigned int r;
892 
893  do
894  {
896  }
897  while (NULL != peers[r].incoming);
898  peers[r].incoming = peer;
899 
900  return &peers[r];
901 }
902 
911 static void
912 start_test(void *cls)
913 {
914  unsigned long i;
915 
916  test_task = NULL;
917  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Start profiler\n");
918 
919 
920  for (i = 0; i < peers_pinging; i++)
921  {
922  peers[i].dest = select_random_peer(&peers[i]);
923  peers[i].ch = GNUNET_CADET_channel_create(peers[i].cadet, NULL,
924  &peers[i].dest->id,
925  GC_u2h(1));
926  if (NULL == peers[i].ch)
927  {
928  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Channel %lu failed\n", i);
929  GNUNET_CADET_TEST_cleanup(test_ctx);
930  return;
931  }
933  "%lu => %u %p\n",
934  i,
935  get_index(peers[i].dest),
936  peers[i].ch);
938  &ping, &peers[i]);
939  }
941  if (NULL != disconnect_task)
942  GNUNET_SCHEDULER_cancel(disconnect_task);
943  disconnect_task =
945  number_rounds + 1),
947  (void *)__LINE__);
949  &next_rnd,
950  NULL);
951 }
952 
953 
957 static void
958 warmup(void)
959 {
960  struct CadetPeer *peer;
961  unsigned int i;
962 
963  for (i = 0; i < peers_total; i++)
964  {
965  peer = select_random_peer(NULL);
966  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WARMUP %u => %u\n",
967  i, get_index(peer));
968  peers[i].warmup_ch =
969  GNUNET_CADET_channel_create(peers[i].cadet, NULL, &peer->id,
970  GC_u2h(1));
971  if (NULL == peers[i].warmup_ch)
972  {
973  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Warmup %u failed\n", i);
974  GNUNET_CADET_TEST_cleanup(test_ctx);
975  return;
976  }
977  }
978 }
979 
980 
990 static void
991 peer_id_cb(void *cls,
993  const struct GNUNET_TESTBED_PeerInformation *pinfo,
994  const char *emsg)
995 {
996  long n = (long)cls;
997 
998  if (NULL == pinfo || NULL != emsg)
999  {
1000  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
1001  abort_test(__LINE__);
1002  return;
1003  }
1004  peers[n].id = *(pinfo->result.id);
1006  "%ld id: %s\n",
1007  n,
1008  GNUNET_i2s(&peers[n].id));
1010  GNUNET_CONTAINER_multipeermap_put(ids, &peers[n].id, &peers[n],
1012 
1013  GNUNET_TESTBED_operation_done(peers[n].op);
1014  peers[n].op = NULL;
1015 
1016  p_ids++;
1017  if (p_ids < peers_total)
1018  return;
1019  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Got all IDs, starting profiler\n");
1020  if (do_warmup)
1021  {
1022  struct GNUNET_TIME_Relative delay;
1023 
1024  warmup();
1026  100 * peers_total);
1027  test_task = GNUNET_SCHEDULER_add_delayed(delay, &start_test, NULL);
1028  return; /* start_test from incoming_channel */
1029  }
1030  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Starting in a second...\n");
1032  &start_test, NULL);
1033 }
1034 
1035 
1045 static void
1046 tmain(void *cls,
1048  unsigned int num_peers,
1050  struct GNUNET_CADET_Handle **cadetes)
1051 {
1052  unsigned long i;
1053 
1055  "test main\n");
1056  test_ctx = ctx;
1057  GNUNET_assert(peers_total == num_peers);
1059  testbed_handles = testbed_peers;
1060  disconnect_task = GNUNET_SCHEDULER_add_delayed(SHORT_TIME,
1062  (void *)__LINE__);
1064  for (i = 0; i < peers_total; i++)
1065  {
1067  "requesting id %ld\n",
1068  i);
1069  peers[i].up = GNUNET_YES;
1070  peers[i].cadet = cadetes[i];
1071  peers[i].op =
1072  GNUNET_TESTBED_peer_get_information(testbed_handles[i],
1074  &peer_id_cb, (void *)i);
1075  }
1076  GNUNET_log(GNUNET_ERROR_TYPE_INFO, "requested peer ids\n");
1077  /* Continues from pi_cb -> do_test */
1078 }
1079 
1080 
1084 int
1085 main(int argc, char *argv[])
1086 {
1087  static const struct GNUNET_HashCode *ports[2];
1088  const char *config_file;
1089 
1090  config_file = ".profiler.conf";
1091 
1092  if (4 > argc)
1093  {
1094  fprintf(stderr,
1095  "usage: %s ROUND_TIME PEERS PINGS [DO_WARMUP]\n",
1096  argv[0]);
1097  fprintf(stderr,
1098  "example: %s 30s 16 1 Y\n",
1099  argv[0]);
1100  return 1;
1101  }
1102 
1103  if (GNUNET_OK !=
1105  &round_time))
1106  {
1107  fprintf(stderr,
1108  "%s is not a valid time\n",
1109  argv[1]);
1110  return 1;
1111  }
1112 
1113  peers_total = atoll(argv[2]);
1114  if (2 > peers_total)
1115  {
1116  fprintf(stderr,
1117  "%s peers is not valid (> 2)\n",
1118  argv[1]);
1119  return 1;
1120  }
1121  peers = GNUNET_new_array(peers_total,
1122  struct CadetPeer);
1123  peers_pinging = atoll(argv[3]);
1124 
1125  if (peers_total < 2 * peers_pinging)
1126  {
1128  "not enough peers, total should be > 2 * peers_pinging\n");
1129  return 1;
1130  }
1131 
1132  do_warmup = (5 > argc || argv[4][0] != 'N');
1133 
1135  GNUNET_YES);
1136  GNUNET_assert(NULL != ids);
1137  p_ids = 0;
1139  ports[0] = GC_u2h(1);
1140  ports[1] = 0;
1141  GNUNET_CADET_TEST_run("cadet-profiler", config_file, peers_total,
1142  &tmain, NULL, /* tmain cls */
1144  handlers, ports);
1145  GNUNET_free(peers);
1146 
1147  return 0;
1148 }
1149 
1150 /* 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:720
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:671
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.
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:1284
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:350
#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.
#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:79
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:517
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:1237
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:1264
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:686
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:440
#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:2037
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:66
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:951
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:1065
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
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:2314
int data_received
Number of payload packets received.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
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: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: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:655
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:900
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:956