GNUnet  0.11.x
gnunet-rps-profiler.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2012 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  */
27 #include "platform.h"
28 // #include "rps_test_lib.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet_testbed_service.h"
31 
32 #include "gnunet_rps_service.h"
33 #include "rps-test_util.h"
35 
36 #include <inttypes.h>
37 
38 
39 #define BIT(n) (1 << (n))
40 
44 static uint32_t num_peers;
45 
49 static unsigned bits_needed;
50 
55 
60 
61 
62 // /**
63 // * Portion of malicious peers
64 // */
65 // static double portion = .1;
66 
70 static unsigned int mal_type = 0;
71 
76 
78 {
111  STAT_TYPE_MAX, /* 32 */
112 };
113 
114 static char*stat_type_strings[] = {
115  "# rounds",
116  "# rounds blocked",
117  "# rounds blocked - too many pushes",
118  "# rounds blocked - no pushes",
119  "# rounds blocked - no pull replies",
120  "# rounds blocked - too many pushes, no pull replies",
121  "# rounds blocked - no pushes, no pull replies",
122  "# push send issued",
123  "# push send issued (multi-hop peer)",
124  "# pull request send issued",
125  "# pull request send issued (multi-hop peer)",
126  "# pull reply send issued",
127  "# pushes sent",
128  "# pull requests sent",
129  "# pull requests sent (multi-hop peer)",
130  "# pull replies sent",
131  "# push message received",
132  "# push message received (multi-hop peer)",
133  "# pull request message received",
134  "# pull request message received (multi-hop peer)",
135  "# pull reply messages received",
136  "# pull reply messages received (multi-hop peer)",
137  "view size",
138  "# known peers",
139  "# valid peers",
140  "# learnd peers",
141  "# pending online checks",
142  "# unrequested pull replies",
143  "# peers in push map at end of round",
144  "# peers in pull map at end of round",
145  "# peers in view at end of round",
146  "view size aim",
147 };
148 
149 struct STATcls
150 {
151  struct RPSPeer *rps_peer;
153 };
154 
155 
163 enum STAT_TYPE
164 stat_str_2_type (const char *stat_str)
165 {
166  if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL],
167  stat_str,
168  strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL])))
169  {
171  }
173  stat_str,
174  strlen (
175  stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL])))
176  {
178  }
179  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH],
180  stat_str,
181  strlen (
182  stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH])))
183  {
185  }
186  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
187  stat_str,
188  strlen (
189  stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL])))
190  {
192  }
193  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH],
194  stat_str,
195  strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH])))
196  {
198  }
199  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS],
200  stat_str,
201  strlen (stat_type_strings[STAT_TYPE_BLOCKS])))
202  {
203  return STAT_TYPE_BLOCKS;
204  }
205  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ROUNDS],
206  stat_str,
207  strlen (stat_type_strings[STAT_TYPE_ROUNDS])))
208  {
209  return STAT_TYPE_ROUNDS;
210  }
211  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND],
212  stat_str,
213  strlen (
214  stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND])))
215  {
217  }
218  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH],
219  stat_str,
220  strlen (
221  stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH])))
222  {
224  }
225  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ],
226  stat_str,
227  strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ])))
228  {
230  }
231  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH],
232  stat_str,
233  strlen (
234  stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH])))
235  {
237  }
238  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REP],
239  stat_str,
240  strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REP])))
241  {
243  }
244  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PUSH_SEND],
245  stat_str,
246  strlen (stat_type_strings[STAT_TYPE_SENT_PUSH_SEND])))
247  {
249  }
250  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REQ],
251  stat_str,
252  strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REQ])))
253  {
255  }
256  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH],
257  stat_str,
258  strlen (
259  stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH])))
260  {
262  }
263  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REP],
264  stat_str,
265  strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REP])))
266  {
268  }
269  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND],
270  stat_str,
271  strlen (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND])))
272  {
274  }
275  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH],
276  stat_str,
277  strlen (
278  stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH])))
279  {
281  }
282  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REQ],
283  stat_str,
284  strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REQ])))
285  {
287  }
288  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH],
289  stat_str,
290  strlen (
291  stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH])))
292  {
294  }
295  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REP],
296  stat_str,
297  strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REP])))
298  {
300  }
301  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH],
302  stat_str,
303  strlen (
304  stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH])))
305  {
307  }
308  else if (0 == strncmp (stat_type_strings[STAT_TYPE_VIEW_SIZE],
309  stat_str,
310  strlen (stat_type_strings[STAT_TYPE_VIEW_SIZE])))
311  {
312  return STAT_TYPE_VIEW_SIZE;
313  }
314  else if (0 == strncmp (stat_type_strings[STAT_TYPE_KNOWN_PEERS],
315  stat_str,
316  strlen (stat_type_strings[STAT_TYPE_KNOWN_PEERS])))
317  {
318  return STAT_TYPE_KNOWN_PEERS;
319  }
320  else if (0 == strncmp (stat_type_strings[STAT_TYPE_VALID_PEERS],
321  stat_str,
322  strlen (stat_type_strings[STAT_TYPE_VALID_PEERS])))
323  {
324  return STAT_TYPE_VALID_PEERS;
325  }
326  else if (0 == strncmp (stat_type_strings[STAT_TYPE_LEARND_PEERS],
327  stat_str,
328  strlen (stat_type_strings[STAT_TYPE_LEARND_PEERS])))
329  {
330  return STAT_TYPE_LEARND_PEERS;
331  }
332  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS],
333  stat_str,
334  strlen (
335  stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS])))
336  {
338  }
340  stat_str,
341  strlen (
342  stat_type_strings[STAT_TYPE_UNREQUESTED_PULL_REPLIES])))
343  {
345  }
346  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP],
347  stat_str,
348  strlen (
349  stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP])))
350  {
352  }
353  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP],
354  stat_str,
355  strlen (
356  stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP])))
357  {
359  }
360  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_VIEW],
361  stat_str,
362  strlen (stat_type_strings[STAT_TYPE_PEERS_IN_VIEW])))
363  {
365  }
366  else if (0 == strncmp (stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM],
367  stat_str,
368  strlen (stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM])))
369  {
371  }
372  return STAT_TYPE_MAX;
373 }
374 
375 
380 {
389 };
390 
394 struct OpListEntry
395 {
399  struct OpListEntry *next;
400 
404  struct OpListEntry *prev;
405 
410 
416 
420  unsigned int index;
421 };
422 
426 static struct OpListEntry *oplist_head;
427 
431 static struct OpListEntry *oplist_tail;
432 
433 
438 {
444 
449 
453  struct RPSPeer *rps_peer;
454 };
455 
456 
461 {
467 
472 
476  struct RPSPeer *rps_peer;
477 };
478 
479 
483 struct RPSPeer
484 {
488  uint32_t index;
489 
494 
499 
504 
508  // struct GNUNET_RPS_Request_Handle *req_handle;
509 
513  int online;
514 
518  unsigned int num_ids_to_request;
519 
525 
529  unsigned int num_pending_reqs;
530 
536 
540  unsigned int num_pending_reps;
541 
545  unsigned int num_recv_ids;
546 
551 
556 
561 
568 
572  const char *file_name_stats;
573 
577  const char *file_name_probs;
578 
582  const char *file_name_probs_hist;
583 
588 
592  uint32_t cur_view_count;
593 
597  uint32_t count_in_views;
598 
602  uint64_t stats[STAT_TYPE_MAX];
607 
613 };
614 
618 static struct RPSPeer *rps_peers;
619 
624 
629 
634 
638 static unsigned int num_peers_online;
639 
643 static unsigned int view_sizes;
644 
648 static int ok;
649 
654 
659 
660 
665 
669 typedef void (*InitPeer) (struct RPSPeer *rps_peer);
670 
677 typedef void (*PreTest) (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h);
678 
688 typedef void (*MainTest) (struct RPSPeer *rps_peer);
689 
693 typedef void (*ReplyHandle) (void *cls,
694  uint64_t n,
695  const struct GNUNET_PeerIdentity *recv_peers);
696 
700 typedef void (*PostTest) (struct RPSPeer *peer);
701 
705 typedef int (*EvaluationCallback) (void);
706 
711 {
720 };
721 
726 {
731 
736 };
737 
742 {
747 
752 };
753 
758 {
763 
768 };
769 
774 {
778  char *name;
779 
784 
789 
794 
799 
804 
809 
814 
818  uint32_t num_requests;
819 
823  enum OPTION_CHURN have_churn;
824 
828  enum OPTION_QUICK_QUIT have_quick_quit;
829 
833  enum OPTION_COLLECT_STATISTICS have_collect_statistics;
834 
838  enum OPTION_COLLECT_VIEW have_collect_view;
839 
845 } cur_test_run;
846 
850 static int post_test;
851 
855 static int in_shutdown;
856 
860 static void
861 tofile_ (const char *file_name, const char *line)
862 {
863  struct GNUNET_DISK_FileHandle *f;
864  /* char output_buffer[512]; */
865  size_t size;
866  /* int size; */
867  size_t size2;
868 
869  if (NULL == (f = GNUNET_DISK_file_open (file_name,
877  {
879  "Not able to open file %s\n",
880  file_name);
881  return;
882  }
883  /* size = GNUNET_snprintf (output_buffer,
884  sizeof (output_buffer),
885  "%llu %s\n",
886  GNUNET_TIME_absolute_get ().abs_value_us,
887  line);
888  if (0 > size)
889  {
890  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
891  "Failed to write string to buffer (size: %i)\n",
892  size);
893  return;
894  } */size = strlen (line) * sizeof(char);
895 
896  size2 = GNUNET_DISK_file_write (f, line, size);
897  if (size != size2)
898  {
900  "Unable to write to file! (Size: %lu, size2: %lu)\n",
901  size,
902  size2);
904  {
906  "Unable to close file\n");
907  }
908  return;
909  }
910 
912  {
914  "Unable to close file\n");
915  }
916 }
917 
918 
922 #define tofile(file_name, ...) do { \
923  char tmp_buf[512]; \
924  int size; \
925  size = GNUNET_snprintf (tmp_buf, sizeof(tmp_buf), __VA_ARGS__); \
926  if (0 > size) \
927  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
928  "Failed to create tmp_buf\n"); \
929  else \
930  tofile_ (file_name, tmp_buf); \
931 } while (0);
932 
933 
938 /* static void
939  ids_to_file (char *file_name,
940  struct GNUNET_PeerIdentity *peer_ids,
941  unsigned int num_peer_ids)
942  {
943  unsigned int i;
944 
945  for (i=0 ; i < num_peer_ids ; i++)
946  {
947  to_file (file_name,
948  "%u\t%s",
949  i,
950  GNUNET_i2s_full (&peer_ids[i]));
951  }
952  } */
953 
957 static int
958 evaluate (void)
959 {
960  unsigned int i;
961  int tmp_ok;
962 
963  tmp_ok = 1;
964 
965  for (i = 0; i < num_peers; i++)
966  {
968  "%u. peer [%s] received %u of %u expected peer_ids: %i\n",
969  i,
970  GNUNET_i2s (rps_peers[i].peer_id),
971  rps_peers[i].num_recv_ids,
972  rps_peers[i].num_ids_to_request,
973  (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids));
974  tmp_ok &= (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids);
975  }
976  return tmp_ok ? 0 : 1;
977 }
978 
979 
983 static struct OpListEntry *
985 {
986  struct OpListEntry *entry;
987 
988  entry = GNUNET_new (struct OpListEntry);
989  GNUNET_CONTAINER_DLL_insert_tail (oplist_head, oplist_tail, entry);
990  return entry;
991 }
992 
993 
1003 static int
1005  const struct RPSPeer *rps_peer)
1006 {
1009  & rps_peer->stat_collected_flags))
1010  {
1011  return GNUNET_NO;
1012  }
1013  return GNUNET_YES;
1014 }
1015 
1016 
1024 static int
1026 {
1027  uint32_t i;
1028 
1029  for (i = 0; i < num_peers; i++)
1030  {
1032  &rps_peers[i]))
1033  {
1035  "At least Peer %" PRIu32
1036  " did not yet receive all statistics values\n",
1037  i);
1038  return GNUNET_NO;
1039  }
1040  }
1042  "All peers received their statistics values\n");
1043  return GNUNET_YES;
1044 }
1045 
1046 
1047 static void
1048 rps_disconnect_adapter (void *cls,
1049  void *op_result);
1050 
1051 static void
1052 cancel_pending_req (struct PendingRequest *pending_req)
1053 {
1054  struct RPSPeer *rps_peer;
1055 
1056  rps_peer = pending_req->rps_peer;
1058  rps_peer->pending_req_tail,
1059  pending_req);
1060  rps_peer->num_pending_reqs--;
1062  "Cancelling pending rps get request\n");
1063  GNUNET_SCHEDULER_cancel (pending_req->request_task);
1064  GNUNET_free (pending_req);
1065 }
1066 
1067 
1068 static void
1069 cancel_request (struct PendingReply *pending_rep)
1070 {
1071  struct RPSPeer *rps_peer;
1072 
1073  rps_peer = pending_rep->rps_peer;
1075  rps_peer->pending_rep_tail,
1076  pending_rep);
1077  rps_peer->num_pending_reps--;
1079  "Cancelling rps get reply\n");
1080  GNUNET_assert (NULL != pending_rep->req_handle);
1082  pending_rep->req_handle = NULL;
1083  GNUNET_free (pending_rep);
1084  pending_rep = NULL;
1085 }
1086 
1087 
1088 void
1089 clean_peer (unsigned peer_index)
1090 {
1091  struct PendingRequest *pending_req;
1092 
1093  while (NULL != (pending_req = rps_peers[peer_index].pending_req_head))
1094  {
1095  cancel_pending_req (pending_req);
1096  }
1097  pending_req = rps_peers[peer_index].pending_req_head;
1098  rps_disconnect_adapter (&rps_peers[peer_index],
1099  &rps_peers[peer_index].rps_handle);
1100  for (unsigned stat_type = STAT_TYPE_ROUNDS;
1102  stat_type++)
1103  {
1104  if (NULL != rps_peers[peer_index].h_stat_get[stat_type])
1105  {
1107  "(%u) did not yet receive stat value for `%s'\n",
1108  rps_peers[peer_index].index,
1109  stat_type_strings[stat_type]);
1111  rps_peers[peer_index].h_stat_get[stat_type]);
1112  }
1113  }
1114  if (NULL != rps_peers[peer_index].op)
1115  {
1116  GNUNET_TESTBED_operation_done (rps_peers[peer_index].op);
1117  rps_peers[peer_index].op = NULL;
1118  }
1119 }
1120 
1121 
1125 static void
1126 shutdown_op (void *cls)
1127 {
1128  unsigned int i;
1129  struct OpListEntry *entry;
1130 
1131  (void) cls;
1132 
1134  "Shutdown task scheduled, going down.\n");
1136 
1137  if (NULL != shutdown_task)
1138  {
1139  GNUNET_SCHEDULER_cancel (shutdown_task);
1140  shutdown_task = NULL;
1141  }
1142  if (NULL != post_test_task)
1143  {
1144  GNUNET_SCHEDULER_cancel (post_test_task);
1145  post_test_task = NULL;
1146  }
1147  if (NULL != churn_task)
1148  {
1149  GNUNET_SCHEDULER_cancel (churn_task);
1150  churn_task = NULL;
1151  }
1152  entry = oplist_head;
1153  while (NULL != (entry = oplist_head))
1154  {
1156  "Operation still pending on shutdown (%u)\n",
1157  entry->index);
1159  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1160  GNUNET_free (entry);
1161  }
1162  for (i = 0; i < num_peers; i++)
1163  {
1164  clean_peer (i);
1165  }
1166  close_all_files ();
1167 }
1168 
1169 
1170 static void
1171 trigger_shutdown (void *cls)
1172 {
1173  (void) cls;
1174 
1176  "Shutdown was triggered by timeout, going down.\n");
1177  shutdown_task = NULL;
1179 }
1180 
1181 
1185 static void
1186 post_test_op (void *cls)
1187 {
1188  unsigned int i;
1189 
1190  (void) cls;
1191 
1192  post_test_task = NULL;
1195  "Executing post test op.\n");
1196  if (NULL != churn_task)
1197  {
1198  GNUNET_SCHEDULER_cancel (churn_task);
1199  churn_task = NULL;
1200  }
1201  for (i = 0; i < num_peers; i++)
1202  {
1204  "Executing post test op. (peer %" PRIu32 ")\n",
1205  rps_peers[i].index);
1206  if (NULL != rps_peers[i].op)
1207  {
1208  GNUNET_TESTBED_operation_done (rps_peers[i].op);
1209  rps_peers[i].op = NULL;
1211  "Cancelled testbed operation\n");
1212  }
1213  if (NULL != cur_test_run.post_test)
1214  {
1215  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n",
1216  i);
1217  cur_test_run.post_test (&rps_peers[i]);
1218  }
1219  }
1220  /* If we do not collect statistics, shut down directly */
1223  {
1224  GNUNET_SCHEDULER_cancel (shutdown_task);
1225  shutdown_task = NULL;
1227  }
1228 }
1229 
1230 
1234 void
1235 info_cb (void *cb_cls,
1236  struct GNUNET_TESTBED_Operation *op,
1237  const struct GNUNET_TESTBED_PeerInformation *pinfo,
1238  const char *emsg)
1239 {
1240  struct OpListEntry *entry = (struct OpListEntry *) cb_cls;
1241 
1242  (void) op;
1243 
1244  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1245  {
1246  return;
1247  }
1248 
1249  if ((NULL == pinfo) || (NULL != emsg))
1250  {
1251  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
1253  return;
1254  }
1255 
1257  "Peer %u is %s\n",
1258  entry->index,
1259  GNUNET_i2s (pinfo->result.id));
1260 
1261  rps_peer_ids[entry->index] = *(pinfo->result.id);
1262  rps_peers[entry->index].peer_id = &rps_peer_ids[entry->index];
1263 
1266  &rps_peer_ids[entry->index],
1267  &rps_peers[entry->index],
1269  tofile ("/tmp/rps/peer_ids",
1270  "%u\t%s\n",
1271  entry->index,
1272  GNUNET_i2s_full (&rps_peer_ids[entry->index]));
1273 
1274  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1276  GNUNET_free (entry);
1277 }
1278 
1279 
1289 static void
1291  struct GNUNET_TESTBED_Operation *op,
1292  void *ca_result,
1293  const char *emsg)
1294 {
1295  struct RPSPeer *rps_peer = cls;
1296  struct GNUNET_RPS_Handle *rps = ca_result;
1297 
1298  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1299  {
1300  return;
1301  }
1302 
1303  rps_peer->rps_handle = rps;
1304  rps_peer->online = GNUNET_YES;
1305  num_peers_online++;
1306 
1307  GNUNET_assert (op == rps_peer->op);
1308  if (NULL != emsg)
1309  {
1311  "Failed to connect to RPS service: %s\n",
1312  emsg);
1313  ok = 1;
1315  return;
1316  }
1317 
1319  "Started client successfully (%u)\n",
1320  rps_peer->index);
1321 
1322  cur_test_run.main_test (rps_peer);
1323 }
1324 
1325 
1336 static void *
1338  const struct GNUNET_CONFIGURATION_Handle *cfg)
1339 {
1340  struct GNUNET_RPS_Handle *h;
1341 
1342  h = GNUNET_RPS_connect (cfg);
1343 
1344  if (NULL != cur_test_run.pre_test)
1345  cur_test_run.pre_test (cls, h);
1346 
1347  return h;
1348 }
1349 
1350 
1360 static void *
1362  const struct GNUNET_CONFIGURATION_Handle *cfg)
1363 {
1364  struct RPSPeer *peer = cls;
1365 
1366  peer->stats_h = GNUNET_STATISTICS_create ("rps-profiler", cfg);
1367  return peer->stats_h;
1368 }
1369 
1370 
1377 static void
1379 {
1380  struct RPSPeer *peer = cls;
1381 
1382  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1383  // (peer->stats_h, "core", "# peers connected",
1384  // stat_iterator, peer));
1385  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1386  // (peer->stats_h, "nse", "# peers connected",
1387  // stat_iterator, peer));
1388  GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
1389  peer->stats_h = NULL;
1390 }
1391 
1392 
1403 static void
1404 stat_complete_cb (void *cls,
1405  struct GNUNET_TESTBED_Operation *op,
1406  void *ca_result,
1407  const char *emsg)
1408 {
1409  // struct GNUNET_STATISTICS_Handle *sh = ca_result;
1410  // struct RPSPeer *peer = (struct RPSPeer *) cls;
1411  (void) cls;
1412  (void) op;
1413  (void) ca_result;
1414 
1415  if (NULL != emsg)
1416  {
1417  GNUNET_break (0);
1418  return;
1419  }
1420  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1421  // (sh, "core", "# peers connected",
1422  // stat_iterator, peer));
1423  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1424  // (sh, "nse", "# peers connected",
1425  // stat_iterator, peer));
1426 }
1427 
1428 
1436 static void
1438  void *op_result)
1439 {
1440  struct RPSPeer *peer = cls;
1441  struct GNUNET_RPS_Handle *h = op_result;
1442  struct PendingReply *pending_rep;
1443 
1445  "disconnect_adapter (%u)\n",
1446  peer->index);
1447  GNUNET_assert (NULL != peer);
1448  if (NULL != peer->rps_handle)
1449  {
1450  while (NULL != (pending_rep = peer->pending_rep_head))
1451  {
1452  cancel_request (pending_rep);
1453  }
1454  GNUNET_assert (h == peer->rps_handle);
1455  if (NULL != h)
1456  {
1458  h = NULL;
1459  }
1460  peer->rps_handle = NULL;
1461  }
1462 }
1463 
1464 
1465 /***********************************************************************
1466 * Definition of tests
1467 ***********************************************************************/
1468 
1476 static void
1478  uint64_t n,
1479  const struct GNUNET_PeerIdentity *recv_peers)
1480 {
1481  struct RPSPeer *rps_peer;
1482  struct PendingReply *pending_rep = (struct PendingReply *) cls;
1483  unsigned int i;
1484 
1485  rps_peer = pending_rep->rps_peer;
1487  rps_peer->pending_rep_tail,
1488  pending_rep);
1489  rps_peer->num_pending_reps--;
1491  "[%s] got %" PRIu64 " peers:\n",
1492  GNUNET_i2s (rps_peer->peer_id),
1493  n);
1494 
1495  for (i = 0; i < n; i++)
1496  {
1498  "%u: %s\n",
1499  i,
1500  GNUNET_i2s (&recv_peers[i]));
1501 
1502  rps_peer->num_recv_ids++;
1503  }
1504 
1505  if (GNUNET_YES != post_test)
1506  return;
1508  return;
1509  if (0 == evaluate ())
1510  {
1512  "Test succeeded before end of duration\n");
1513  if (NULL != post_test_task)
1514  GNUNET_SCHEDULER_cancel (post_test_task);
1515  post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1516  GNUNET_assert (NULL != post_test_task);
1517  }
1518 }
1519 
1520 
1521 static void
1522 profiler_reply_handle_info (void *cls,
1523  const struct GNUNET_PeerIdentity *recv_peer,
1524  double probability,
1525  uint32_t num_observed);
1526 
1530 static void
1531 request_peers (void *cls)
1532 {
1533  struct PendingRequest *pending_req = cls;
1534  struct RPSPeer *rps_peer;
1535  struct PendingReply *pending_rep;
1536 
1537  rps_peer = pending_req->rps_peer;
1538  GNUNET_assert (1 <= rps_peer->num_pending_reqs);
1540  rps_peer->pending_req_tail,
1541  pending_req);
1542  rps_peer->num_pending_reqs--;
1543  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1544  return;
1546  "Requesting one peer\n");
1547  pending_rep = GNUNET_new (struct PendingReply);
1548  pending_rep->rps_peer = rps_peer;
1549  // pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle,
1550  // 1,
1551  // cur_test_run.reply_handle,
1552  // pending_rep);
1553  pending_rep->req_handle = GNUNET_RPS_request_peer_info (rps_peer->rps_handle,
1555  pending_rep);
1557  rps_peer->pending_rep_tail,
1558  pending_rep);
1559  rps_peer->num_pending_reps++;
1560 }
1561 
1562 
1567 void
1569 {
1570  unsigned int i;
1571  struct PendingRequest *pending_req;
1572 
1574  "Scheduling %u - %u missing requests\n",
1575  rps_peer->num_ids_to_request,
1576  rps_peer->num_pending_reqs + rps_peer->num_pending_reps);
1577  GNUNET_assert (rps_peer->num_pending_reqs + rps_peer->num_pending_reps <=
1578  rps_peer->num_ids_to_request);
1579  for (i = rps_peer->num_pending_reqs + rps_peer->num_pending_reps;
1580  i < rps_peer->num_ids_to_request; i++)
1581  {
1582  pending_req = GNUNET_new (struct PendingRequest);
1583  pending_req->rps_peer = rps_peer;
1587  request_peers,
1588  pending_req);
1590  rps_peer->pending_req_tail,
1591  pending_req);
1592  rps_peer->num_pending_reqs++;
1593  }
1594 }
1595 
1596 
1597 void
1599 {
1601  "Cancelling all (pending) requests.\n");
1602  while (NULL != rps_peer->pending_req_head)
1604  GNUNET_assert (0 == rps_peer->num_pending_reqs);
1605  while (NULL != rps_peer->pending_rep_head)
1606  cancel_request (rps_peer->pending_rep_head);
1607  GNUNET_assert (0 == rps_peer->num_pending_reps);
1608 }
1609 
1610 
1611 /***********************************
1612 * MALICIOUS
1613 ***********************************/
1614 
1616 // * Initialise only non-mal RPSPeers
1617 // */
1618 //static void
1619 //mal_init_peer (struct RPSPeer *rps_peer)
1620 //{
1621 // if (rps_peer->index >= round (portion * num_peers))
1622 // rps_peer->num_ids_to_request = 1;
1623 //}
1624 
1625 
1627 // * @brief Set peers to (non-)malicious before execution
1628 // *
1629 // * Of signature #PreTest
1630 // *
1631 // * @param rps_peer the peer to set (non-) malicious
1632 // * @param h the handle to the service
1633 // */
1634 //static void
1635 //mal_pre (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
1636 //{
1637 // #if ENABLE_MALICIOUS
1638 // uint32_t num_mal_peers;
1639 //
1640 // GNUNET_assert ((1 >= portion) &&
1641 // (0 < portion));
1642 // num_mal_peers = round (portion * num_peers);
1643 //
1644 // if (rps_peer->index < num_mal_peers)
1645 // {
1646 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1647 // "%u. peer [%s] of %" PRIu32
1648 // " malicious peers turning malicious\n",
1649 // rps_peer->index,
1650 // GNUNET_i2s (rps_peer->peer_id),
1651 // num_mal_peers);
1652 //
1653 // GNUNET_RPS_act_malicious (h, mal_type, num_mal_peers,
1654 // rps_peer_ids, target_peer);
1655 // }
1656 // #endif /* ENABLE_MALICIOUS */
1657 //}
1658 
1659 
1660 // static void
1661 // mal_cb (struct RPSPeer *rps_peer)
1662 // {
1663 // if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1664 // {
1665 // return;
1666 // }
1667 //
1668 // #if ENABLE_MALICIOUS
1669 // uint32_t num_mal_peers;
1670 //
1671 // GNUNET_assert ((1 >= portion) &&
1672 // (0 < portion));
1673 // num_mal_peers = round (portion * num_peers);
1674 //
1675 // if (rps_peer->index >= num_mal_peers)
1676 // { /* It's useless to ask a malicious peer about a random sample -
1677 // it's not sampling */
1678 // GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (
1679 // GNUNET_TIME_UNIT_SECONDS, 2),
1680 // seed_peers, rps_peer);
1681 // schedule_missing_requests (rps_peer);
1682 // }
1683 // #endif /* ENABLE_MALICIOUS */
1684 // }
1685 
1686 
1687 /***********************************
1688 * CHURN
1689 ***********************************/
1690 
1691 static void
1692 churn (void *cls);
1693 
1694 
1695 /***********************************
1696 * PROFILER
1697 ***********************************/
1698 
1706 static void
1707 churn_cb (void *cls,
1708  struct GNUNET_TESTBED_Operation *op,
1709  const char *emsg)
1710 {
1711  // FIXME
1712  struct OpListEntry *entry = cls;
1713 
1714  (void) op;
1715 
1716  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1717  {
1718  return;
1719  }
1720 
1722  if (NULL != emsg)
1723  {
1725  "Failed to start/stop RPS at a peer\n");
1727  return;
1728  }
1729  GNUNET_assert (0 != entry->delta);
1730 
1731  num_peers_online += entry->delta;
1732 
1733  if (PEER_GO_OFFLINE == entry->delta)
1734  { /* Peer hopefully just went offline */
1735  if (GNUNET_YES != rps_peers[entry->index].online)
1736  {
1738  "peer %s was expected to go offline but is still marked as online\n",
1739  GNUNET_i2s (rps_peers[entry->index].peer_id));
1740  GNUNET_break (0);
1741  }
1742  else
1743  {
1745  "peer %s probably went offline as expected\n",
1746  GNUNET_i2s (rps_peers[entry->index].peer_id));
1747  }
1748  rps_peers[entry->index].online = GNUNET_NO;
1749  }
1750 
1751  else if (PEER_GO_ONLINE < entry->delta)
1752  { /* Peer hopefully just went online */
1753  if (GNUNET_NO != rps_peers[entry->index].online)
1754  {
1756  "peer %s was expected to go online but is still marked as offline\n",
1757  GNUNET_i2s (rps_peers[entry->index].peer_id));
1758  GNUNET_break (0);
1759  }
1760  else
1761  {
1763  "peer %s probably went online as expected\n",
1764  GNUNET_i2s (rps_peers[entry->index].peer_id));
1765  if (NULL != cur_test_run.pre_test)
1766  {
1767  cur_test_run.pre_test (&rps_peers[entry->index],
1768  rps_peers[entry->index].rps_handle);
1769  schedule_missing_requests (&rps_peers[entry->index]);
1770  }
1771  }
1772  rps_peers[entry->index].online = GNUNET_YES;
1773  }
1774  else
1775  {
1777  "Invalid value for delta: %i\n", entry->delta);
1778  GNUNET_break (0);
1779  }
1780 
1781  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1782  rps_peers[entry->index].entry_op_manage = NULL;
1783  GNUNET_free (entry);
1784  // if (num_peers_in_round[current_round] == peers_running)
1785  // run_round ();
1786 }
1787 
1788 
1797 static void
1798 manage_service_wrapper (unsigned int i, unsigned int j,
1799  enum PEER_ONLINE_DELTA delta,
1800  double prob_go_on_off)
1801 {
1802  struct OpListEntry *entry = NULL;
1803  uint32_t prob;
1804 
1805  /* make sure that management operation is not already scheduled */
1806  if (NULL != rps_peers[j].entry_op_manage)
1807  {
1808  return;
1809  }
1810 
1812  UINT32_MAX);
1814  "%u. selected peer (%u: %s) is %s.\n",
1815  i,
1816  j,
1817  GNUNET_i2s (rps_peers[j].peer_id),
1818  (PEER_GO_ONLINE == delta) ? "online" : "offline");
1819  if (prob < prob_go_on_off * UINT32_MAX)
1820  {
1822  "%s goes %s\n",
1823  GNUNET_i2s (rps_peers[j].peer_id),
1824  (PEER_GO_OFFLINE == delta) ? "offline" : "online");
1825 
1826  if (PEER_GO_OFFLINE == delta)
1827  cancel_pending_req_rep (&rps_peers[j]);
1828  entry = make_oplist_entry ();
1829  entry->delta = delta;
1830  entry->index = j;
1831  entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
1832  testbed_peers[j],
1833  "rps",
1834  &churn_cb,
1835  entry,
1836  (PEER_GO_OFFLINE == delta) ?
1837  0 : 1);
1838  rps_peers[j].entry_op_manage = entry;
1839  }
1840 }
1841 
1842 
1843 static void
1844 churn (void *cls)
1845 {
1846  unsigned int i;
1847  unsigned int j;
1848  double portion_online;
1849  unsigned int *permut;
1850  double prob_go_offline;
1851  double portion_go_online;
1852  double portion_go_offline;
1853 
1854  (void) cls;
1855 
1856  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1857  {
1858  return;
1859  }
1861  "Churn function executing\n");
1862 
1863  churn_task = NULL; /* Should be invalid by now */
1864 
1865  /* Compute the probability for an online peer to go offline
1866  * this round */
1867  portion_online = num_peers_online * 1.0 / num_peers;
1869  "Portion online: %f\n",
1870  portion_online);
1871  portion_go_online = ((1 - portion_online) * .5 * .66);
1873  "Portion that should go online: %f\n",
1874  portion_go_online);
1875  portion_go_offline = (portion_online + portion_go_online) - .75;
1877  "Portion that probably goes offline: %f\n",
1878  portion_go_offline);
1879  prob_go_offline = portion_go_offline / (portion_online * .5);
1881  "Probability of a selected online peer to go offline: %f\n",
1882  prob_go_offline);
1883 
1885  (unsigned int) num_peers);
1886 
1887  /* Go over 50% randomly chosen peers */
1888  for (i = 0; i < .5 * num_peers; i++)
1889  {
1890  j = permut[i];
1891 
1892  /* If online, shut down with certain probability */
1893  if (GNUNET_YES == rps_peers[j].online)
1894  {
1895  manage_service_wrapper (i, j, -1, prob_go_offline);
1896  }
1897 
1898  /* If offline, restart with certain probability */
1899  else if (GNUNET_NO == rps_peers[j].online)
1900  {
1901  manage_service_wrapper (i, j, 1, 0.66);
1902  }
1903  }
1904 
1905  GNUNET_free (permut);
1906 
1907  churn_task = GNUNET_SCHEDULER_add_delayed (
1909  churn,
1910  NULL);
1911 }
1912 
1913 
1917 static void
1918 profiler_init_peer (struct RPSPeer *rps_peer)
1919 {
1921  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer shall request %i peers\n",
1922  rps_peer->num_ids_to_request);
1923 }
1924 
1925 
1933 static void
1935  uint64_t n,
1936  const struct GNUNET_PeerIdentity *recv_peers)
1937 {
1938  struct RPSPeer *rps_peer;
1939  struct RPSPeer *rcv_rps_peer;
1940  char file_name_buf[128];
1941  char file_name_dh_buf[128];
1942  char file_name_dhr_buf[128];
1943  char file_name_dhru_buf[128];
1944  char *file_name = file_name_buf;
1945  char *file_name_dh = file_name_dh_buf;
1946  char *file_name_dhr = file_name_dhr_buf;
1947  char *file_name_dhru = file_name_dhru_buf;
1948  unsigned int i;
1949  struct PendingReply *pending_rep = (struct PendingReply *) cls;
1950 
1951  pending_rep->req_handle = NULL;
1952  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
1953  rps_peer = pending_rep->rps_peer;
1954  (void) GNUNET_asprintf (&file_name,
1955  "/tmp/rps/received_ids-%u",
1956  rps_peer->index);
1957 
1958  (void) GNUNET_asprintf (&file_name_dh,
1959  "/tmp/rps/diehard_input-%u",
1960  rps_peer->index);
1961  (void) GNUNET_asprintf (&file_name_dhr,
1962  "/tmp/rps/diehard_input_raw-%u",
1963  rps_peer->index);
1964  (void) GNUNET_asprintf (&file_name_dhru,
1965  "/tmp/rps/diehard_input_raw_aligned-%u",
1966  rps_peer->index);
1968  "[%s] got %" PRIu64 " peers:\n",
1969  GNUNET_i2s (rps_peer->peer_id),
1970  n);
1971  for (i = 0; i < n; i++)
1972  {
1974  "%u: %s\n",
1975  i,
1976  GNUNET_i2s (&recv_peers[i]));
1977  tofile (file_name,
1978  "%s\n",
1979  GNUNET_i2s_full (&recv_peers[i]));
1980  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, &recv_peers[i]);
1981  GNUNET_assert (NULL != rcv_rps_peer);
1982  tofile (file_name_dh,
1983  "%" PRIu32 "\n",
1984  (uint32_t) rcv_rps_peer->index);
1985 #ifdef TO_FILE
1986  to_file_raw (file_name_dhr,
1987  (char *) &rcv_rps_peer->index,
1988  sizeof(uint32_t));
1989  to_file_raw_unaligned (file_name_dhru,
1990  (char *) &rcv_rps_peer->index,
1991  sizeof(uint32_t),
1992  bits_needed);
1993 #endif /* TO_FILE */
1994  }
1995  default_reply_handle (cls, n, recv_peers);
1996 }
1997 
1998 
2006 static void
2008  const struct GNUNET_PeerIdentity *recv_peer,
2009  double probability,
2010  uint32_t num_observed)
2011 {
2012  struct RPSPeer *rps_peer;
2013  struct RPSPeer *rcv_rps_peer;
2014  char file_name_buf[128];
2015  char file_name_dh_buf[128];
2016  char file_name_dhr_buf[128];
2017  char file_name_dhru_buf[128];
2018  char *file_name = file_name_buf;
2019  char *file_name_dh = file_name_dh_buf;
2020  char *file_name_dhr = file_name_dhr_buf;
2021  char *file_name_dhru = file_name_dhru_buf;
2022  struct PendingReply *pending_rep = (struct PendingReply *) cls;
2023 
2024  pending_rep->req_handle = NULL;
2025  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2026  rps_peer = pending_rep->rps_peer;
2027  (void) GNUNET_asprintf (&file_name,
2028  "/tmp/rps/received_ids-%u",
2029  rps_peer->index);
2030 
2031  (void) GNUNET_asprintf (&file_name_dh,
2032  "/tmp/rps/diehard_input-%u",
2033  rps_peer->index);
2034  (void) GNUNET_asprintf (&file_name_dhr,
2035  "/tmp/rps/diehard_input_raw-%u",
2036  rps_peer->index);
2037  (void) GNUNET_asprintf (&file_name_dhru,
2038  "/tmp/rps/diehard_input_raw_aligned-%u",
2039  rps_peer->index);
2041  "[%s] got peer with info:\n",
2042  GNUNET_i2s (rps_peer->peer_id));
2044  " %s\n",
2045  GNUNET_i2s (recv_peer));
2046  tofile (file_name,
2047  "%s %f %" PRIu32 " \n",
2048  GNUNET_i2s_full (recv_peer),
2049  probability,
2050  num_observed);
2051  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, recv_peer);
2052  GNUNET_assert (NULL != rcv_rps_peer);
2053  tofile (file_name_dh,
2054  "%" PRIu32 "\n",
2055  (uint32_t) rcv_rps_peer->index);
2056 #ifdef TO_FILE
2057  to_file_raw (file_name_dhr,
2058  (char *) &rcv_rps_peer->index,
2059  sizeof(uint32_t));
2060  to_file_raw_unaligned (file_name_dhru,
2061  (char *) &rcv_rps_peer->index,
2062  sizeof(uint32_t),
2063  bits_needed);
2064 #endif /* TO_FILE */
2065  default_reply_handle (cls, 1, recv_peer);
2066 }
2067 
2068 
2069 static void
2070 profiler_cb (struct RPSPeer *rps_peer)
2071 {
2072  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
2073  {
2074  return;
2075  }
2076 
2077  /* Start churn */
2078  if ((HAVE_CHURN == cur_test_run.have_churn) && (NULL == churn_task))
2079  {
2081  "Starting churn task\n");
2082  churn_task = GNUNET_SCHEDULER_add_delayed (
2084  churn,
2085  NULL);
2086  }
2087  else
2088  {
2090  "Not starting churn task\n");
2091  }
2092 
2093  /* Only request peer ids at one peer.
2094  * (It's the before-last because last one is target of the focused attack.)
2095  */
2096  if (0 < rps_peer->num_ids_to_request)
2097  schedule_missing_requests (rps_peer);
2098 }
2099 
2100 
2110 static int
2111 file_name_cb (void *cls, const char *filename)
2112 {
2113  if (NULL != strstr (filename, "sampler_el"))
2114  {
2115  struct RPS_SamplerElement *s_elem;
2116  struct GNUNET_CRYPTO_AuthKey auth_key;
2117  const char *key_char;
2118  uint32_t i;
2119  (void) cls;
2120 
2121  key_char = filename + 20; /* Length of "/tmp/rps/sampler_el-" */
2122  tofile (filename, "--------------------------\n");
2123 
2124  auth_key = string_to_auth_key (key_char);
2125  s_elem = RPS_sampler_elem_create ();
2126  RPS_sampler_elem_set (s_elem, auth_key);
2127 
2128  for (i = 0; i < num_peers; i++)
2129  {
2130  RPS_sampler_elem_next (s_elem, &rps_peer_ids[i]);
2131  }
2132  RPS_sampler_elem_destroy (s_elem);
2133  }
2134  return GNUNET_OK;
2135 }
2136 
2137 
2143 static int
2145 {
2146 #ifdef TO_FILE
2147  /* Compute perfect sample for each sampler element */
2148  if (-1 == GNUNET_DISK_directory_scan ("/tmp/rps/", file_name_cb, NULL))
2149  {
2150  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Scan of directory failed\n");
2151  }
2152 #endif /* TO_FILE */
2153 
2154  return evaluate ();
2155 }
2156 
2157 
2165 static int
2166 is_in_view (uint32_t a, uint32_t b)
2167 {
2168  uint32_t i;
2169 
2170  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2171  {
2172  if (0 == memcmp (rps_peers[b].peer_id,
2173  &rps_peers[a].cur_view[i],
2174  sizeof(struct GNUNET_PeerIdentity)))
2175  {
2176  return GNUNET_YES;
2177  }
2178  }
2179  return GNUNET_NO;
2180 }
2181 
2182 
2183 static uint32_t
2185 {
2186  uint32_t i;
2187 
2188  for (i = 0; i < num_peers; i++)
2189  {
2190  if (0 == memcmp (pid,
2191  rps_peers[i].peer_id,
2192  sizeof(struct GNUNET_PeerIdentity)))
2193  {
2194  return i;
2195  }
2196  }
2197  // return 0; /* Should not happen - make compiler happy */
2199  "No known _PeerIdentity %s!\n",
2200  GNUNET_i2s_full (pid));
2201  GNUNET_assert (0);
2202 }
2203 
2204 
2213 static uint32_t
2214 count_containing_views (uint32_t a, uint32_t b)
2215 {
2216  uint32_t i;
2217  uint32_t peer_idx;
2218  uint32_t count = 0;
2219 
2220  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2221  {
2222  peer_idx = get_idx_of_pid (&rps_peers[a].cur_view[i]);
2223  if (GNUNET_YES == is_in_view (peer_idx, b))
2224  {
2225  count++;
2226  }
2227  }
2228  return count;
2229 }
2230 
2231 
2238 static void
2239 compute_probabilities (uint32_t peer_idx)
2240 {
2241  // double probs[num_peers] = { 0 };
2242  double probs[num_peers];
2243  double probs_hist[num_peers]; /* Probability respecting the history */
2244  size_t probs_as_str_size = (num_peers * 10 + 2) * sizeof(char);
2245  char *probs_as_str = GNUNET_malloc (probs_as_str_size);
2246  char *probs_as_str_cpy;
2247  uint32_t i;
2248  double prob_push;
2249  double prob_pull;
2250  uint32_t view_size;
2251  uint32_t cont_views;
2252  uint32_t number_of_being_in_pull_events;
2253  int tmp;
2254  double sum_non_zero_prob = 0;
2255  double sum_non_zero_prob_hist = 0;
2256 
2258  "Computing probabilities for peer %" PRIu32 "\n", peer_idx);
2259  /* Firstly without knowledge of old views */
2260  for (i = 0; i < num_peers; i++)
2261  {
2263  "\tfor peer %" PRIu32 ":\n", i);
2264  view_size = rps_peers[i].cur_view_count;
2266  "\t\tview_size: %" PRIu32 "\n", view_size);
2267  /* For peer i the probability of being sampled is
2268  * evenly distributed among all possibly observed peers. */
2269  /* We could have observed a peer in three cases:
2270  * 1. peer sent a push
2271  * 2. peer was contained in a pull reply
2272  * 3. peer was in history (sampler) - ignored for now */
2273  /* 1. Probability of having received a push from peer i */
2274  if ((GNUNET_YES == is_in_view (i, peer_idx)) &&
2275  (1 <= (0.45 * view_size)))
2276  {
2277  if (0 == binom (view_size, 0.45 * view_size))
2278  prob_push = 0;
2279  else
2280  {
2281  prob_push = 1.0 * binom (0.45 * view_size, 1)
2282  /
2283  binom (view_size, 0.45 * view_size);
2284  }
2286  "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
2287  peer_idx,
2288  i,
2289  prob_push);
2291  "\t\tposs choices from view: %" PRIu32 ", containing i: %"
2292  PRIu32 "\n",
2293  binom (view_size, 0.45 * view_size),
2294  binom (0.45 * view_size, 1));
2295  }
2296  else
2297  {
2298  prob_push = 0;
2300  "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
2301  peer_idx,
2302  i);
2303  }
2304  /* 2. Probability of peer i being contained in pulls */
2305  view_size = rps_peers[peer_idx].cur_view_count;
2306  cont_views = count_containing_views (peer_idx, i);
2307  number_of_being_in_pull_events =
2308  (binom (view_size, 0.45 * view_size)
2309  - binom (view_size - cont_views, 0.45 * view_size));
2310  if (0 != number_of_being_in_pull_events)
2311  {
2312  prob_pull = number_of_being_in_pull_events
2313  /
2314  (1.0 * binom (view_size, 0.45 * view_size));
2315  }
2316  else
2317  {
2318  prob_pull = 0;
2319  }
2320  probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
2322  "\t\t%" PRIu32 " has %" PRIu32 " of %" PRIu32
2323  " peers in its view who know %" PRIu32 " prob: %f\n",
2324  peer_idx,
2325  cont_views,
2326  view_size,
2327  i,
2328  prob_pull);
2330  "\t\tnumber of possible pull combinations: %" PRIu32 "\n",
2331  binom (view_size, 0.45 * view_size));
2333  "\t\tnumber of possible pull combinations without %" PRIu32
2334  ": %" PRIu32 "\n",
2335  i,
2336  binom (view_size - cont_views, 0.45 * view_size));
2338  "\t\tnumber of possible pull combinations with %" PRIu32
2339  ": %" PRIu32 "\n",
2340  i,
2341  number_of_being_in_pull_events);
2342 
2343  probs_hist[i] = 0.9 * rps_peers[peer_idx].eval_probs_cache[i] + probs[i];
2344  rps_peers[peer_idx].eval_probs_cache[i] = probs_hist[i];
2345 
2346  sum_non_zero_prob += probs[i];
2347  sum_non_zero_prob_hist += probs_hist[i];
2348  }
2349  /* normalize */
2350  if (0 != sum_non_zero_prob)
2351  {
2352  for (i = 0; i < num_peers; i++)
2353  {
2354  probs[i] = probs[i] * (1.0 / sum_non_zero_prob);
2355  }
2356  }
2357  if (0 != sum_non_zero_prob_hist)
2358  {
2359  for (i = 0; i < num_peers; i++)
2360  {
2361  probs_hist[i] = probs_hist[i] * (1.0 / sum_non_zero_prob_hist);
2362  }
2363  }
2364 
2365  /* str repr */
2366  for (i = 0; i < num_peers; i++)
2367  {
2368  probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2369  tmp = GNUNET_snprintf (probs_as_str,
2370  probs_as_str_size,
2371  "%s %7.6f", probs_as_str_cpy, probs[i]);
2372  GNUNET_free (probs_as_str_cpy);
2373  GNUNET_assert (0 <= tmp);
2374  }
2375 
2376  to_file_w_len (rps_peers[peer_idx].file_name_probs,
2377  probs_as_str_size,
2378  "%s",
2379  probs_as_str);
2380 
2381  probs_as_str[0] = '\0';
2382  for (i = 0; i < num_peers; i++)
2383  {
2384  probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2385  tmp = GNUNET_snprintf (probs_as_str,
2386  probs_as_str_size,
2387  "%s %7.6f", probs_as_str_cpy, probs_hist[i]);
2388  GNUNET_free (probs_as_str_cpy);
2389  GNUNET_assert (0 <= tmp);
2390  }
2391 
2392  to_file_w_len (rps_peers[peer_idx].file_name_probs_hist,
2393  probs_as_str_size,
2394  "%s",
2395  probs_as_str);
2396  GNUNET_free (probs_as_str);
2397 }
2398 
2399 
2409 static uint32_t
2410 count_peer_in_views_2 (uint32_t peer_idx)
2411 {
2412  uint32_t i, j;
2413  uint32_t count = 0;
2414 
2415  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2416  {
2417  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2418  {
2419  if (0 == memcmp (rps_peers[peer_idx].peer_id,
2420  &rps_peers[i].cur_view[j],
2421  sizeof(struct GNUNET_PeerIdentity)))
2422  {
2423  count++;
2424  break;
2425  }
2426  }
2427  }
2428  rps_peers[peer_idx].count_in_views = count;
2429  return count;
2430 }
2431 
2432 
2433 static uint32_t
2435 {
2436  uint32_t i;
2437 
2438  view_sizes = 0;
2439  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2440  {
2441  view_sizes += rps_peers[i].cur_view_count;
2442  }
2443  return view_sizes;
2444 }
2445 
2446 
2447 static void
2448 count_peer_in_views (uint32_t *count_peers)
2449 {
2450  uint32_t i, j;
2451 
2452  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2453  {
2454  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2455  {
2456  if (0 == memcmp (rps_peers[i].peer_id,
2457  &rps_peers[i].cur_view[j],
2458  sizeof(struct GNUNET_PeerIdentity)))
2459  {
2460  count_peers[i]++;
2461  }
2462  }
2463  }
2464 }
2465 
2466 
2467 void
2469 {
2470  uint32_t i;
2471  /* ith entry represents the number of occurrences in other peer's views */
2472  uint32_t *count_peers = GNUNET_new_array (num_peers, uint32_t);
2473  uint32_t views_total_size;
2474  double expected;
2475  /* deviation from expected number of peers */
2476  double *deviation = GNUNET_new_array (num_peers, double);
2477 
2478  views_total_size = 0;
2479  expected = 0;
2480 
2481  /* For each peer count its representation in other peer's views*/
2482  for (i = 0; i < num_peers; i++) /* Peer to count */
2483  {
2484  views_total_size += rps_peers[i].cur_view_count;
2485  count_peer_in_views (count_peers);
2487  "Counted representation of %" PRIu32 "th peer [%s]: %" PRIu32
2488  "\n",
2489  i,
2490  GNUNET_i2s (rps_peers[i].peer_id),
2491  count_peers[i]);
2492  }
2493 
2495  "size of all views combined: %" PRIu32 "\n",
2496  views_total_size);
2497  expected = ((double) 1 / num_peers) * views_total_size;
2499  "Expected number of occurrences of each peer in all views: %f\n",
2500  expected);
2501  for (i = 0; i < num_peers; i++) /* Peer to count */
2502  {
2503  deviation[i] = expected - count_peers[i];
2505  "Deviation from expectation: %f\n", deviation[i]);
2506  }
2507  GNUNET_free (count_peers);
2508  GNUNET_free (deviation);
2509 }
2510 
2511 
2512 void
2514 {
2515  uint32_t i;
2516 
2517  for (i = 0; i < num_peers; i++) /* Peer to count */
2518  {
2520  "View size of %" PRIu32 ". [%s] is %" PRIu32 "\n",
2521  i,
2522  GNUNET_i2s (rps_peers[i].peer_id),
2523  rps_peers[i].cur_view_count);
2524  }
2525 }
2526 
2527 
2528 void
2530 {
2531  compute_diversity ();
2532  print_view_sizes ();
2533 }
2534 
2535 
2536 void
2537 view_update_cb (void *cls,
2538  uint64_t view_size,
2539  const struct GNUNET_PeerIdentity *peers)
2540 {
2542  "View was updated (%" PRIu64 ")\n", view_size);
2543  struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
2544  to_file ("/tmp/rps/view_sizes.txt",
2545  "%" PRIu32 " %" PRIu64 "",
2546  rps_peer->index,
2547  view_size);
2548  for (uint64_t i = 0; i < view_size; i++)
2549  {
2551  "\t%s\n", GNUNET_i2s (&peers[i]));
2552  }
2553  GNUNET_array_grow (rps_peer->cur_view,
2554  rps_peer->cur_view_count,
2555  view_size);
2556  // *rps_peer->cur_view = *peers;
2557  GNUNET_memcpy (rps_peer->cur_view,
2558  peers,
2559  view_size * sizeof(struct GNUNET_PeerIdentity));
2560  to_file ("/tmp/rps/count_in_views.txt",
2561  "%" PRIu32 " %" PRIu32 "",
2562  rps_peer->index,
2563  count_peer_in_views_2 (rps_peer->index));
2565  if (0 != view_size)
2566  {
2567  to_file ("/tmp/rps/repr.txt",
2568  "%" PRIu32 /* index */
2569  " %" PRIu32 /* occurrence in views */
2570  " %" PRIu32 /* view sizes */
2571  " %f" /* fraction of repr in views */
2572  " %f" /* average view size */
2573  " %f" /* prob of occurrence in view slot */
2574  " %f" "", /* exp frac of repr in views */
2575  rps_peer->index,
2576  count_peer_in_views_2 (rps_peer->index),
2577  view_sizes,
2578  count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2579  view_sizes / (view_size * 1.0), /* average view size */
2580  1.0 / view_size, /* prob of occurrence in view slot */
2581  (1.0 / view_size) * (view_sizes / view_size) /* expected fraction of repr in views */
2582  );
2583  }
2584  compute_probabilities (rps_peer->index);
2586 }
2587 
2588 
2589 static void
2590 pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
2591 {
2592  rps_peer->file_name_probs =
2593  store_prefix_file_name (rps_peer->index, "probs");
2594  rps_peer->file_name_probs_hist =
2595  store_prefix_file_name (rps_peer->index, "probs_hist");
2596  rps_peer->eval_probs_cache = GNUNET_new_array (num_peers, double);
2597  memset (rps_peer->eval_probs_cache, 0, num_peers * sizeof (double));
2598  GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer);
2599 }
2600 
2601 void
2603 {
2604  uint64_t sums[STAT_TYPE_MAX] = { 0 };
2605 
2606  for (uint32_t i = 0; i < num_peers; i++)
2607  {
2608  to_file ("/tmp/rps/final_stats.csv",
2609  "%" PRIu32 ", " /* index */
2610  "%s, %" /* id */
2611  PRIu64 ", %" /* rounds */
2612  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2613  PRIu64 ", %" /* blocking */
2614  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2615  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2616  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2617  PRIu64 ", %" /* recv */
2618  PRIu64 ", %" /* view size */
2619  PRIu64 ", %" /* known peers */
2620  PRIu64 ", %" /* valid peers */
2621  PRIu64 ", %" /* learned peers */
2622  PRIu64 ", %" /* pending online checks */
2623  PRIu64 ", %" /* unrequested pull replies */
2624  PRIu64 ", %" /* peers in push map */
2625  PRIu64 ", %" /* peers in pull map */
2626  PRIu64 ", %" /* peers in view */
2627  PRIu64 "\n" /* view size aim */,
2628  i,
2629  GNUNET_i2s (rps_peers[i].peer_id),
2630  rps_peers[i].stats[STAT_TYPE_ROUNDS],
2631  rps_peers[i].stats[STAT_TYPE_BLOCKS],
2632  rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH],
2633  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH],
2634  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PULL],
2637  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND],
2638  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND_MH],
2639  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ],
2640  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ_MH],
2641  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REP],
2642  rps_peers[i].stats[STAT_TYPE_SENT_PUSH_SEND],
2643  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ],
2644  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ_MH],
2645  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REP],
2646  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND],
2647  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND_MH],
2648  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ],
2649  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ_MH],
2650  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP_MH],
2651  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP],
2652  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE],
2653  rps_peers[i].stats[STAT_TYPE_KNOWN_PEERS],
2654  rps_peers[i].stats[STAT_TYPE_VALID_PEERS],
2655  rps_peers[i].stats[STAT_TYPE_LEARND_PEERS],
2656  rps_peers[i].stats[STAT_TYPE_PENDING_ONLINE_CHECKS],
2658  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PUSH_MAP],
2659  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PULL_MAP],
2660  rps_peers[i].stats[STAT_TYPE_PEERS_IN_VIEW],
2661  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE_AIM]);
2662  for (enum STAT_TYPE stat_type = STAT_TYPE_ROUNDS;
2664  stat_type++)
2665  {
2666  sums[stat_type] += rps_peers[i].stats[stat_type];
2667  }
2668  }
2669  to_file ("/tmp/rps/final_stats.dat",
2670  "SUM %"
2671  PRIu64 " %" /* rounds */
2672  PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
2673  " %" /* blocking */
2674  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2675  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2676  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2677  PRIu64 ", %" /* recv */
2678  PRIu64 ", %" /* view size */
2679  PRIu64 ", %" /* known peers */
2680  PRIu64 ", %" /* valid peers */
2681  PRIu64 ", %" /* learned peers */
2682  PRIu64 ", %" /* pending online checks */
2683  PRIu64 ", %" /* unrequested pull replies */
2684  PRIu64 ", %" /* peers in push map */
2685  PRIu64 ", %" /* peers in pull map */
2686  PRIu64 ", %" /* peers in view */
2687  PRIu64 "\n" /* view size aim */,
2688  sums[STAT_TYPE_ROUNDS],
2689  sums[STAT_TYPE_BLOCKS],
2710  sums[STAT_TYPE_VIEW_SIZE],
2711  sums[STAT_TYPE_KNOWN_PEERS],
2712  sums[STAT_TYPE_VALID_PEERS],
2713  sums[STAT_TYPE_LEARND_PEERS],
2719  sums[STAT_TYPE_VIEW_SIZE_AIM]);
2720 }
2721 
2722 
2734 void
2736  int success)
2737 {
2738  struct STATcls *stat_cls = (struct STATcls *) cls;
2739  struct RPSPeer *rps_peer = stat_cls->rps_peer;
2740 
2741  rps_peer->h_stat_get[stat_cls->stat_type] = NULL;
2742  if (GNUNET_OK == success)
2743  {
2744  /* set flag that we we got the value */
2745  rps_peer->stat_collected_flags |= BIT (stat_cls->stat_type);
2746  }
2747  else
2748  {
2750  "Peer %u did not receive statistics value\n",
2751  rps_peer->index);
2752  GNUNET_free (stat_cls);
2753  GNUNET_break (0);
2754  return;
2755  }
2756 
2757  if ((NULL != rps_peer->stat_op) &&
2759  rps_peer)) )
2760  {
2762  }
2763 
2764  write_final_stats ();
2766  {
2767  // write_final_stats ();
2768  GNUNET_free (stat_cls);
2770  "Shutting down\n");
2772  }
2773  else
2774  {
2775  GNUNET_free (stat_cls);
2776  }
2777 }
2778 
2779 
2790 int
2791 stat_iterator (void *cls,
2792  const char *subsystem,
2793  const char *name,
2794  uint64_t value,
2795  int is_persistent)
2796 {
2797  const struct STATcls *stat_cls = (const struct STATcls *) cls;
2798  struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer;
2799  enum STAT_TYPE stat_type;
2800 
2801  (void) subsystem;
2802  (void) is_persistent;
2803 
2805  "Got stat value: %s - %" PRIu64 " (%u)\n",
2806  name,
2807  value,
2808  rps_peer->index);
2809  to_file (rps_peer->file_name_stats,
2810  "%s: %" PRIu64 "\n",
2811  name,
2812  value);
2813  stat_type = stat_str_2_type (name);
2816  rps_peer->stats[stat_type] = value;
2817  return GNUNET_OK;
2818 }
2819 
2820 
2821 void
2822 post_profiler (struct RPSPeer *rps_peer)
2823 {
2825  {
2826  return;
2827  }
2828 
2830  "Going to request statistic values with mask 0x%" PRIx32 "\n",
2832 
2833  struct STATcls *stat_cls;
2834  uint32_t stat_type;
2835  for (stat_type = STAT_TYPE_ROUNDS;
2836  stat_type < STAT_TYPE_MAX;
2837  stat_type++)
2838  {
2839  if (BIT (stat_type) & cur_test_run.stat_collect_flags)
2840  {
2841  stat_cls = GNUNET_malloc (sizeof(struct STATcls));
2842  stat_cls->rps_peer = rps_peer;
2843  stat_cls->stat_type = stat_type;
2844  rps_peer->file_name_stats =
2845  store_prefix_file_name (rps_peer->index, "stats");
2846  rps_peer->h_stat_get[stat_type] =
2847  GNUNET_STATISTICS_get (rps_peer->stats_h,
2848  "rps",
2849  stat_type_strings [stat_type],
2851  stat_iterator,
2852  (struct STATcls *) stat_cls);
2853  GNUNET_assert (NULL != rps_peer->h_stat_get);
2855  "Requested statistics for %s (peer %" PRIu32 ")\n",
2856  stat_type_strings [stat_type],
2857  rps_peer->index);
2858  }
2859  }
2860  GNUNET_free (rps_peer->eval_probs_cache);
2861 }
2862 
2863 
2864 /***********************************************************************
2865 * /Definition of tests
2866 ***********************************************************************/
2867 
2868 
2881 static void
2882 test_run (void *cls,
2883  struct GNUNET_TESTBED_RunHandle *h,
2884  unsigned int n_peers,
2885  struct GNUNET_TESTBED_Peer **peers,
2886  unsigned int links_succeeded,
2887  unsigned int links_failed)
2888 {
2889  unsigned int i;
2890  struct OpListEntry *entry;
2891 
2892  (void) cls;
2893  (void) h;
2894  (void) links_failed;
2895 
2896  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2897 
2898  /* Check whether we timed out */
2899  if ((n_peers != num_peers) ||
2900  (NULL == peers) ||
2901  (0 == links_succeeded) )
2902  {
2904  "Going down due to args (eg. timeout)\n");
2905  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers);
2906  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n",
2907  num_peers);
2908  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers);
2909  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n",
2910  links_succeeded);
2911  ok = 1;
2913  return;
2914  }
2915 
2916 
2917  /* Initialize peers */
2918  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "going to initialise peers\n");
2919  testbed_peers = peers;
2920  num_peers_online = 0;
2921  for (i = 0; i < num_peers; i++)
2922  {
2923  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "initialising %u\n", i);
2924  entry = make_oplist_entry ();
2925  entry->index = i;
2926  rps_peers[i].index = i;
2927  if (NULL != cur_test_run.init_peer)
2928  cur_test_run.init_peer (&rps_peers[i]);
2930  {
2931  rps_peers->cur_view_count = 0;
2932  rps_peers->cur_view = NULL;
2933  }
2934  entry->op = GNUNET_TESTBED_peer_get_information (peers[i],
2936  &info_cb,
2937  entry);
2938  }
2939 
2940  /* Bring peers up */
2941  GNUNET_assert (num_peers == n_peers);
2942  for (i = 0; i < n_peers; i++)
2943  {
2944  rps_peers[i].index = i;
2945  rps_peers[i].op =
2946  GNUNET_TESTBED_service_connect (&rps_peers[i],
2947  peers[i],
2948  "rps",
2950  &rps_peers[i],
2953  &rps_peers[i]);
2954  /* Connect all peers to statistics service */
2956  {
2958  "Connecting to statistics service\n");
2959  rps_peers[i].stat_op =
2961  peers[i],
2962  "statistics",
2964  &rps_peers[i],
2967  &rps_peers[i]);
2968  }
2969  }
2970 
2971  if (NULL != churn_task)
2972  GNUNET_SCHEDULER_cancel (churn_task);
2973  post_test_task = GNUNET_SCHEDULER_add_delayed (duration, &post_test_op, NULL);
2974  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "timeout for shutdown is %lu\n",
2975  timeout.rel_value_us / 1000000);
2976  shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout,
2978  NULL);
2980 }
2981 
2982 
2989 static void
2990 run (void *cls,
2991  char *const *args,
2992  const char *cfgfile,
2993  const struct GNUNET_CONFIGURATION_Handle *cfg)
2994 {
2995  // int ret_value;
2996  (void) cls;
2997  (void) args;
2998  (void) cfgfile;
2999 
3000  /* Defaults for tests */
3001  churn_task = NULL;
3002 
3003  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
3004  cur_test_run.name = "test-rps-profiler";
3005  if (0 == num_peers)
3006  num_peers = 10;
3007  mal_type = 3;
3009  // cur_test_run.pre_test = mal_pre;
3016  if (0 == cur_test_run.num_requests)
3018  // cur_test_run.have_churn = HAVE_CHURN;
3023  | BIT (STAT_TYPE_BLOCKS)
3055 
3056  /* 'Clean' directory */
3057  (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
3058  GNUNET_DISK_directory_create ("/tmp/rps/");
3059  if (0 == duration.rel_value_us)
3060  {
3061  if (0 == timeout.rel_value_us)
3062  {
3065  (90 * 1.2)
3066  + (0.01 * num_peers));
3067  }
3068  else
3069  {
3072  ( (double) timeout.rel_value_us / (double) 1000000)
3073  * 0.75);
3074  }
3075  }
3076  else
3077  {
3078  if (0 == timeout.rel_value_us)
3079  {
3082  / 1000000)
3083  * 1.2) + (0.01 * num_peers));
3084  }
3085  }
3088  "duration is %lus\n",
3089  duration.rel_value_us / 1000000);
3091  "timeout is %lus\n",
3092  timeout.rel_value_us / 1000000);
3093 
3094  /* Compute number of bits for representing largest peer id */
3095  for (bits_needed = 1; (uint32_t) (1 << bits_needed) < num_peers; bits_needed++)
3096  ;
3098  "Need %u bits to represent %" PRIu32 " peers\n",
3099  bits_needed,
3100  num_peers);
3101 
3102  rps_peers = GNUNET_new_array (num_peers, struct RPSPeer);
3104  rps_peer_ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
3105  if ((2 == mal_type) ||
3106  (3 == mal_type))
3107  target_peer = &rps_peer_ids[num_peers - 2];
3108 
3109  ok = 1;
3110  GNUNET_TESTBED_run (NULL,
3111  cfg,
3112  num_peers,
3113  0, /* event mask */
3114  NULL,
3115  NULL,
3116  &test_run,
3117  NULL);
3118 }
3119 
3120 
3128 int
3129 main (int argc, char *argv[])
3130 {
3131  int ret_value;
3132  struct GNUNET_GETOPT_CommandLineOption options[] = {
3134  "num-peers",
3135  "COUNT",
3136  gettext_noop ("number of peers to start"),
3137  &num_peers),
3139  "duration",
3140  "DURATION",
3141  gettext_noop (
3142  "duration of the profiling"),
3143  &duration),
3145  "timeout",
3146  "TIMEOUT",
3147  gettext_noop (
3148  "timeout for the profiling"),
3149  &timeout),
3151  "num-requests",
3152  "COUNT",
3153  gettext_noop ("number of PeerIDs to request"),
3156  };
3157 
3158  unsetenv ("XDG_DATA_HOME");
3159  unsetenv ("XDG_CONFIG_HOME");
3160  // if (GNUNET_OK !=
3161  // GNUNET_STRINGS_get_utf8_args (argc, argv,
3162  // &argc, &argv))
3163  // return 2;
3164  ret_value = 0;
3165  if (GNUNET_OK !=
3166  GNUNET_PROGRAM_run (argc,
3167  argv,
3168  "gnunet-rps-profiler",
3169  gettext_noop (
3170  "Measure quality and performance of the RPS service."),
3171  options,
3172  &run,
3173  NULL))
3174  {
3175  ret_value = 1;
3176  }
3177  if (0 != ret_value)
3178  {
3180  "Test did not run successfully!\n");
3181  }
3182  else
3183  {
3184  ret_value = cur_test_run.eval_cb ();
3186  {
3187  GNUNET_array_grow (rps_peers->cur_view,
3188  rps_peers->cur_view_count,
3189  0);
3190  }
3191  GNUNET_free (rps_peers);
3192  GNUNET_free (rps_peer_ids);
3194  }
3195  return ret_value;
3196 }
3197 
3198 
3199 /* end of test_rps.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time)...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct OpListEntry * oplist_tail
OpList DLL tail.
struct OpListEntry * prev
DLL prev ptr.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Entry point for the testcase, sets up the testbed.
uint32_t count_in_views
Number of occurrences in other peer&#39;s view.
Create file if it doesn&#39;t exist.
void(* ReplyHandle)(void *cls, uint64_t n, const struct GNUNET_PeerIdentity *recv_peers)
Callback called once the requested random peers are available.
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
static struct GNUNET_TIME_Relative timeout
When do we do a hard shutdown?
int main(int argc, char *argv[])
Entry point for the testcase, sets up the testbed.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:360
static int is_in_view(uint32_t a, uint32_t b)
is b in view of a?
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
uint64_t rel_value_us
The actual value.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
unsigned int * GNUNET_CRYPTO_random_permute(enum GNUNET_CRYPTO_Quality mode, unsigned int n)
Get an array with a random permutation of the numbers 0...n-1.
void(* MainTest)(struct RPSPeer *rps_peer)
Executes functions to test the api/service for a given peer.
int online
A request handle to check for an request.
static void stat_disconnect_adapter(void *cls, void *op_result)
Called to disconnect from peer&#39;s statistics service.
A sampler element sampling one PeerID at a time.
static struct OpListEntry * oplist_head
OpList DLL head.
enum OPTION_COLLECT_VIEW have_collect_view
Collect view during run?
A pending request: A request was not made yet but is scheduled for later.
void RPS_sampler_elem_destroy(struct RPS_SamplerElement *sampler_elem)
Destroy a sampler element.
struct PendingRequest * prev
static void request_peers(void *cls)
Request random peers.
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:1331
double * eval_probs_cache
Keep the probabilities in cache for computing the probabilities with respect to history.
void GNUNET_RPS_view_request(struct GNUNET_RPS_Handle *rps_handle, uint32_t num_updates, GNUNET_RPS_NotifyReadyCB view_update_cb, void *cls)
Request updates of view.
Definition: rps_api.c:461
struct GNUNET_RPS_Request_Handle_Single_Info * req_handle
Handle to the request we are waiting for.
Some utils facilitating the view into the internals for the sampler needed for evaluation.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
#define to_file(file_name,...)
This function is used to facilitate writing important information to disk.
Definition: rps-test_util.h:65
struct RPSPeer * rps_peer
struct PendingReply * pending_rep_head
Pending replies DLL.
void(* InitPeer)(struct RPSPeer *rps_peer)
Called to initialise the given RPSPeer.
void to_file_raw(const char *file_name, const char *buf, size_t size_buf)
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
static void count_peer_in_views(uint32_t *count_peers)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void profiler_reply_handle(void *cls, uint64_t n, const struct GNUNET_PeerIdentity *recv_peers)
Callback to call on receipt of a reply.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1305
static int op_result(struct GNUNET_OP_Handle *h, uint64_t op_id, int64_t result_code, const void *data, uint16_t data_size, void **ctx, uint8_t cancel)
Remove an operation, and call its result callback (unless it was cancelled).
Definition: op.c:245
A pending reply: A request was sent and the reply is pending.
#define GNUNET_TIME_UNIT_SECONDS
One second.
void RPS_sampler_elem_set(struct RPS_SamplerElement *sampler_elem, struct GNUNET_CRYPTO_AuthKey auth_key)
Set the min-wise independent function of the given sampler element.
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
static void profiler_reply_handle_info(void *cls, const struct GNUNET_PeerIdentity *recv_peer, double probability, uint32_t num_observed)
Callback to call on receipt of a reply.
static struct GNUNET_RPS_Handle * rps_handle
RPS handle.
Definition: gnunet-rps.c:36
static void tofile_(const char *file_name, const char *line)
Append arguments to file.
static char * file_name
Dump file name.
Indicates peer going online.
OPTION_COLLECT_STATISTICS
Do we collect statistics at the end?
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ok
Return value from &#39;main&#39;.
sampler element implementation
Append to the file.
enum OPTION_QUICK_QUIT have_quick_quit
Quit test before timeout?
static void pre_profiler(struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
static unsigned int mal_type
Portion of malicious peers.
Linked list of things we still need to do.
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
struct RPS_SamplerElement * RPS_sampler_elem_create(void)
Create a sampler element and initialise it.
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
If we have churn this is set.
PostTest post_test
Called directly before disconnecting from the service.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
void(* PreTest)(struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
Called directly after connecting to the service.
struct PendingRequest * next
DLL next,prev ptr.
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:814
static int check_statistics_collect_completed()
Checks if all peers already received their statistics value from the statistics service.
struct GNUNET_STATISTICS_Handle * stats_h
Handle to the statistics service.
void GNUNET_RPS_disconnect(struct GNUNET_RPS_Handle *h)
Disconnect from the rps service.
Definition: rps_api.c:1263
static void default_reply_handle(void *cls, uint64_t n, const struct GNUNET_PeerIdentity *recv_peers)
Callback to call on receipt of a reply.
#define tofile(file_name,...)
This function is used to facilitate writing important information to disk.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
static unsigned bits_needed
number of bits required to represent the largest peer id
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:531
Handle for the service.
Handler to handle requests from a client.
Definition: rps_api.c:78
void to_file_raw_unaligned(const char *file_name, const char *buf, size_t size_buf, unsigned bits_needed)
static void test_run(void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int n_peers, struct GNUNET_TESTBED_Peer **peers, unsigned int links_succeeded, unsigned int links_failed)
Actual "main" function for the testcase.
struct SingleTestRun cur_test_run
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Indicates peer going offline.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
enum STAT_TYPE stat_type
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
Opaque handle to an abstract operation to be executed by the testing framework.
static void churn_cb(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Callback to be called when RPS service is started or stopped at peers.
void schedule_missing_requests(struct RPSPeer *rps_peer)
Schedule requests for peer rps_peer that have neither been scheduled, nor issued, nor replied...
#define to_file_w_len(file_name, len,...)
Definition: rps-test_util.h:83
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
static int post_test
Did we finish the test?
static unsigned int num_peers_online
Number of online peers.
struct PendingRequest * pending_req_tail
struct GNUNET_PeerIdentity * id
The identity of the peer.
struct GNUNET_RPS_Handle * GNUNET_RPS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the rps service.
Definition: rps_api.c:843
struct PendingReply * prev
struct PendingReply * next
DLL next,prev ptr.
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_service_connect(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_ServiceConnectCompletionCallback cb, void *cb_cls, GNUNET_TESTBED_ConnectAdapter ca, GNUNET_TESTBED_DisconnectAdapter da, void *cada_cls)
Connect to a service offered by the given peer.
static struct OpListEntry * make_oplist_entry()
Creates an oplist entry and adds it to the oplist DLL.
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:1269
static char * stat_type_strings[]
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
static char * line
Desired phone line (string to be converted to a hash).
static char * value
Value of the record to add/remove.
static struct RPSPeer * rps_peers
Information for all the peers.
void GNUNET_RPS_request_single_info_cancel(struct GNUNET_RPS_Request_Handle_Single_Info *rhs)
Cancel an issued single info request.
Definition: rps_api.c:1231
It is NOT ok for the test to quit before the timeout triggers.
static void churn(void *cls)
Initialise only non-mal RPSPeers.
char * name
Name of the test.
struct GNUNET_RPS_Handle * rps_handle
Handle to RPS service.
char * store_prefix_file_name(const unsigned int index, const char *prefix)
struct GNUNET_SCHEDULER_Task * request_task
Handle to the request we are waiting for.
uint64_t stats[STAT_TYPE_MAX]
statistics values
unsigned int num_pending_reps
Number of pending replies.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:686
void view_update_cb(void *cls, uint64_t view_size, const struct GNUNET_PeerIdentity *peers)
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:1296
static struct GNUNET_CONTAINER_MultiPeerMap * peer_map
Peermap to get the index of a given peer ID quick.
const char * file_name_probs
File name of the file the stats are finally written to.
Operation map entry.
static void * rps_connect_adapter(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Adapter function called to establish a connection to the RPS service.
static void cancel_request(struct PendingReply *pending_rep)
uint32_t cur_view_count
Number of peers in the cur_view.
struct GNUNET_PeerIdentity * peer_id
ID of the peer.
enum OPTION_COLLECT_STATISTICS have_collect_statistics
Collect statistics at the end?
static void compute_probabilities(uint32_t peer_idx)
Computes the probability for each other peer to be selected by the sampling process based on the view...
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
static char * filename
static unsigned int view_sizes
The added sizes of the peer&#39;s views.
static uint32_t get_idx_of_pid(const struct GNUNET_PeerIdentity *pid)
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:311
static void shutdown_op(void *cls)
Task run on timeout to shut everything down.
enum STAT_TYPE stat_str_2_type(const char *stat_str)
Converts string representation to the corresponding STAT_TYPE enum.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
struct PendingRequest * pending_req_head
Pending requests DLL.
static int profiler_eval(void)
This is run after the test finished.
Internal representation of the hash map.
struct GNUNET_RPS_Request_Handle_Single_Info * GNUNET_RPS_request_peer_info(struct GNUNET_RPS_Handle *rps_handle, GNUNET_RPS_NotifyReadySingleInfoCB ready_cb, void *cls)
Request one random peer, getting additional information.
Definition: rps_api.c:995
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:2045
struct GNUNET_TESTBED_Operation * op
Handle for RPS connect operation.
void clean_peer(unsigned peer_index)
static void * stat_connect_adapter(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Called to open a connection to the peer&#39;s statistics.
unsigned int num_ids_to_request
Number of Peer IDs to request during the whole test.
void post_test_shutdown_ready_cb(void *cls, int success)
Continuation called by GNUNET_STATISTICS_get() functions.
void GNUNET_TESTBED_run(const char *host_filename, const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int num_peers, uint64_t event_mask, GNUNET_TESTBED_ControllerCallback cc, void *cc_cls, GNUNET_TESTBED_TestMaster test_master, void *test_master_cls)
Convenience method for running a testbed with a single call.
PEER_ONLINE_DELTA
Indicates whether peer should go off- or online.
int(* EvaluationCallback)(void)
Function called after disconnect to evaluate test success.
uint32_t binom(uint32_t n, uint32_t k)
Binomial coefficient (n choose k)
int close_all_files()
Close all files that were opened with get_file_handle.
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 rps_disconnect_adapter(void *cls, void *op_result)
Adapter function called to destroy connection to RPS service.
Handler for a single request from a client.
Definition: rps_api.c:212
MainTest main_test
Main function for each peer.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
uint32_t request_interval
Request interval.
static void stat_complete_cb(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Called after successfully opening a connection to a peer&#39;s statistics service; we register statistics...
struct RPSPeer * rps_peer
The peer that requested.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static uint32_t count_peer_in_views_2(uint32_t peer_idx)
This counts the number of peers in which views a given peer occurs.
void write_final_stats(void)
static struct GNUNET_SCHEDULER_Task * post_test_task
Identifier for the task that runs after the test to collect results.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
OPTION_CHURN
Do we have Churn?
Structure to define a single test.
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_TESTBED_Peer ** testbed_peers
Handles to all of the running peers.
uint32_t stat_collect_flags
Mark which values from the statistics service to collect at the end of the run.
Open the file for writing.
We collect statistics at the end.
enum OPTION_CHURN have_churn
Run with (-out) churn.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static void profiler_cb(struct RPSPeer *rps_peer)
void(* PostTest)(struct RPSPeer *peer)
Called directly before disconnecting from the service.
unsigned int num_recv_ids
Number of received PeerIDs.
static void profiler_init_peer(struct RPSPeer *rps_peer)
Initialise given RPSPeer.
int delta
Depending on whether we start or stop NSE service at the peer set this to 1 or -1.
void info_cb(void *cb_cls, struct GNUNET_TESTBED_Operation *op, const struct GNUNET_TESTBED_PeerInformation *pinfo, const char *emsg)
Get the id of peer i.
static struct GNUNET_PeerIdentity * target_peer
ID of the targeted peer.
int stat_iterator(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Callback function to process statistic values.
Information we track for each peer.
static int file_name_cb(void *cls, const char *filename)
Function called from profiler_eval with a filename.
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.
struct GNUNET_STATISTICS_GetHandle * h_stat_get[STAT_TYPE_MAX]
Handle for the statistics get request.
const struct OpListEntry * entry_op_manage
Pending operation on that peer.
static uint32_t count_containing_views(uint32_t a, uint32_t b)
Counts number of peers in view of a that have b in their view.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
Everybody can read.
The identity of the host (wraps the signing key of the peer).
What is the identity of the peer? Returns a &#39;const struct GNUNET_PeerIdentity *&#39;. ...
struct GNUNET_STATISTICS_GetHandle * GNUNET_STATISTICS_get(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Callback cont, GNUNET_STATISTICS_Iterator proc, void *cls)
Get statistic from the peer.
static void rps_connect_complete_cb(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Callback to be called when RPS service connect operation is completed.
void cancel_pending_req_rep(struct RPSPeer *rps_peer)
static void post_test_op(void *cls)
Task run after duration to collect statistics and potentially shut down.
configuration data
InitPeer init_peer
Called with a single peer in order to initialise that peer.
uint32_t stat_collected_flags
flags to indicate which statistics values have been already collected from the statistics service...
const char * name
EvaluationCallback eval_cb
Function to evaluate the test results.
We collect view during run.
static struct CadetPeer * peers
Operation to get peer ids.
const char * file_name_probs_hist
File name of the file the stats are finally written to.
struct GNUNET_CRYPTO_AuthKey string_to_auth_key(const char *str)
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.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
It is ok for the test to quit before the timeout triggers.
unsigned int index
Index of the regarding peer.
static void cancel_pending_req(struct PendingRequest *pending_req)
static struct GNUNET_SCHEDULER_Task * shutdown_task
Identifier for the shutdown task.
struct PendingReply * pending_rep_tail
const char * file_name_stats
File name of the file the stats are finally written to.
ReplyHandle reply_handle
Callback called once the requested peers are available.
static struct GNUNET_TIME_Relative duration
How long do we run the test?
static struct GNUNET_SCHEDULER_Task * churn_task
Identifier for the churn task that runs periodically.
struct RPSPeer * rps_peer
The peer that requested.
We do not collect statistics at the end.
#define BIT(n)
void compute_diversity()
struct GNUNET_TESTBED_Operation * stat_op
Testbed operation to connect to statistics service.
static uint32_t cumulated_view_sizes()
OPTION_COLLECT_VIEW
Do we collect views during run?
void post_profiler(struct RPSPeer *rps_peer)
PreTest pre_test
Called directly after connecting to the service.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1084
union GNUNET_TESTBED_PeerInformation::@49 result
The result of the get information operation; Choose according to the pit.
static void trigger_shutdown(void *cls)
static uint32_t num_peers
How many peers do we start?
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_uint(char shortName, const char *name, const char *argumentHelp, const char *description, unsigned int *val)
Allow user to specify an unsigned int.
static int evaluate(void)
Write the ids and their according index in the given array to a file Unused.
static int in_shutdown
Are we shutting down?
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
uint32_t num_requests
Number of Requests to make.
A peer controlled by the testing framework.
unsigned int num_pending_reqs
Number of pending requests.
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.
uint32_t index
Index of the peer.
If we have no churn this is set.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1234
void print_view_sizes()
void RPS_sampler_elem_next(struct RPS_SamplerElement *sampler_elem, const struct GNUNET_PeerIdentity *new_ID)
Update a sampler element with a PeerID.
Handle used to access files (and pipes).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct OpListEntry * next
DLL next ptr.
struct GNUNET_TESTBED_Operation * op
The testbed operation.
We do not collect the view during run.
type for (message) authentication keys
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
void all_views_updated_cb()
static struct GNUNET_PeerIdentity * rps_peer_ids
IDs of the peers.
#define GNUNET_free(ptr)
Wrapper around free.
static void manage_service_wrapper(unsigned int i, unsigned int j, enum PEER_ONLINE_DELTA delta, double prob_go_on_off)
Set the rps-service up or down for a specific peer.
OPTION_QUICK_QUIT
Is it ok to quit the test before the timeout?
Time for relative time used by GNUnet, in microseconds.
Data returned from GNUNET_TESTBED_peer_get_information.
#define gettext_noop(String)
Definition: gettext.h:69
static int check_statistics_collect_completed_single_peer(const struct RPSPeer *rps_peer)
Checks if given peer already received its statistics value from the statistics service.
struct GNUNET_PeerIdentity * cur_view
The current view.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972